From f84c8b990c4e3e29aedbd09d206459b268580087 Mon Sep 17 00:00:00 2001 From: "antoine.roux@zenika.com" Date: Fri, 22 Feb 2019 19:18:45 +0100 Subject: [PATCH] Add default tomcat service --- .gitignore | 10 +- .../tomcat/webapps/ROOT/RELEASE-NOTES.txt | 172 + .../tomcat/webapps/ROOT/WEB-INF/web.xml | 30 + .../tomcat/webapps/ROOT/asf-logo-wide.svg | 295 + .../tomcat/webapps/ROOT/bg-button.png | Bin 0 -> 713 bytes .../tomcat/webapps/ROOT/bg-middle.png | Bin 0 -> 1918 bytes .../tomcat/webapps/ROOT/bg-nav-item.png | Bin 0 -> 1392 bytes test.dockerapp/tomcat/webapps/ROOT/bg-nav.png | Bin 0 -> 1401 bytes .../tomcat/webapps/ROOT/bg-upper.png | Bin 0 -> 3103 bytes .../tomcat/webapps/ROOT/favicon.ico | Bin 0 -> 21630 bytes test.dockerapp/tomcat/webapps/ROOT/index.jsp | 223 + .../tomcat/webapps/ROOT/tomcat-power.gif | Bin 0 -> 2376 bytes test.dockerapp/tomcat/webapps/ROOT/tomcat.css | 351 + test.dockerapp/tomcat/webapps/ROOT/tomcat.gif | Bin 0 -> 2066 bytes test.dockerapp/tomcat/webapps/ROOT/tomcat.png | Bin 0 -> 5103 bytes test.dockerapp/tomcat/webapps/ROOT/tomcat.svg | 967 ++ .../tomcat/webapps/docs/BUILDING.txt | 568 ++ .../tomcat/webapps/docs/RELEASE-NOTES.txt | 172 + .../tomcat/webapps/docs/RUNNING.txt | 477 + .../tomcat/webapps/docs/WEB-INF/web.xml | 29 + test.dockerapp/tomcat/webapps/docs/aio.html | 366 + .../tomcat/webapps/docs/api/index.html | 34 + .../tomcat/webapps/docs/appdev/build.xml.txt | 508 + .../webapps/docs/appdev/deployment.html | 244 + .../tomcat/webapps/docs/appdev/index.html | 87 + .../webapps/docs/appdev/installation.html | 115 + .../webapps/docs/appdev/introduction.html | 100 + .../tomcat/webapps/docs/appdev/processes.html | 315 + .../webapps/docs/appdev/sample/build.xml | 508 + .../docs/appdev/sample/docs/README.txt | 17 + .../webapps/docs/appdev/sample/index.html | 55 + .../webapps/docs/appdev/sample/sample.war | Bin 0 -> 4606 bytes .../appdev/sample/src/mypackage/Hello.java | 83 + .../docs/appdev/sample/web/WEB-INF/web.xml | 40 + .../webapps/docs/appdev/sample/web/hello.jsp | 37 + .../docs/appdev/sample/web/images/tomcat.gif | Bin 0 -> 2066 bytes .../webapps/docs/appdev/sample/web/index.html | 39 + .../tomcat/webapps/docs/appdev/source.html | 321 + .../tomcat/webapps/docs/appdev/web.xml.txt | 166 + test.dockerapp/tomcat/webapps/docs/apr.html | 190 + .../webapps/docs/architecture/index.html | 77 + .../webapps/docs/architecture/overview.html | 146 + .../docs/architecture/requestProcess.html | 85 + .../requestProcess/authentication-process.png | Bin 0 -> 42682 bytes .../requestProcess/request-process.png | Bin 0 -> 109471 bytes .../webapps/docs/architecture/startup.html | 84 + .../architecture/startup/serverStartup.pdf | Bin 0 -> 46175 bytes .../architecture/startup/serverStartup.txt | 139 + .../tomcat/webapps/docs/balancer-howto.html | 61 + .../tomcat/webapps/docs/building.html | 278 + .../tomcat/webapps/docs/cgi-howto.html | 154 + .../tomcat/webapps/docs/changelog.html | 8612 +++++++++++++++++ .../webapps/docs/class-loader-howto.html | 262 + .../tomcat/webapps/docs/cluster-howto.html | 668 ++ .../tomcat/webapps/docs/comments.html | 122 + .../tomcat/webapps/docs/config/ajp.html | 755 ++ .../docs/config/automatic-deployment.html | 540 ++ .../webapps/docs/config/cluster-channel.html | 130 + .../webapps/docs/config/cluster-deployer.html | 107 + .../docs/config/cluster-interceptor.html | 291 + .../webapps/docs/config/cluster-listener.html | 77 + .../webapps/docs/config/cluster-manager.html | 301 + .../docs/config/cluster-membership.html | 163 + .../webapps/docs/config/cluster-receiver.html | 159 + .../webapps/docs/config/cluster-sender.html | 175 + .../webapps/docs/config/cluster-valve.html | 168 + .../tomcat/webapps/docs/config/cluster.html | 176 + .../tomcat/webapps/docs/config/context.html | 1260 +++ .../webapps/docs/config/cookie-processor.html | 209 + .../docs/config/credentialhandler.html | 209 + .../tomcat/webapps/docs/config/engine.html | 259 + .../tomcat/webapps/docs/config/executor.html | 127 + .../tomcat/webapps/docs/config/filter.html | 1633 ++++ .../webapps/docs/config/globalresources.html | 258 + .../tomcat/webapps/docs/config/host.html | 621 ++ .../tomcat/webapps/docs/config/http.html | 1370 +++ .../tomcat/webapps/docs/config/index.html | 107 + .../webapps/docs/config/jar-scan-filter.html | 183 + .../webapps/docs/config/jar-scanner.html | 141 + .../tomcat/webapps/docs/config/listeners.html | 556 ++ .../tomcat/webapps/docs/config/loader.html | 161 + .../tomcat/webapps/docs/config/manager.html | 524 + .../tomcat/webapps/docs/config/realm.html | 1038 ++ .../tomcat/webapps/docs/config/resources.html | 320 + .../tomcat/webapps/docs/config/server.html | 123 + .../tomcat/webapps/docs/config/service.html | 110 + .../docs/config/sessionidgenerator.html | 131 + .../webapps/docs/config/systemprops.html | 626 ++ .../tomcat/webapps/docs/config/valve.html | 1592 +++ .../tomcat/webapps/docs/connectors.html | 86 + .../tomcat/webapps/docs/default-servlet.html | 292 + .../tomcat/webapps/docs/deployer-howto.html | 351 + .../tomcat/webapps/docs/developers.html | 89 + .../tomcat/webapps/docs/elapi/index.html | 34 + .../tomcat/webapps/docs/extras.html | 128 + .../webapps/docs/funcspecs/fs-admin-apps.html | 299 + .../docs/funcspecs/fs-admin-objects.html | 453 + .../docs/funcspecs/fs-admin-opers.html | 309 + .../webapps/docs/funcspecs/fs-default.html | 270 + .../webapps/docs/funcspecs/fs-jdbc-realm.html | 266 + .../webapps/docs/funcspecs/fs-jndi-realm.html | 417 + .../docs/funcspecs/fs-memory-realm.html | 253 + .../tomcat/webapps/docs/funcspecs/index.html | 80 + .../webapps/docs/funcspecs/mbean-names.html | 710 ++ .../webapps/docs/host-manager-howto.html | 232 + .../webapps/docs/html-host-manager-howto.html | 201 + .../webapps/docs/html-manager-howto.html | 537 + .../tomcat/webapps/docs/images/add.gif | Bin 0 -> 1037 bytes .../tomcat/webapps/docs/images/asf-logo.svg | 226 + .../tomcat/webapps/docs/images/code.gif | Bin 0 -> 394 bytes .../webapps/docs/images/cors-flowchart.png | Bin 0 -> 86555 bytes .../tomcat/webapps/docs/images/design.gif | Bin 0 -> 608 bytes .../webapps/docs/images/docs-stylesheet.css | 303 + .../tomcat/webapps/docs/images/docs.gif | Bin 0 -> 261 bytes .../tomcat/webapps/docs/images/fix.gif | Bin 0 -> 345 bytes .../docs/images/fonts/OpenSans400.woff | Bin 0 -> 21956 bytes .../docs/images/fonts/OpenSans400italic.woff | Bin 0 -> 21092 bytes .../docs/images/fonts/OpenSans600.woff | Bin 0 -> 22604 bytes .../docs/images/fonts/OpenSans600italic.woff | Bin 0 -> 21252 bytes .../docs/images/fonts/OpenSans700.woff | Bin 0 -> 22748 bytes .../docs/images/fonts/OpenSans700italic.woff | Bin 0 -> 21184 bytes .../webapps/docs/images/fonts/fonts.css | 54 + .../tomcat/webapps/docs/images/printer.gif | Bin 0 -> 438 bytes .../tomcat/webapps/docs/images/tomcat.gif | Bin 0 -> 2066 bytes .../tomcat/webapps/docs/images/tomcat.png | Bin 0 -> 5103 bytes .../tomcat/webapps/docs/images/tomcat.svg | 967 ++ .../tomcat/webapps/docs/images/update.gif | Bin 0 -> 627 bytes .../tomcat/webapps/docs/images/void.gif | Bin 0 -> 43 bytes test.dockerapp/tomcat/webapps/docs/index.html | 229 + .../tomcat/webapps/docs/introduction.html | 147 + .../tomcat/webapps/docs/jasper-howto.html | 411 + .../tomcat/webapps/docs/jdbc-pool.html | 929 ++ .../docs/jndi-datasource-examples-howto.html | 676 ++ .../webapps/docs/jndi-resources-howto.html | 1056 ++ .../tomcat/webapps/docs/jspapi/index.html | 34 + .../tomcat/webapps/docs/logging.html | 623 ++ .../tomcat/webapps/docs/manager-howto.html | 1405 +++ .../tomcat/webapps/docs/maven-jars.html | 69 + .../docs/mbeans-descriptors-howto.html | 94 + .../webapps/docs/mbeans-descriptors.dtd | 247 + .../tomcat/webapps/docs/monitoring.html | 1136 +++ .../tomcat/webapps/docs/proxy-howto.html | 155 + .../tomcat/webapps/docs/realm-howto.html | 1221 +++ .../tomcat/webapps/docs/rewrite.html | 717 ++ .../tomcat/webapps/docs/security-howto.html | 526 + .../webapps/docs/security-manager-howto.html | 525 + .../tomcat/webapps/docs/servletapi/index.html | 34 + test.dockerapp/tomcat/webapps/docs/setup.html | 202 + .../tomcat/webapps/docs/ssi-howto.html | 398 + .../tomcat/webapps/docs/ssl-howto.html | 664 ++ .../webapps/docs/tribes/developers.html | 50 + .../tomcat/webapps/docs/tribes/faq.html | 50 + .../webapps/docs/tribes/interceptors.html | 50 + .../webapps/docs/tribes/introduction.html | 274 + .../webapps/docs/tribes/membership.html | 50 + .../tomcat/webapps/docs/tribes/setup.html | 50 + .../tomcat/webapps/docs/tribes/status.html | 50 + .../tomcat/webapps/docs/tribes/transport.html | 50 + .../webapps/docs/virtual-hosting-howto.html | 140 + .../tomcat/webapps/docs/web-socket-howto.html | 178 + .../webapps/docs/websocketapi/index.html | 34 + .../webapps/docs/windows-auth-howto.html | 340 + .../webapps/docs/windows-service-howto.html | 483 + .../WEB-INF/classes/CookieExample.class | Bin 0 -> 4472 bytes .../WEB-INF/classes/CookieExample.java | 142 + .../WEB-INF/classes/HelloWorldExample.class | Bin 0 -> 2234 bytes .../WEB-INF/classes/HelloWorldExample.java | 79 + .../WEB-INF/classes/LocalStrings.properties | 51 + .../classes/LocalStrings_en.properties | 51 + .../classes/LocalStrings_es.properties | 43 + .../classes/LocalStrings_fr.properties | 51 + .../classes/LocalStrings_pt.properties | 51 + .../classes/RequestHeaderExample.class | Bin 0 -> 3617 bytes .../WEB-INF/classes/RequestHeaderExample.java | 109 + .../WEB-INF/classes/RequestInfoExample.class | Bin 0 -> 3298 bytes .../WEB-INF/classes/RequestInfoExample.java | 118 + .../WEB-INF/classes/RequestParamExample.class | Bin 0 -> 3247 bytes .../WEB-INF/classes/RequestParamExample.java | 111 + .../WEB-INF/classes/ServletToJsp.class | Bin 0 -> 1391 bytes .../WEB-INF/classes/ServletToJsp.java | 39 + .../WEB-INF/classes/SessionExample.class | Bin 0 -> 4682 bytes .../WEB-INF/classes/SessionExample.java | 147 + .../WEB-INF/classes/async/Async0$1.class | Bin 0 -> 1815 bytes .../WEB-INF/classes/async/Async0.class | Bin 0 -> 2647 bytes .../WEB-INF/classes/async/Async0.java | 67 + .../WEB-INF/classes/async/Async1$1.class | Bin 0 -> 1749 bytes .../WEB-INF/classes/async/Async1.class | Bin 0 -> 1546 bytes .../WEB-INF/classes/async/Async1.java | 62 + .../WEB-INF/classes/async/Async2$1.class | Bin 0 -> 2139 bytes .../WEB-INF/classes/async/Async2.class | Bin 0 -> 1546 bytes .../WEB-INF/classes/async/Async2.java | 64 + .../WEB-INF/classes/async/Async3.class | Bin 0 -> 1015 bytes .../WEB-INF/classes/async/Async3.java | 39 + .../async/AsyncStockContextListener.class | Bin 0 -> 1205 bytes .../async/AsyncStockContextListener.java | 44 + .../classes/async/AsyncStockServlet.class | Bin 0 -> 5060 bytes .../classes/async/AsyncStockServlet.java | 144 + .../classes/async/Stockticker$Stock.class | Bin 0 -> 2596 bytes .../async/Stockticker$TickListener.class | Bin 0 -> 307 bytes .../WEB-INF/classes/async/Stockticker.class | Bin 0 -> 3489 bytes .../WEB-INF/classes/async/Stockticker.java | 207 + .../WEB-INF/classes/cal/Entries.class | Bin 0 -> 2001 bytes .../examples/WEB-INF/classes/cal/Entries.java | 60 + .../examples/WEB-INF/classes/cal/Entry.class | Bin 0 -> 911 bytes .../examples/WEB-INF/classes/cal/Entry.java | 53 + .../WEB-INF/classes/cal/JspCalendar.class | Bin 0 -> 3510 bytes .../WEB-INF/classes/cal/JspCalendar.java | 151 + .../WEB-INF/classes/cal/TableBean.class | Bin 0 -> 2575 bytes .../WEB-INF/classes/cal/TableBean.java | 101 + .../chat/ChatServlet$MessageSender.class | Bin 0 -> 2699 bytes .../WEB-INF/classes/chat/ChatServlet.class | Bin 0 -> 7124 bytes .../WEB-INF/classes/chat/ChatServlet.java | 292 + .../WEB-INF/classes/checkbox/CheckTest.class | Bin 0 -> 604 bytes .../WEB-INF/classes/checkbox/CheckTest.java | 31 + .../classes/colors/ColorGameBean.class | Bin 0 -> 2171 bytes .../WEB-INF/classes/colors/ColorGameBean.java | 113 + .../CompressionFilter.class | Bin 0 -> 5511 bytes .../compressionFilters/CompressionFilter.java | 269 + .../CompressionFilterTestServlet.class | Bin 0 -> 2019 bytes .../CompressionFilterTestServlet.java | 66 + .../CompressionResponseStream.class | Bin 0 -> 6652 bytes .../CompressionResponseStream.java | 430 + .../CompressionServletResponseWrapper.class | Bin 0 -> 5369 bytes .../CompressionServletResponseWrapper.java | 278 + .../WEB-INF/classes/dates/JspCalendar.class | Bin 0 -> 4143 bytes .../WEB-INF/classes/dates/JspCalendar.java | 153 + .../WEB-INF/classes/error/Smart.class | Bin 0 -> 521 bytes .../examples/WEB-INF/classes/error/Smart.java | 30 + .../classes/examples/ExampleTagBase.class | Bin 0 -> 1400 bytes .../classes/examples/ExampleTagBase.java | 74 + .../WEB-INF/classes/examples/FooTag.class | Bin 0 -> 1926 bytes .../WEB-INF/classes/examples/FooTag.java | 87 + .../classes/examples/FooTagExtraInfo.class | Bin 0 -> 658 bytes .../classes/examples/FooTagExtraInfo.java | 36 + .../WEB-INF/classes/examples/LogTag.class | Bin 0 -> 1522 bytes .../WEB-INF/classes/examples/LogTag.java | 61 + .../WEB-INF/classes/examples/ShowSource.class | Bin 0 -> 2633 bytes .../WEB-INF/classes/examples/ShowSource.java | 76 + .../WEB-INF/classes/examples/ValuesTag.class | Bin 0 -> 2063 bytes .../WEB-INF/classes/examples/ValuesTag.java | 79 + .../classes/filters/ExampleFilter.class | Bin 0 -> 2281 bytes .../classes/filters/ExampleFilter.java | 142 + .../classes/jsp2/examples/BookBean.class | Bin 0 -> 736 bytes .../classes/jsp2/examples/BookBean.java | 44 + .../classes/jsp2/examples/FooBean.class | Bin 0 -> 554 bytes .../classes/jsp2/examples/FooBean.java | 36 + .../classes/jsp2/examples/ValuesBean.class | Bin 0 -> 983 bytes .../classes/jsp2/examples/ValuesBean.java | 52 + .../classes/jsp2/examples/el/Functions.class | Bin 0 -> 1148 bytes .../classes/jsp2/examples/el/Functions.java | 45 + .../simpletag/EchoAttributesTag.class | Bin 0 -> 1898 bytes .../examples/simpletag/EchoAttributesTag.java | 57 + .../simpletag/FindBookSimpleTag.class | Bin 0 -> 1133 bytes .../examples/simpletag/FindBookSimpleTag.java | 46 + .../simpletag/HelloWorldSimpleTag.class | Bin 0 -> 764 bytes .../simpletag/HelloWorldSimpleTag.java | 34 + .../examples/simpletag/RepeatSimpleTag.class | Bin 0 -> 1102 bytes .../examples/simpletag/RepeatSimpleTag.java | 44 + .../examples/simpletag/ShuffleSimpleTag.class | Bin 0 -> 1524 bytes .../examples/simpletag/ShuffleSimpleTag.java | 87 + .../examples/simpletag/TileSimpleTag.class | Bin 0 -> 1263 bytes .../examples/simpletag/TileSimpleTag.java | 48 + .../classes/listeners/ContextListener.class | Bin 0 -> 2225 bytes .../classes/listeners/ContextListener.java | 138 + .../classes/listeners/SessionListener.class | Bin 0 -> 2863 bytes .../classes/listeners/SessionListener.java | 160 + .../classes/nonblocking/ByteCounter$1.class | Bin 0 -> 208 bytes .../ByteCounter$CounterListener.class | Bin 0 -> 2741 bytes .../classes/nonblocking/ByteCounter.class | Bin 0 -> 1822 bytes .../classes/nonblocking/ByteCounter.java | 142 + .../classes/nonblocking/NumberWriter$1.class | Bin 0 -> 211 bytes .../NumberWriter$NumberWriterListener.class | Bin 0 -> 3075 bytes .../classes/nonblocking/NumberWriter.class | Bin 0 -> 1577 bytes .../classes/nonblocking/NumberWriter.java | 148 + .../WEB-INF/classes/num/NumberGuessBean.class | Bin 0 -> 2153 bytes .../WEB-INF/classes/num/NumberGuessBean.java | 99 + .../WEB-INF/classes/sessions/DummyCart.class | Bin 0 -> 1566 bytes .../WEB-INF/classes/sessions/DummyCart.java | 65 + .../WEB-INF/classes/util/CookieFilter.class | Bin 0 -> 1942 bytes .../WEB-INF/classes/util/CookieFilter.java | 85 + .../WEB-INF/classes/util/HTMLFilter.class | Bin 0 -> 1081 bytes .../WEB-INF/classes/util/HTMLFilter.java | 67 + .../classes/validators/DebugValidator.class | Bin 0 -> 1539 bytes .../classes/validators/DebugValidator.java | 84 + .../classes/websocket/ExamplesConfig.class | Bin 0 -> 2382 bytes .../classes/websocket/ExamplesConfig.java | 66 + .../websocket/chat/ChatAnnotation.class | Bin 0 -> 3723 bytes .../websocket/chat/ChatAnnotation.java | 109 + .../websocket/drawboard/Client$1.class | Bin 0 -> 1774 bytes .../classes/websocket/drawboard/Client.class | Bin 0 -> 4964 bytes .../classes/websocket/drawboard/Client.java | 229 + .../DrawMessage$ParseException.class | Bin 0 -> 688 bytes .../websocket/drawboard/DrawMessage.class | Bin 0 -> 5967 bytes .../websocket/drawboard/DrawMessage.java | 270 + .../drawboard/DrawboardContextListener.class | Bin 0 -> 890 bytes .../drawboard/DrawboardContextListener.java | 37 + .../drawboard/DrawboardEndpoint$1.class | Bin 0 -> 2158 bytes .../drawboard/DrawboardEndpoint$2.class | Bin 0 -> 1590 bytes .../drawboard/DrawboardEndpoint$3$1.class | Bin 0 -> 2521 bytes .../drawboard/DrawboardEndpoint$3.class | Bin 0 -> 1279 bytes .../drawboard/DrawboardEndpoint.class | Bin 0 -> 3908 bytes .../drawboard/DrawboardEndpoint.java | 236 + .../websocket/drawboard/Room$1$1.class | Bin 0 -> 725 bytes .../classes/websocket/drawboard/Room$1.class | Bin 0 -> 747 bytes .../classes/websocket/drawboard/Room$2.class | Bin 0 -> 899 bytes .../drawboard/Room$MessageType.class | Bin 0 -> 1454 bytes .../websocket/drawboard/Room$Player.class | Bin 0 -> 3859 bytes .../classes/websocket/drawboard/Room.class | Bin 0 -> 8278 bytes .../classes/websocket/drawboard/Room.java | 490 + .../wsmessages/AbstractWebsocketMessage.class | Bin 0 -> 359 bytes .../wsmessages/AbstractWebsocketMessage.java | 25 + .../wsmessages/BinaryWebsocketMessage.class | Bin 0 -> 590 bytes .../wsmessages/BinaryWebsocketMessage.java | 34 + .../wsmessages/CloseWebsocketMessage.class | Bin 0 -> 389 bytes .../wsmessages/CloseWebsocketMessage.java | 24 + .../wsmessages/StringWebsocketMessage.class | Bin 0 -> 583 bytes .../wsmessages/StringWebsocketMessage.java | 34 + .../websocket/echo/EchoAnnotation.class | Bin 0 -> 1806 bytes .../websocket/echo/EchoAnnotation.java | 75 + .../echo/EchoAsyncAnnotation$1.class | Bin 0 -> 238 bytes .../EchoAsyncAnnotation$CompletedFuture.class | Bin 0 -> 1714 bytes .../websocket/echo/EchoAsyncAnnotation.class | Bin 0 -> 2844 bytes .../websocket/echo/EchoAsyncAnnotation.java | 128 + .../websocket/echo/EchoEndpoint$1.class | Bin 0 -> 217 bytes ...choEndpoint$EchoMessageHandlerBinary.class | Bin 0 -> 1624 bytes .../EchoEndpoint$EchoMessageHandlerText.class | Bin 0 -> 1604 bytes .../classes/websocket/echo/EchoEndpoint.class | Bin 0 -> 1266 bytes .../classes/websocket/echo/EchoEndpoint.java | 80 + .../websocket/echo/EchoStreamAnnotation.class | Bin 0 -> 1850 bytes .../websocket/echo/EchoStreamAnnotation.java | 75 + .../classes/websocket/echo/servers.json | 20 + .../classes/websocket/snake/Direction.class | Bin 0 -> 1110 bytes .../classes/websocket/snake/Direction.java | 21 + .../classes/websocket/snake/Location$1.class | Bin 0 -> 813 bytes .../classes/websocket/snake/Location.class | Bin 0 -> 1322 bytes .../classes/websocket/snake/Location.java | 65 + .../classes/websocket/snake/Snake.class | Bin 0 -> 5122 bytes .../classes/websocket/snake/Snake.java | 150 + .../websocket/snake/SnakeAnnotation.class | Bin 0 -> 4408 bytes .../websocket/snake/SnakeAnnotation.java | 135 + .../websocket/snake/SnakeTimer$1.class | Bin 0 -> 838 bytes .../classes/websocket/snake/SnakeTimer.class | Bin 0 -> 3577 bytes .../classes/websocket/snake/SnakeTimer.java | 115 + .../examples/WEB-INF/jsp/applet/Clock2.java | 230 + .../examples/WEB-INF/jsp/debug-taglib.tld | 54 + .../examples/WEB-INF/jsp/example-taglib.tld | 118 + .../WEB-INF/jsp2/jsp2-example-taglib.tld | 124 + .../lib/taglibs-standard-impl-1.2.5.jar | Bin 0 -> 206430 bytes .../lib/taglibs-standard-spec-1.2.5.jar | Bin 0 -> 40153 bytes .../examples/WEB-INF/tags/displayProducts.tag | 55 + .../examples/WEB-INF/tags/helloWorld.tag | 17 + .../webapps/examples/WEB-INF/tags/panel.tag | 29 + .../tomcat/webapps/examples/WEB-INF/web.xml | 407 + .../tomcat/webapps/examples/index.html | 30 + .../webapps/examples/jsp/async/async1.jsp | 26 + .../examples/jsp/async/async1.jsp.html | 27 + .../webapps/examples/jsp/async/async3.jsp | 20 + .../examples/jsp/async/async3.jsp.html | 21 + .../webapps/examples/jsp/async/index.jsp | 69 + .../webapps/examples/jsp/async/index.jsp.html | 70 + .../examples/jsp/cal/Entries.java.html | 61 + .../webapps/examples/jsp/cal/Entry.java.html | 54 + .../examples/jsp/cal/JspCalendar.java.html | 152 + .../examples/jsp/cal/TableBean.java.html | 102 + .../tomcat/webapps/examples/jsp/cal/cal1.jsp | 94 + .../webapps/examples/jsp/cal/cal1.jsp.html | 95 + .../tomcat/webapps/examples/jsp/cal/cal2.jsp | 45 + .../webapps/examples/jsp/cal/cal2.jsp.html | 46 + .../webapps/examples/jsp/cal/calendar.html | 43 + .../webapps/examples/jsp/cal/login.html | 47 + .../examples/jsp/checkbox/CheckTest.html | 56 + .../webapps/examples/jsp/checkbox/check.html | 38 + .../examples/jsp/checkbox/checkresult.jsp | 63 + .../jsp/checkbox/checkresult.jsp.html | 64 + .../examples/jsp/checkbox/cresult.html | 34 + .../examples/jsp/colors/ColorGameBean.html | 116 + .../webapps/examples/jsp/colors/clr.html | 34 + .../webapps/examples/jsp/colors/colors.html | 47 + .../webapps/examples/jsp/colors/colrs.jsp | 70 + .../examples/jsp/colors/colrs.jsp.html | 71 + .../webapps/examples/jsp/dates/date.html | 31 + .../webapps/examples/jsp/dates/date.jsp | 41 + .../webapps/examples/jsp/dates/date.jsp.html | 42 + .../tomcat/webapps/examples/jsp/error/er.html | 31 + .../tomcat/webapps/examples/jsp/error/err.jsp | 44 + .../webapps/examples/jsp/error/err.jsp.html | 45 + .../webapps/examples/jsp/error/error.html | 37 + .../webapps/examples/jsp/error/errorpge.jsp | 25 + .../examples/jsp/error/errorpge.jsp.html | 26 + .../webapps/examples/jsp/forward/forward.jsp | 33 + .../examples/jsp/forward/forward.jsp.html | 34 + .../webapps/examples/jsp/forward/fwd.html | 30 + .../webapps/examples/jsp/forward/one.jsp | 23 + .../webapps/examples/jsp/forward/one.jsp.html | 24 + .../webapps/examples/jsp/forward/two.html | 23 + .../webapps/examples/jsp/images/code.gif | Bin 0 -> 292 bytes .../webapps/examples/jsp/images/execute.gif | Bin 0 -> 1242 bytes .../webapps/examples/jsp/images/read.gif | Bin 0 -> 1125 bytes .../webapps/examples/jsp/images/return.gif | Bin 0 -> 1231 bytes .../webapps/examples/jsp/include/foo.html | 17 + .../webapps/examples/jsp/include/foo.jsp | 17 + .../webapps/examples/jsp/include/foo.jsp.html | 18 + .../webapps/examples/jsp/include/inc.html | 30 + .../webapps/examples/jsp/include/include.jsp | 30 + .../examples/jsp/include/include.jsp.html | 31 + .../tomcat/webapps/examples/jsp/index.html | 370 + .../examples/jsp/jsp2/el/Functions.java.html | 46 + .../examples/jsp/jsp2/el/ValuesBean.java.html | 53 + .../examples/jsp/jsp2/el/ValuesTag.java.html | 80 + .../jsp/jsp2/el/basic-arithmetic.html | 30 + .../examples/jsp/jsp2/el/basic-arithmetic.jsp | 88 + .../jsp/jsp2/el/basic-arithmetic.jsp.html | 89 + .../jsp/jsp2/el/basic-comparisons.html | 30 + .../jsp/jsp2/el/basic-comparisons.jsp | 116 + .../jsp/jsp2/el/basic-comparisons.jsp.html | 117 + .../examples/jsp/jsp2/el/composite.html | 31 + .../examples/jsp/jsp2/el/composite.jsp | 110 + .../examples/jsp/jsp2/el/composite.jsp.html | 111 + .../examples/jsp/jsp2/el/functions.html | 32 + .../examples/jsp/jsp2/el/functions.jsp | 67 + .../examples/jsp/jsp2/el/functions.jsp.html | 68 + .../jsp/jsp2/el/implicit-objects.html | 31 + .../examples/jsp/jsp2/el/implicit-objects.jsp | 90 + .../jsp/jsp2/el/implicit-objects.jsp.html | 91 + .../jsp/jsp2/jspattribute/FooBean.java.html | 37 + .../HelloWorldSimpleTag.java.html | 35 + .../jspattribute/ShuffleSimpleTag.java.html | 88 + .../jsp2/jspattribute/TileSimpleTag.java.html | 49 + .../jsp/jsp2/jspattribute/jspattribute.html | 37 + .../jsp/jsp2/jspattribute/jspattribute.jsp | 46 + .../jsp2/jspattribute/jspattribute.jsp.html | 47 + .../jsp/jsp2/jspattribute/shuffle.html | 37 + .../jsp/jsp2/jspattribute/shuffle.jsp | 90 + .../jsp/jsp2/jspattribute/shuffle.jsp.html | 91 + .../webapps/examples/jsp/jsp2/jspx/basic.html | 31 + .../webapps/examples/jsp/jsp2/jspx/basic.jspx | 48 + .../examples/jsp/jsp2/jspx/basic.jspx.html | 49 + .../examples/jsp/jsp2/jspx/svgexample.html | 46 + .../examples/jsp/jsp2/jspx/textRotate.html | 32 + .../examples/jsp/jsp2/jspx/textRotate.jpg | Bin 0 -> 26729 bytes .../examples/jsp/jsp2/jspx/textRotate.jspx | 53 + .../jsp/jsp2/jspx/textRotate.jspx.html | 54 + .../jsp/jsp2/misc/EchoAttributesTag.java.html | 58 + .../webapps/examples/jsp/jsp2/misc/coda.jspf | 21 + .../examples/jsp/jsp2/misc/coda.jspf.html | 22 + .../examples/jsp/jsp2/misc/config.html | 35 + .../webapps/examples/jsp/jsp2/misc/config.jsp | 32 + .../examples/jsp/jsp2/misc/config.jsp.html | 33 + .../examples/jsp/jsp2/misc/dynamicattrs.html | 33 + .../examples/jsp/jsp2/misc/dynamicattrs.jsp | 44 + .../jsp/jsp2/misc/dynamicattrs.jsp.html | 45 + .../examples/jsp/jsp2/misc/prelude.jspf | 21 + .../examples/jsp/jsp2/misc/prelude.jspf.html | 22 + .../jsp/jsp2/simpletag/BookBean.java.html | 45 + .../simpletag/FindBookSimpleTag.java.html | 47 + .../jsp/jsp2/simpletag/Functions.java.html | 46 + .../simpletag/HelloWorldSimpleTag.java.html | 35 + .../jsp2/simpletag/RepeatSimpleTag.java.html | 45 + .../examples/jsp/jsp2/simpletag/book.html | 37 + .../examples/jsp/jsp2/simpletag/book.jsp | 55 + .../examples/jsp/jsp2/simpletag/book.jsp.html | 56 + .../examples/jsp/jsp2/simpletag/hello.html | 33 + .../examples/jsp/jsp2/simpletag/hello.jsp | 31 + .../jsp/jsp2/simpletag/hello.jsp.html | 32 + .../examples/jsp/jsp2/simpletag/repeat.html | 33 + .../examples/jsp/jsp2/simpletag/repeat.jsp | 39 + .../jsp/jsp2/simpletag/repeat.jsp.html | 40 + .../jsp2/tagfiles/displayProducts.tag.html | 56 + .../examples/jsp/jsp2/tagfiles/hello.html | 33 + .../examples/jsp/jsp2/tagfiles/hello.jsp | 35 + .../examples/jsp/jsp2/tagfiles/hello.jsp.html | 36 + .../jsp/jsp2/tagfiles/helloWorld.tag.html | 18 + .../examples/jsp/jsp2/tagfiles/panel.html | 33 + .../examples/jsp/jsp2/tagfiles/panel.jsp | 58 + .../examples/jsp/jsp2/tagfiles/panel.jsp.html | 59 + .../examples/jsp/jsp2/tagfiles/panel.tag.html | 30 + .../examples/jsp/jsp2/tagfiles/products.html | 33 + .../examples/jsp/jsp2/tagfiles/products.jsp | 54 + .../jsp/jsp2/tagfiles/products.jsp.html | 55 + .../jsp/jsptoserv/ServletToJsp.java.html | 40 + .../webapps/examples/jsp/jsptoserv/hello.jsp | 26 + .../examples/jsp/jsptoserv/hello.jsp.html | 27 + .../examples/jsp/jsptoserv/jsptoservlet.jsp | 23 + .../jsp/jsptoserv/jsptoservlet.jsp.html | 24 + .../webapps/examples/jsp/jsptoserv/jts.html | 36 + .../webapps/examples/jsp/num/numguess.html | 34 + .../webapps/examples/jsp/num/numguess.jsp | 69 + .../examples/jsp/num/numguess.jsp.html | 70 + .../examples/jsp/plugin/applet/Clock2.class | Bin 0 -> 5869 bytes .../examples/jsp/plugin/applet/Clock2.java | 230 + .../webapps/examples/jsp/plugin/plugin.html | 30 + .../webapps/examples/jsp/plugin/plugin.jsp | 34 + .../examples/jsp/plugin/plugin.jsp.html | 35 + .../examples/jsp/security/protected/error.jsp | 25 + .../jsp/security/protected/error.jsp.html | 26 + .../examples/jsp/security/protected/index.jsp | 82 + .../jsp/security/protected/index.jsp.html | 83 + .../examples/jsp/security/protected/login.jsp | 38 + .../jsp/security/protected/login.jsp.html | 39 + .../examples/jsp/sessions/DummyCart.html | 56 + .../webapps/examples/jsp/sessions/carts.html | 53 + .../webapps/examples/jsp/sessions/carts.jsp | 43 + .../examples/jsp/sessions/carts.jsp.html | 44 + .../webapps/examples/jsp/sessions/crt.html | 34 + .../webapps/examples/jsp/simpletag/foo.html | 30 + .../webapps/examples/jsp/simpletag/foo.jsp | 38 + .../examples/jsp/simpletag/foo.jsp.html | 39 + .../webapps/examples/jsp/snp/snoop.html | 31 + .../tomcat/webapps/examples/jsp/snp/snoop.jsp | 56 + .../webapps/examples/jsp/snp/snoop.jsp.html | 57 + .../tomcat/webapps/examples/jsp/source.jsp | 20 + .../webapps/examples/jsp/source.jsp.html | 21 + .../examples/jsp/tagplugin/choose.html | 36 + .../webapps/examples/jsp/tagplugin/choose.jsp | 54 + .../examples/jsp/tagplugin/choose.jsp.html | 55 + .../examples/jsp/tagplugin/foreach.html | 36 + .../examples/jsp/tagplugin/foreach.jsp | 54 + .../examples/jsp/tagplugin/foreach.jsp.html | 55 + .../webapps/examples/jsp/tagplugin/howto.html | 45 + .../webapps/examples/jsp/tagplugin/if.html | 36 + .../webapps/examples/jsp/tagplugin/if.jsp | 47 + .../examples/jsp/tagplugin/if.jsp.html | 48 + .../webapps/examples/jsp/tagplugin/notes.html | 41 + .../tomcat/webapps/examples/jsp/xml/xml.html | 31 + .../tomcat/webapps/examples/jsp/xml/xml.jsp | 70 + .../webapps/examples/jsp/xml/xml.jsp.html | 71 + .../webapps/examples/servlets/chat/index.jsp | 32 + .../examples/servlets/chat/index.jsp.html | 33 + .../webapps/examples/servlets/chat/login.jsp | 33 + .../examples/servlets/chat/login.jsp.html | 34 + .../webapps/examples/servlets/chat/post.jsp | 55 + .../examples/servlets/chat/post.jsp.html | 56 + .../webapps/examples/servlets/cookies.html | 61 + .../webapps/examples/servlets/helloworld.html | 50 + .../webapps/examples/servlets/images/code.gif | Bin 0 -> 292 bytes .../examples/servlets/images/execute.gif | Bin 0 -> 1242 bytes .../examples/servlets/images/return.gif | Bin 0 -> 1231 bytes .../webapps/examples/servlets/index.html | 186 + .../servlets/nonblocking/bytecounter.html | 32 + .../webapps/examples/servlets/reqheaders.html | 49 + .../webapps/examples/servlets/reqinfo.html | 68 + .../webapps/examples/servlets/reqparams.html | 78 + .../webapps/examples/servlets/sessions.html | 70 + .../webapps/examples/websocket/chat.xhtml | 136 + .../examples/websocket/drawboard.xhtml | 897 ++ .../webapps/examples/websocket/echo.xhtml | 184 + .../webapps/examples/websocket/index.xhtml | 32 + .../webapps/examples/websocket/snake.xhtml | 266 + .../webapps/host-manager/META-INF/context.xml | 28 + .../webapps/host-manager/WEB-INF/jsp/401.jsp | 71 + .../webapps/host-manager/WEB-INF/jsp/403.jsp | 85 + .../webapps/host-manager/WEB-INF/jsp/404.jsp | 62 + .../webapps/host-manager/WEB-INF/web.xml | 143 + .../webapps/host-manager/images/add.gif | Bin 0 -> 1037 bytes .../webapps/host-manager/images/asf-logo.svg | 226 + .../webapps/host-manager/images/code.gif | Bin 0 -> 394 bytes .../webapps/host-manager/images/design.gif | Bin 0 -> 608 bytes .../webapps/host-manager/images/docs.gif | Bin 0 -> 261 bytes .../webapps/host-manager/images/fix.gif | Bin 0 -> 345 bytes .../webapps/host-manager/images/tomcat.gif | Bin 0 -> 2066 bytes .../webapps/host-manager/images/update.gif | Bin 0 -> 627 bytes .../webapps/host-manager/images/void.gif | Bin 0 -> 43 bytes .../tomcat/webapps/host-manager/index.jsp | 18 + .../tomcat/webapps/host-manager/manager.xml | 26 + .../webapps/manager/META-INF/context.xml | 28 + .../webapps/manager/WEB-INF/jsp/401.jsp | 80 + .../webapps/manager/WEB-INF/jsp/403.jsp | 95 + .../webapps/manager/WEB-INF/jsp/404.jsp | 63 + .../manager/WEB-INF/jsp/connectorCiphers.jsp | 92 + .../manager/WEB-INF/jsp/sessionDetail.jsp | 197 + .../manager/WEB-INF/jsp/sessionsList.jsp | 172 + .../tomcat/webapps/manager/WEB-INF/web.xml | 213 + .../tomcat/webapps/manager/images/add.gif | Bin 0 -> 1037 bytes .../webapps/manager/images/asf-logo.svg | 226 + .../tomcat/webapps/manager/images/code.gif | Bin 0 -> 394 bytes .../tomcat/webapps/manager/images/design.gif | Bin 0 -> 608 bytes .../tomcat/webapps/manager/images/docs.gif | Bin 0 -> 261 bytes .../tomcat/webapps/manager/images/fix.gif | Bin 0 -> 345 bytes .../tomcat/webapps/manager/images/tomcat.gif | Bin 0 -> 2066 bytes .../tomcat/webapps/manager/images/update.gif | Bin 0 -> 627 bytes .../tomcat/webapps/manager/images/void.gif | Bin 0 -> 43 bytes .../tomcat/webapps/manager/index.jsp | 18 + .../tomcat/webapps/manager/status.xsd | 84 + .../tomcat/webapps/manager/xform.xsl | 125 + 584 files changed, 73553 insertions(+), 5 deletions(-) create mode 100644 test.dockerapp/tomcat/webapps/ROOT/RELEASE-NOTES.txt create mode 100644 test.dockerapp/tomcat/webapps/ROOT/WEB-INF/web.xml create mode 100644 test.dockerapp/tomcat/webapps/ROOT/asf-logo-wide.svg create mode 100644 test.dockerapp/tomcat/webapps/ROOT/bg-button.png create mode 100644 test.dockerapp/tomcat/webapps/ROOT/bg-middle.png create mode 100644 test.dockerapp/tomcat/webapps/ROOT/bg-nav-item.png create mode 100644 test.dockerapp/tomcat/webapps/ROOT/bg-nav.png create mode 100644 test.dockerapp/tomcat/webapps/ROOT/bg-upper.png create mode 100644 test.dockerapp/tomcat/webapps/ROOT/favicon.ico create mode 100644 test.dockerapp/tomcat/webapps/ROOT/index.jsp create mode 100644 test.dockerapp/tomcat/webapps/ROOT/tomcat-power.gif create mode 100644 test.dockerapp/tomcat/webapps/ROOT/tomcat.css create mode 100644 test.dockerapp/tomcat/webapps/ROOT/tomcat.gif create mode 100644 test.dockerapp/tomcat/webapps/ROOT/tomcat.png create mode 100644 test.dockerapp/tomcat/webapps/ROOT/tomcat.svg create mode 100644 test.dockerapp/tomcat/webapps/docs/BUILDING.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/RELEASE-NOTES.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/RUNNING.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/WEB-INF/web.xml create mode 100644 test.dockerapp/tomcat/webapps/docs/aio.html create mode 100644 test.dockerapp/tomcat/webapps/docs/api/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/build.xml.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/deployment.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/installation.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/introduction.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/processes.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/build.xml create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/docs/README.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/sample.war create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/src/mypackage/Hello.java create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/web/WEB-INF/web.xml create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/web/hello.jsp create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/web/images/tomcat.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/sample/web/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/source.html create mode 100644 test.dockerapp/tomcat/webapps/docs/appdev/web.xml.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/apr.html create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/overview.html create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/requestProcess.html create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/requestProcess/authentication-process.png create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/requestProcess/request-process.png create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/startup.html create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/startup/serverStartup.pdf create mode 100644 test.dockerapp/tomcat/webapps/docs/architecture/startup/serverStartup.txt create mode 100644 test.dockerapp/tomcat/webapps/docs/balancer-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/building.html create mode 100644 test.dockerapp/tomcat/webapps/docs/cgi-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/changelog.html create mode 100644 test.dockerapp/tomcat/webapps/docs/class-loader-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/cluster-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/comments.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/ajp.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/automatic-deployment.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-channel.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-deployer.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-interceptor.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-listener.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-manager.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-membership.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-receiver.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-sender.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster-valve.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cluster.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/context.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/cookie-processor.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/credentialhandler.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/engine.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/executor.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/filter.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/globalresources.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/host.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/http.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/jar-scan-filter.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/jar-scanner.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/listeners.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/loader.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/manager.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/realm.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/resources.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/server.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/service.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/sessionidgenerator.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/systemprops.html create mode 100644 test.dockerapp/tomcat/webapps/docs/config/valve.html create mode 100644 test.dockerapp/tomcat/webapps/docs/connectors.html create mode 100644 test.dockerapp/tomcat/webapps/docs/default-servlet.html create mode 100644 test.dockerapp/tomcat/webapps/docs/deployer-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/developers.html create mode 100644 test.dockerapp/tomcat/webapps/docs/elapi/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/extras.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-apps.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-objects.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-opers.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-default.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jdbc-realm.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jndi-realm.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/fs-memory-realm.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/funcspecs/mbean-names.html create mode 100644 test.dockerapp/tomcat/webapps/docs/host-manager-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/html-host-manager-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/html-manager-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/images/add.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/asf-logo.svg create mode 100644 test.dockerapp/tomcat/webapps/docs/images/code.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/cors-flowchart.png create mode 100644 test.dockerapp/tomcat/webapps/docs/images/design.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/docs-stylesheet.css create mode 100644 test.dockerapp/tomcat/webapps/docs/images/docs.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fix.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans400.woff create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans400italic.woff create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans600.woff create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans600italic.woff create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans700.woff create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans700italic.woff create mode 100644 test.dockerapp/tomcat/webapps/docs/images/fonts/fonts.css create mode 100644 test.dockerapp/tomcat/webapps/docs/images/printer.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/tomcat.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/tomcat.png create mode 100644 test.dockerapp/tomcat/webapps/docs/images/tomcat.svg create mode 100644 test.dockerapp/tomcat/webapps/docs/images/update.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/images/void.gif create mode 100644 test.dockerapp/tomcat/webapps/docs/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/introduction.html create mode 100644 test.dockerapp/tomcat/webapps/docs/jasper-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/jdbc-pool.html create mode 100644 test.dockerapp/tomcat/webapps/docs/jndi-datasource-examples-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/jndi-resources-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/jspapi/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/logging.html create mode 100644 test.dockerapp/tomcat/webapps/docs/manager-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/maven-jars.html create mode 100644 test.dockerapp/tomcat/webapps/docs/mbeans-descriptors-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/mbeans-descriptors.dtd create mode 100644 test.dockerapp/tomcat/webapps/docs/monitoring.html create mode 100644 test.dockerapp/tomcat/webapps/docs/proxy-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/realm-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/rewrite.html create mode 100644 test.dockerapp/tomcat/webapps/docs/security-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/security-manager-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/servletapi/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/setup.html create mode 100644 test.dockerapp/tomcat/webapps/docs/ssi-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/ssl-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/developers.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/faq.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/interceptors.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/introduction.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/membership.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/setup.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/status.html create mode 100644 test.dockerapp/tomcat/webapps/docs/tribes/transport.html create mode 100644 test.dockerapp/tomcat/webapps/docs/virtual-hosting-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/web-socket-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/websocketapi/index.html create mode 100644 test.dockerapp/tomcat/webapps/docs/windows-auth-howto.html create mode 100644 test.dockerapp/tomcat/webapps/docs/windows-service-howto.html create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/HelloWorldExample.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/HelloWorldExample.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings.properties create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_en.properties create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_es.properties create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_fr.properties create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_pt.properties create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestInfoExample.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestInfoExample.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestParamExample.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestParamExample.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/ServletToJsp.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/ServletToJsp.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/SessionExample.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/SessionExample.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async0$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async0.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async0.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async1$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async1.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async2$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async2.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async2.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async3.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Async3.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/AsyncStockContextListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/AsyncStockContextListener.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/AsyncStockServlet.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/AsyncStockServlet.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Stockticker$Stock.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Stockticker$TickListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Stockticker.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/async/Stockticker.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/Entries.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/Entries.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/Entry.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/Entry.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/JspCalendar.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/JspCalendar.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/TableBean.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/cal/TableBean.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/chat/ChatServlet$MessageSender.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/chat/ChatServlet.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/chat/ChatServlet.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/checkbox/CheckTest.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/checkbox/CheckTest.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/colors/ColorGameBean.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/colors/ColorGameBean.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilter.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilter.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionResponseStream.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionResponseStream.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/LogTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/LogTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ShowSource.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ShowSource.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/filters/ExampleFilter.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/filters/ExampleFilter.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/BookBean.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/BookBean.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/FooBean.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/FooBean.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/ValuesBean.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/ValuesBean.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/el/Functions.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/el/Functions.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/ShuffleSimpleTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/ShuffleSimpleTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/SessionListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/SessionListener.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter$CounterListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter$NumberWriterListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/num/NumberGuessBean.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/num/NumberGuessBean.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/CookieFilter.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/CookieFilter.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/HTMLFilter.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/HTMLFilter.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/validators/DebugValidator.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/validators/DebugValidator.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/ExamplesConfig.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/ExamplesConfig.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage$ParseException.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$2.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$3$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$3.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$1$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$2.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$MessageType.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$Player.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/CloseWebsocketMessage.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/CloseWebsocketMessage.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/StringWebsocketMessage.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/StringWebsocketMessage.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAnnotation.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAnnotation.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation$CompletedFuture.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$EchoMessageHandlerBinary.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$EchoMessageHandlerText.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/servers.json create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer$1.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.class create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/applet/Clock2.java create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/debug-taglib.tld create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/example-taglib.tld create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp2/jsp2-example-taglib.tld create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/lib/taglibs-standard-impl-1.2.5.jar create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/lib/taglibs-standard-spec-1.2.5.jar create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/displayProducts.tag create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/helloWorld.tag create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/panel.tag create mode 100644 test.dockerapp/tomcat/webapps/examples/WEB-INF/web.xml create mode 100644 test.dockerapp/tomcat/webapps/examples/index.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/Entries.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/Entry.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/JspCalendar.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/TableBean.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/calendar.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/cal/login.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/checkbox/CheckTest.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/checkbox/check.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/checkbox/cresult.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/colors/ColorGameBean.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/colors/clr.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/colors/colors.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/dates/date.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/error/er.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/error/error.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/forward/fwd.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/forward/two.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/images/code.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/images/execute.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/images/read.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/images/return.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/include/foo.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/include/inc.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/index.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/Functions.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesBean.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/FooBean.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/HelloWorldSimpleTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/ShuffleSimpleTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/TileSimpleTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/svgexample.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jpg create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/EchoAttributesTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/BookBean.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/FindBookSimpleTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/Functions.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/HelloWorldSimpleTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/RepeatSimpleTag.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/displayProducts.tag.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/helloWorld.tag.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.tag.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/ServletToJsp.java.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jts.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/plugin/applet/Clock2.class create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/plugin/applet/Clock2.java create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/sessions/DummyCart.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/sessions/crt.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/source.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/source.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/howto.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/notes.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.html create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/cookies.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/helloworld.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/images/code.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/images/execute.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/images/return.gif create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/index.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/nonblocking/bytecounter.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/reqheaders.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/reqinfo.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/reqparams.html create mode 100644 test.dockerapp/tomcat/webapps/examples/servlets/sessions.html create mode 100644 test.dockerapp/tomcat/webapps/examples/websocket/chat.xhtml create mode 100644 test.dockerapp/tomcat/webapps/examples/websocket/drawboard.xhtml create mode 100644 test.dockerapp/tomcat/webapps/examples/websocket/echo.xhtml create mode 100644 test.dockerapp/tomcat/webapps/examples/websocket/index.xhtml create mode 100644 test.dockerapp/tomcat/webapps/examples/websocket/snake.xhtml create mode 100644 test.dockerapp/tomcat/webapps/host-manager/META-INF/context.xml create mode 100644 test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/401.jsp create mode 100644 test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/403.jsp create mode 100644 test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/404.jsp create mode 100644 test.dockerapp/tomcat/webapps/host-manager/WEB-INF/web.xml create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/add.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/asf-logo.svg create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/code.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/design.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/docs.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/fix.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/tomcat.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/update.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/images/void.gif create mode 100644 test.dockerapp/tomcat/webapps/host-manager/index.jsp create mode 100644 test.dockerapp/tomcat/webapps/host-manager/manager.xml create mode 100644 test.dockerapp/tomcat/webapps/manager/META-INF/context.xml create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/401.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/403.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/404.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/connectorCiphers.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionDetail.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionsList.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/WEB-INF/web.xml create mode 100644 test.dockerapp/tomcat/webapps/manager/images/add.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/asf-logo.svg create mode 100644 test.dockerapp/tomcat/webapps/manager/images/code.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/design.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/docs.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/fix.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/tomcat.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/update.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/images/void.gif create mode 100644 test.dockerapp/tomcat/webapps/manager/index.jsp create mode 100644 test.dockerapp/tomcat/webapps/manager/status.xsd create mode 100644 test.dockerapp/tomcat/webapps/manager/xform.xsl diff --git a/.gitignore b/.gitignore index 7435cca..abfc968 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,8 @@ test.dockerapp/tomcat/certificates/ test.dockerapp/tomcat/webapps/ -!test.dockerapp/tomcat/webapps/manager/ -!test.dockerapp/tomcat/webapps/host-manager/ -!test.dockerapp/tomcat/webapps/examples/ -!test.dockerapp/tomcat/webapps/docs/ -!test.dockerapp/tomcat/webapps/ROOT/ +!test.dockerapp/tomcat/webapps/manager +!test.dockerapp/tomcat/webapps/host-manager +!test.dockerapp/tomcat/webapps/examples +!test.dockerapp/tomcat/webapps/docs +!test.dockerapp/tomcat/webapps/ROOT diff --git a/test.dockerapp/tomcat/webapps/ROOT/RELEASE-NOTES.txt b/test.dockerapp/tomcat/webapps/ROOT/RELEASE-NOTES.txt new file mode 100644 index 0000000..7e3d6f1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/ROOT/RELEASE-NOTES.txt @@ -0,0 +1,172 @@ +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +================================================================================ + + + Apache Tomcat Version 8.0.53 + Release Notes + + +========= +CONTENTS: +========= + +* Dependency Changes +* API Stability +* Bundled APIs +* Web application reloading and static fields in shared libraries +* Security manager URLs +* Symlinking static resources +* Viewing the Tomcat Change Log +* Cryptographic software notice +* When all else fails + + +=================== +Dependency Changes: +=================== +Tomcat 8.0 is designed to run on Java SE 7 and later. + + +============== +API Stability: +============== + +The public interfaces for the following classes are fixed and will not be +changed at all during the remaining lifetime of the 8.x series: +- All classes in the javax namespace + +The public interfaces for the following classes may be added to in order to +resolve bugs and/or add new features. No existing interface method will be +removed or changed although it may be deprecated. +- org.apache.catalina.* (excluding sub-packages) + +Note: As Tomcat 8 matures, the above list will be added to. The list is not + considered complete at this time. + +The remaining classes are considered part of the Tomcat internals and may change +without notice between point releases. + + +============= +Bundled APIs: +============= +A standard installation of Tomcat 8.0 makes all of the following APIs available +for use by web applications (by placing them in "lib"): +* annotations-api.jar (Annotations package) +* catalina.jar (Tomcat Catalina implementation) +* catalina-ant.jar (Tomcat Catalina Ant tasks) +* catalina-ha.jar (High availability package) +* catalina-storeconfig.jar (Generation of XML configuration from current state) +* catalina-tribes.jar (Group communication) +* ecj-4.6.3.jar (Eclipse JDT Java compiler) +* el-api.jar (EL 3.0 API) +* jasper.jar (Jasper 2 Compiler and Runtime) +* jasper-el.jar (Jasper 2 EL implementation) +* jsp-api.jar (JSP 2.3 API) +* servlet-api.jar (Servlet 3.1 API) +* tomcat-api.jar (Interfaces shared by Catalina and Jasper) +* tomcat-coyote.jar (Tomcat connectors and utility classes) +* tomcat-dbcp.jar (package renamed database connection pool based on Commons DBCP) +* tomcat-jdbc.jar (Tomcat's database connection pooling solution) +* tomcat-jni.jar (Interface to the native component of the APR/native connector) +* tomcat-util.jar (Various utilities) +* tomcat-websocket.jar (WebSocket 1.1 implementation) +* websocket-api.jar (WebSocket 1.1 API) + +You can make additional APIs available to all of your web applications by +putting unpacked classes into a "classes" directory (not created by default), +or by placing them in JAR files in the "lib" directory. + +To override the XML parser implementation or interfaces, use the endorsed +mechanism of the JVM. The default configuration defines JARs located in +"endorsed" as endorsed. This mechanism is no longer supported with Java 9. + + +================================================================ +Web application reloading and static fields in shared libraries: +================================================================ +Some shared libraries (many are part of the JDK) keep references to objects +instantiated by the web application. To avoid class loading related problems +(ClassCastExceptions, messages indicating that the classloader +is stopped, etc.), the shared libraries state should be reinitialized. + +Something which might help is to avoid putting classes which would be +referenced by a shared static field in the web application classloader, +and putting them in the shared classloader instead (JARs should be put in the +"lib" folder, and classes should be put in the "classes" folder). + + +====================== +Security manager URLs: +====================== +In order to grant security permissions to JARs located inside the +web application repository, use URLs of of the following format +in your policy file: + +file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar + + +============================ +Symlinking static resources: +============================ +By default, Unix symlinks will not work when used in a web application to link +resources located outside the web application root directory. + +This behavior is optional, and the "allowLinking" flag may be used to disable +the check. + + +============================== +Viewing the Tomcat Change Log: +============================== +The full change log is available from https://tomcat.apache.org and is also +included in the documentation web application. + + +============================= +Cryptographic software notice +============================= +This distribution includes cryptographic software. The country in +which you currently reside may have restrictions on the import, +possession, use, and/or re-export to another country, of +encryption software. BEFORE using any encryption software, please +check your country's laws, regulations and policies concerning the +import, possession, or use, and re-export of encryption software, to +see if this is permitted. See for more +information. + +The U.S. Government Department of Commerce, Bureau of Industry and +Security (BIS), has classified this software as Export Commodity +Control Number (ECCN) 5D002.C.1, which includes information security +software using or performing cryptographic functions with asymmetric +algorithms. The form and manner of this Apache Software Foundation +distribution makes it eligible for export under the License Exception +ENC Technology Software Unrestricted (TSU) exception (see the BIS +Export Administration Regulations, Section 740.13) for both object +code and source code. + +The following provides more details on the included cryptographic +software: + - Tomcat includes code designed to work with JSSE + - Tomcat includes code designed to work with OpenSSL + + +==================== +When all else fails: +==================== +See the FAQ +https://tomcat.apache.org/faq/ diff --git a/test.dockerapp/tomcat/webapps/ROOT/WEB-INF/web.xml b/test.dockerapp/tomcat/webapps/ROOT/WEB-INF/web.xml new file mode 100644 index 0000000..55fc211 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/ROOT/WEB-INF/web.xml @@ -0,0 +1,30 @@ + + + + + Welcome to Tomcat + + Welcome to Tomcat + + + diff --git a/test.dockerapp/tomcat/webapps/ROOT/asf-logo-wide.svg b/test.dockerapp/tomcat/webapps/ROOT/asf-logo-wide.svg new file mode 100644 index 0000000..5743c42 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/ROOT/asf-logo-wide.svg @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/ROOT/bg-button.png b/test.dockerapp/tomcat/webapps/ROOT/bg-button.png new file mode 100644 index 0000000000000000000000000000000000000000..b544bbfcdf91f6044ece15ffd1ca57575cebb8ee GIT binary patch literal 713 zcmV;)0yh1LP)8;Kh4yc88a9&Xs#a;crB)WJpK+3`7r~*sH&=# z&*$&aK8-j=7tiyY`Fw7S$78+SZoi_VU!>oGNyLyjm=SK7ruj@!l*b5N{ID$Rd97A^ zO3N$KikT$Azp+vx4~N4?jYi`MLKRO6g~I(-t99A$_YIy!ydZ# zKj+LFfk9Hs4o}u4xk*YS)`#3C<%R9cOz?IUMCdll`;2SS4-)G;rmPL&=Ge^X?$72XxFIAi vwodbN5Ixv+cEwG?O!1Si*W5tD9{~mcOy(T`4wOWJ00000NkvXXu0mjf|HwjX literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/ROOT/bg-middle.png b/test.dockerapp/tomcat/webapps/ROOT/bg-middle.png new file mode 100644 index 0000000000000000000000000000000000000000..0c95a828d10281783d0cf82dba498f954320346e GIT binary patch literal 1918 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 Z_ip9o=XZF$ZAu$O{K1`Z;MeEN{{f@AXfgl* literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/ROOT/index.jsp b/test.dockerapp/tomcat/webapps/ROOT/index.jsp new file mode 100644 index 0000000..df418ab --- /dev/null +++ b/test.dockerapp/tomcat/webapps/ROOT/index.jsp @@ -0,0 +1,223 @@ +<%-- +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +--%> +<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> +<% +java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy"); +request.setAttribute("year", sdf.format(new java.util.Date())); +request.setAttribute("tomcatUrl", "https://tomcat.apache.org/"); +request.setAttribute("tomcatDocUrl", "/docs/"); +request.setAttribute("tomcatExamplesUrl", "/examples/"); +%> + + + + + <%=request.getServletContext().getServerInfo() %> + + + + + + +
+ +
+

${pageContext.servletContext.serverInfo}

+
+
+
+

If you're seeing this, you've successfully installed Tomcat. Congratulations!

+
+ +
+ + + +
+ +
+
+
+

Developer Quick Start

+ + +
+
+

Examples

+
+
+ +
+
+
+
+
+

Managing Tomcat

+

For security, access to the manager webapp is restricted. + Users are defined in:

+
$CATALINA_HOME/conf/tomcat-users.xml
+

In Tomcat 8.0 access to the manager application is split between + different users.   Read more...

+
+

Release Notes

+

Changelog

+

Migration Guide

+

Security Notices

+
+
+
+
+

Documentation

+

Tomcat 8.0 Documentation

+

Tomcat 8.0 Configuration

+

Tomcat Wiki

+

Find additional important configuration information in:

+
$CATALINA_HOME/RUNNING.txt
+

Developers may be interested in:

+ +
+
+
+
+

Getting Help

+

FAQ and Mailing Lists

+

The following mailing lists are available:

+ +
+
+
+
+ + +
+ + + diff --git a/test.dockerapp/tomcat/webapps/ROOT/tomcat-power.gif b/test.dockerapp/tomcat/webapps/ROOT/tomcat-power.gif new file mode 100644 index 0000000000000000000000000000000000000000..01c400b09a1cf2579519b5b2200cf80b4ee60a91 GIT binary patch literal 2376 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/ROOT/tomcat.css b/test.dockerapp/tomcat/webapps/ROOT/tomcat.css new file mode 100644 index 0000000..6995838 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/ROOT/tomcat.css @@ -0,0 +1,351 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +*/ +body { + margin: 10px 20px; + text-align: center; + font-family: Arial, sans-serif; +} + +h1, h2, h3, h4, h5, h6, p, ul, ol { + margin: 0 0 0.5em; +} +h1 { + font-size: 18pt; + margin: 0.5em 0 0; +} +h2 { + font-size: 16pt; +} +h3 { + font-size: 13pt; +} +h4 { + font-size: 12pt; +} +h5 { + font-size: 11pt; +} +p { + font-size: 11pt +} + +ul { + margin: 0; + padding: 0 0 0 0.25em; + text-indent: 0; + list-style: none; +} +li { + margin: 0; + padding: 0 0 0.25em; + text-indent: 0; + font-size: 80%; +} + +pre { + text-indent: 0.25em; + width: 90%; + font-size: 90%; +} + +br.separator { + margin: 0; + padding: 0; + clear: both; +} + +a img { + border: 0 none; +} + +.container { + padding: 10px; + margin: 0 0 10px; +} + +.col20 { + float: left; + width: 20%; +} + +.col25 { + float: left; + width: 25%; +} + +#wrapper { + display: block; + margin: 0 auto; + text-align: left; + min-width: 720px; + max-width: 1000px; +} +.curved { + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; +} + +#navigation { + background: #eee url(bg-nav.png) repeat-x top left; + margin: 0 0 10px; + padding: 0; +} +#navigation span { + float: left; +} +#navigation span a { + display: block; + padding: 10px; + font-weight: bold; + text-shadow: 1px 1px 1px #fff; +} +#navigation span a:link, +#navigation span a:visited, +#navigation span a:hover, +#navigation span a:active { + color: #666; + text-decoration: none; +} +#navigation span#nav-help { + float: right; + margin-right: 0; +} + +#asf-box { + height: 40px; + background: #fff url(asf-logo-wide.svg) no-repeat top right;} +#asf-box h1 { + padding: 0; + margin: 0; +} + +#upper { + background: #fff url(bg-upper.png) repeat-x top left; +} + +#congrats { + text-align: center; + padding: 10px; + margin: 0 40px 20px; + background-color: #9c9; +} +#congrats h2 { + font-size: 14pt; + padding: 0; + margin: 0; + color: #fff; +} + +#notice { + float: left; + width: 560px; + color: #696; +} +#notice a:link, +#notice a:visited, +#notice a:hover, +#notice a:active { + color: #090; + text-decoration: none; +} +#notice img, +#notice #tasks { + float: left; +} +#tasks a:link, +#tasks a:visited, +#tasks a:hover, +#tasks a:active { + text-decoration: underline; +} +#notice img { + margin-right: 20px; +} + +#actions { + float: right; + width: 140px; +} + +#actions .button { + display: block; + padding: 0; + height: 36px; + background: url(bg-button.png) no-repeat top left; +} + +#actions .button a { + display: block; + padding: 0; +} + +#actions .button a:link, +#actions .button a:visited, +#actions .button a:hover, +#actions .button a:active { + color: #696; + text-decoration: none; +} + +#actions .button a span { + display: block; + padding: 6px 10px; + color: #666; + text-shadow: 1px 1px 1px #fff; + font-size: 10pt; + font-weight: bold; +} + +#middle { + background: #eef url(bg-middle.png) repeat-x top left; + margin: 20px 0; + padding: 1px 10px; +} +#middle h3 { + margin: 0 0 10px; + color: #033; +} +#middle p { + font-size: 10pt; +} +#middle a:link, +#middle a:visited, +#middle a:hover, +#middle a:active { + color: #366; + font-weight: bold; +} +#middle .col25 .container { + padding: 0 0 1px; +} + +#developers { + float: left; + width: 40%; +} +#security { + float: right; + width: 50%; +} + +#lower { + padding: 0; +} + +#lower a:link, +#lower a:visited, +#lower a:hover, +#lower a:active { + color: #600; +} + +#lower strong a:link, +#lower strong a:visited, +#lower strong a:hover, +#lower strong a:active { + color: #c00; +} + +#lower h3 { + color: #963; + font-size: 14pt; +} +#lower h4 { + font-size: 12pt; +} +#lower ul { + padding: 0; + margin: 0.5em 0; +} +#lower p, +#lower li { + font-size: 9pt; + color: #753; + margin: 0 0 0.1em; +} +#lower li { + padding: 3px 5px; +} +#lower li strong { + color: #a53; +} +#lower li#list-announce { + border: 1px solid #f90; + background-color: #ffe8c8; +} +#lower p { + font-size: 10.5pt; +} + +#low-manage, +#low-docs, +#low-help { + float: left; + width: 32%; +} +#low-docs { + margin: 0 0 0 2.2%; +} +#low-help { + float: right; +} + +#low-manage div, +#low-docs div, +#low-help div { + min-height: 280px; + border: 3px solid #ffdc75; + background-color: #fff1c8; + padding: 10px; +} + +#footer { + padding: 0; + margin: 20px 0; + color: #999; + background-color: #eee; +} +#footer h4 { + margin: 0 0 10px; + font-size: 10pt; +} +#footer p { + margin: 0 0 10px; + font-size: 10pt; +} +#footer ul { + margin: 6px 0 1px; + padding: 0; +} +#footer li { + margin: 0; + font-size: 9pt; +} + +#footer a:link, +#footer a:visited, +#footer a:hover, +#footer a:active { + color: #666; +} + +.copyright { + font-size: 10pt; + color: #666; +} \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/ROOT/tomcat.gif b/test.dockerapp/tomcat/webapps/ROOT/tomcat.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6f863e43e3924a35854c556a9c1b6d125cba GIT binary patch literal 2066 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/ROOT/tomcat.png b/test.dockerapp/tomcat/webapps/ROOT/tomcat.png new file mode 100644 index 0000000000000000000000000000000000000000..209b07fd8a8d2429b1a0c9740dc184f803ba3c67 GIT binary patch literal 5103 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 + + + + + + + + + + + + + + + + + + + + + + + + + + 2006-05-09T08:17:21Z + 2006-05-09T08:37:38Z + Illustrator + + + + JPEG + 256 + 184 + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA +AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK +DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f +Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAuAEAAwER +AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA +AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB +UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE +1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ +qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy +obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp +0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo ++DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 +FXYq7FXYq7FXYq7FXYq7FXhH/OYHnWfQ/wAurfRLSUxXXmK49GQqaN9VtwJJqH3cxqfYnFXhP5Y/ +85O+f/JU0enaw769okbBJLS8ZvrUKg0IhnarDj/I9R2HHFX2F+Xn5neT/P8ApP6R8u3glKAfW7KS +iXNuzdFljqaezCqnsTirK8VdirsVdirsVdirsVdirC/zM/Nvyd+XemC71255Xcqk2WmQUa5nI2+F +CRxUd3ag+nbFXx1+Zf8Azkn+YvneaW1tLh9C0NgwXTrB2V3Sm/rzji8m3UDitP2cVfV//OOfmabz +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 + + + + + + + image/svg+xml + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +/Dn4G1vgFa2715u9zrn+L1T7Dxc= + + + TM + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/BUILDING.txt b/test.dockerapp/tomcat/webapps/docs/BUILDING.txt new file mode 100644 index 0000000..0ad68a2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/BUILDING.txt @@ -0,0 +1,568 @@ +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +================================================================================ + + ==================================================== + Building The Apache Tomcat 8.0 Servlet/JSP Container + ==================================================== + +This subproject contains the source code for Tomcat 8.0, a container that +implements the Servlet 3.1, JSP 2.3, EL 3.0 and WebSocket 1.1 specifications +from the Java Community Process . + +Note: If you just need to run Apache Tomcat, it is not necessary to build +it. You may simply download a binary distribution. It is cross-platform. +Read RUNNING.txt for the instruction on how to run it. + +In order to build a binary distribution version of Apache Tomcat from a +source distribution, do the following: + + +(1) Download and Install a Java Development Kit + + 1. If the JDK is already installed, skip to (2). + + 2. Download a version 7 of Java Development Kit (JDK) release (use the + latest update available for your chosen version) from one of: + + http://www.oracle.com/technetwork/java/javase/downloads/index.html + http://openjdk.java.net/install/index.html + or another JDK vendor. + + Note regarding later versions of Java: + + As documented elsewhere, one of components in Apache Tomcat includes + a private copy of the Apache Commons DBCP library. + + The JDBC interfaces implemented by DBCP frequently change in non-backwards + compatible ways between versions of the Java SE specification. Therefore, + it is likely that DBCP will only compile with the specific version of Java + listed above and that compilation will fail if a later version of Java is + used. + + See Apache Commons DBCP project web site for more details on + available versions of the library and its requirements, + + https://commons.apache.org/dbcp/ + + 3. Install the JDK according to the instructions included with the release. + + 4. Set an environment variable JAVA_HOME to the pathname of the directory + into which you installed the JDK release. + + +(2) Install Apache Ant version 1.9.8 or later on your computer. + + 1. If Apache Ant version 1.9.8 or later is already installed on your + computer, skip to (3). + + 2. Download a binary distribution of Ant from: + + https://ant.apache.org/bindownload.cgi + + 3. Unpack the binary distribution into a convenient location so that the + Ant release resides in its own directory (conventionally named + "apache-ant-[version]"). + + For the purposes of the remainder of this document, the symbolic name + "${ant.home}" is used to refer to the full pathname of the release + directory. + + 4. Create an ANT_HOME environment variable to point the directory + ${ant.home}. + + 5. Modify the PATH environment variable to include the directory + ${ant.home}/bin in its list. This makes the "ant" command line script + available, which will be used to actually perform the build. + + +(3) Building Tomcat 8.0 + +(3.1) Checkout or obtain the source code for Tomcat 8.0 + +Checkout the source using SVN, selecting a tag for released version or +trunk for the current development code, or download and unpack a source +package. + + * Tomcat SVN repository URL: + + https://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ + + * Source packages can be downloaded from: + + https://tomcat.apache.org/download-80.cgi + +The location where the source has been placed will be further referred as +${tomcat.source}. + +The Tomcat local build process does not modify line-endings. The svn repository +is configured so that all files will be checked out with the line-ending +appropriate for the current platform. When using a source package you should +ensure that you use the source package that has the appropriate line-ending +for your platform: + + zip -> CRLF + tar.gz -> LF + +Note that the release build process does modify line-endings to ensure that +each release package has the appropriate line-endings. + +(3.2) Building + + 1. The build is controlled by creating a ${tomcat.source}/build.properties + file. + + It is recommended to always create the file, because of unfortunate + default value of base.path property. You may start with the following + content for the file: + + # ----- Default Base Path for Dependent Packages ----- + # Replace this path with the directory path where dependencies binaries + # should be downloaded + base.path=/home/me/some-place-to-download-to + + 2. Configure base.path property by adding it to the + ${tomcat.source}/build.properties file. + + The base.path property specifies the place where Tomcat dependencies + required by the build are downloaded. It is recommended to place this + directory outside of the source tree, so that you do not waste your + time re-downloading the libraries. + +* NOTE: The default value of the base.path property configures the build script + to download the libraries required to build Tomcat to the + ${user.home}/tomcat-build-libs directory. + +* NOTE: Users accessing the Internet through a proxy must use the properties + file to indicate to Ant the proxy configuration. + + The following properties should be added to the ${tomcat.source}/build.properties + file. + + proxy.use=true + proxy.host=proxy.domain + proxy.port=8080 + proxy.user=username + proxy.password=password + + See Apache Ant documentation for the task for details. + + 3. Go to the sources directory and run Ant: + + cd ${tomcat.source} + ant + + This will execute the "deploy" target in build.xml. + + Once the build has completed successfully, a usable Tomcat installation + will have been produced in the ${tomcat.source}/output/build directory, + and can be started and stopped with the usual scripts. + + Note that the build includes Tomcat documentation, which can be found + in the output/build/webapps/docs directory. + + The path of the output directory can be controlled by specifying the + "tomcat.output" property in the build.properties file. + +* NOTE: Do not run the build as the root user. Building and running Tomcat + does not require root privileges. + + +(4) Updating sources and rebuilding + +It is recommended that you regularly update the downloaded Tomcat 8.0 +sources using your SVN client. + +For a quick rebuild of only modified code you can use: + + cd ${tomcat.source} + ant + + +(5) Special builds + +There are several targets in Tomcat build files that are useful to be +called separately. They build components that you may want to build +quickly, or ones that are included in the full release and are not built +during the default "deploy" build. + +(5.1) Building documentation + +The documentation web application is built during the default "deploy" +build. + +It can be built quickly by using the following commands: + + cd ${tomcat.source} + ant build-docs + +The output of this command will be found in the following directory: + + output/build/webapps/docs + + +The API documentation (Javadoc) is built during a "release" build. It is +easy to build it separately by using the following commands: + + cd ${tomcat.source} + ant javadoc + +The output of this command will be found in the following directories: + + output/dist/webapps/docs/api + output/dist/webapps/docs/elapi + output/dist/webapps/docs/jspapi + output/dist/webapps/docs/servletapi + + +(5.2) Building the extras (commons-logging, webservices etc.) + +These components are documented on the "Additional Components" +(extras.html) page of documentation. They are built during a "release" +build. + +You can build them by using the following commands: + + cd ${tomcat.source} + ant extras + +(5.3) Building the embedded packages + +These are built during a "release" build. + +You can build them by using the following commands: + + cd ${tomcat.source} + ant embed + + +(6) Building a full release (as provided via the ASF download pages) + + A full release includes the Windows installer which requires a Windows + environment to be available to create it. If not building in a Windows + environment, the build scripts assume that Wine is available. If this is not + the case, the skip.installer property may be set to skip the creation of the + Windows installer. + + 1. Configure GPG, if needed + + If the released artifacts have to be cryptographically signed with a + PGP signature, like the official ASF releases are, the following + property can be added to the build.properties file: + + # Location of GPG executable (used only for releases) + gpg.exec=/path/to/gpg + + You do not need it if you do not plan to sign the release. + + If "gpg.exec" property does not point to an existing file, it will be + ignored and this feature will be disabled. + + You will be prompted for the GPG passphrase when the release build + starts, unless "gpg.passphrase" property is set. + + 2. If building the Windows installer + + If running the build in a UAC enabled environment, building the Windows + installer requires elevated privileges. The simplest way to do this is to + open the command prompt used for the build with the "Run as administrator" + option. + + 3. Configure the code signing service + + ASF committers performing official releases will need to configure the code + signing service so that the Windows installer is signed during the build + process. The following properties need to be added to the build.properties + file: + + # Location of GPG executable (used only for releases) + # Code signing of Windows installer + do.codesigning=true + codesigning.user=request-via-pmc + codesigning.pwd=request-via-pmc + codesigning.partnercode=request-via-pmc + codesigning.service=Microsoft Windows Signing + + Release managers will be provided with the necessary credentials by the PMC. + It will also be necessary to enable TLS 1.1 and TLS 1.2 by default (they are + disabled by default on Java 7) for the build process to communicate with the + code signing service. The simplest way is by setting the ANT_OPTS + environment variable. E.g. (for Windows): + + set ANT_OPTS=-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 + + 4. Build the release: + + cd ${tomcat.source} + ant release + + +(7) Tests + +(7.1) Running Tomcat tests + +Tomcat includes a number of junit tests. The tests are not run when a +release is built. There is separate command to run them. + +To run the testsuite use the following command: + + cd ${tomcat.source} + ant test + +It is advisable to redirect output of the above command to a file for later +inspection. + +The JUnit reports generated by the tests will be written to the following +directory: + + output/build/logs + +By default the testsuite is run four times to test 4 different +implementations of Tomcat connectors: BIO, NIO, NIO2 and APR. (If you are not +familiar with Tomcat connectors, see config/http.html in documentation for +details). + +The 4 runs are enabled and disabled individually by the following +properties, which all are "true" by default: + + execute.test.bio=true + execute.test.nio=true + execute.test.nio2=true + execute.test.apr=true + +The APR connector can be tested only if Tomcat-Native library binaries are +found by the testsuite. The "test.apr.loc" property specifies the directory +where the library binaries are located. + +By default the "test.apr.loc" property specifies the following location: + + output/build/bin/native/ + +If you are on Windows and want to test the APR connector you can put the +tcnative-1.dll file into ${tomcat.source}/bin/native/ and it will be copied +into the above directory when the build runs. + +The unit tests include tests of the clustering functionality which require +multicast to be enabled. There is a simple application provided in the Tomcat +test source (org.apache.catalina.tribes.TesterMulticast) that can be used to +check if a machine supports multicast. Notes on enabling multicast for different +operating systems are provided in the Javadoc for that class. + + +(7.2) Running a single test + +It is possible to run a single JUnit test class by adding the "test.entry" +property to the build.properties file. The property specifies the name of +the test class. + +For example: + + test.entry=org.apache.catalina.util.TestServerInfo + +It is possible to further limit such run to a number of selected test +methods by adding "test.entry.methods" property. The property specifies a +comma-separated list of test case methods. + +For example: + + test.entry=org.apache.el.lang.TestELArithmetic + test.entry.methods=testMultiply01,testMultiply02 + + +(7.3) Running a set of tests + +It is possible to run a set of JUnit test classes by adding the "test.name" +property to the build.properties file. The property specifies an Ant +includes pattern for the fileset of test class files to run. + +The default value is "**/Test*.java", so all test classes are being +executed (with few exceptions - see build.xml for several exclude patterns). + +You can include multiple patterns by concatenating them with a comma (",") +as the separator. + +For example: + + test.name=**/TestSsl.java,**/TestWebSocketFrameClientSSL.java + +You can exclude specific JUnit test classes by adding the "test.exclude" +property to the build.properties file. The property specifies an Ant +excludes pattern for the fileset of test class files to exclude form the run. +The default value is empty, so no classes are excluded. The syntax is the same +as for the property "test.name". + + +(7.4) Other configuration options + + 1. It is possible to configure the directory where JUnit reports are + written to. It is configured by "test.reports" property. The default + value is + + output/build/logs + + 2. It is possible to enable generation of access log file when the tests + are run. This is off by default and can be enabled by the following + property: + + test.accesslog=true + + The "access_log." file will be written to the same directory as + JUnit reports, + + output/build/logs + + 3. The testsuite respects logging configuration as configured by + ${tomcat.source}/conf/logging.properties + + The log files will be written to the temporary directory used by the + tests, + + output/test-tmp/logs + + 4. It is possible to configure formatter used by JUnit reports. + Configuration properties are "junit.formatter.type", + "junit.formatter.extension" and "junit.formatter.usefile". + + For example the following property disables generation of separate report + files: + + junit.formatter.usefile=false + + 5. It is possible to speed up testing by letting JUnit to run several + tests in parallel. + + This is configured by setting "test.threads" property. The recommended + value is one thread per core. + + 6. Optional support is provided for the Cobertura code coverage tool. + +NOTE: Cobertura is licensed under GPL v2 with parts of it being under + Apache License v1.1. See https://cobertura.github.io/cobertura/ for details. + Using it during Tomcat build is optional and is off by default. + + Cobertura can be enabled using the following properties: + + test.cobertura=true + test.threads=1 + + Using Cobertura currently requires setting test.threads configuration + property to the value of 1. Setting that property to a different value + will disable code coverage. + + The report files by default are written to + + output/coverage + + 7. The performance tests are written to run reasonably powerful machines (such + as a developer may use day to day) assuming no other resource hungry + processes are running. + + These assumptions are not always true (e.g. on CI systems running in a + virtual machine) so the performance tests may be disabled by using the + following property: + + test.excludePerformance=true + + 8. Some tests include checks that the access log valve entries are as expected. + These checks include timings. On slower / loaded systems these checks will + often fail. The checks may be relaxed by using the following property: + + test.relaxTiming=true + + 9. It is known that some platforms (e.g. OSX El Capitan) require IPv4 to + be the default for the multicast tests to work. This is configured by + the following property: + + java.net.preferIPv4Stack=true + + 10. It is possible to control whether the output of the tests is displayed + on the console or not. By default it is displayed and can be disabled + by the following property: + + test.verbose=true + +(8) Source code checks + +(8.1) Checkstyle + +NOTE: Checkstyle is licensed under LGPL. Using Checkstyle during Tomcat + build is optional and is off by default. + + See http://checkstyle.sourceforge.net/ for more information. + +Tomcat comes with a Checkstyle configuration that tests its source code +for certain conventions, like presence of the license header. + +To enable Checkstyle, add the following property to build.properties file: + + execute.validate=true + +Once Checkstyle is enabled, the check will be performed automatically +during the build. The check is run before compilation of the source code. + +To speed-up repeated runs of this check, a cache is configured. The cache +is located in the following directory: + + output/res/checkstyle + +It is possible to run the check separately by calling the "validate" +target. The command is: + + cd ${tomcat.source} + ant -Dexecute.validate=true validate + + +(8.2) FindBugs + +NOTE: FindBugs is licensed under LGPL. Using Findbugs during Tomcat build is + optional and is off by default. + + See http://findbugs.sourceforge.net/ for more information. + +To enable FindBugs, add the following property to build.properties file: + + execute.findbugs=true + +To compile Tomcat classes and generate a FindBugs report, call the +"findbugs" target. For example: + + cd ${tomcat.source} + ant -Dexecute.findbugs=true findbugs + +The report file by default is written to + + output/findbugs + + +(8.3) End-of-line conventions check + +You usually would not need to run this check. You can skip this section. + +Apache Tomcat project has convention that all of its textual source files, +stored in Subversion repository, are marked with Subversion property +"svn:eol-style" with value of "native". This convention makes the editing +of source code on different platforms easier. + +This test is used by developers to check that the source code adheres to +this convention. It verifies that the ends of lines in textual files are +appropriate for the operating system where it is run. The idea is to run +this check regularly on two different platforms and notify developers when +an inconsistency is detected. + +The command to run this test is: + + cd ${tomcat.source} + ant validate-eoln diff --git a/test.dockerapp/tomcat/webapps/docs/RELEASE-NOTES.txt b/test.dockerapp/tomcat/webapps/docs/RELEASE-NOTES.txt new file mode 100644 index 0000000..7e3d6f1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/RELEASE-NOTES.txt @@ -0,0 +1,172 @@ +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +================================================================================ + + + Apache Tomcat Version 8.0.53 + Release Notes + + +========= +CONTENTS: +========= + +* Dependency Changes +* API Stability +* Bundled APIs +* Web application reloading and static fields in shared libraries +* Security manager URLs +* Symlinking static resources +* Viewing the Tomcat Change Log +* Cryptographic software notice +* When all else fails + + +=================== +Dependency Changes: +=================== +Tomcat 8.0 is designed to run on Java SE 7 and later. + + +============== +API Stability: +============== + +The public interfaces for the following classes are fixed and will not be +changed at all during the remaining lifetime of the 8.x series: +- All classes in the javax namespace + +The public interfaces for the following classes may be added to in order to +resolve bugs and/or add new features. No existing interface method will be +removed or changed although it may be deprecated. +- org.apache.catalina.* (excluding sub-packages) + +Note: As Tomcat 8 matures, the above list will be added to. The list is not + considered complete at this time. + +The remaining classes are considered part of the Tomcat internals and may change +without notice between point releases. + + +============= +Bundled APIs: +============= +A standard installation of Tomcat 8.0 makes all of the following APIs available +for use by web applications (by placing them in "lib"): +* annotations-api.jar (Annotations package) +* catalina.jar (Tomcat Catalina implementation) +* catalina-ant.jar (Tomcat Catalina Ant tasks) +* catalina-ha.jar (High availability package) +* catalina-storeconfig.jar (Generation of XML configuration from current state) +* catalina-tribes.jar (Group communication) +* ecj-4.6.3.jar (Eclipse JDT Java compiler) +* el-api.jar (EL 3.0 API) +* jasper.jar (Jasper 2 Compiler and Runtime) +* jasper-el.jar (Jasper 2 EL implementation) +* jsp-api.jar (JSP 2.3 API) +* servlet-api.jar (Servlet 3.1 API) +* tomcat-api.jar (Interfaces shared by Catalina and Jasper) +* tomcat-coyote.jar (Tomcat connectors and utility classes) +* tomcat-dbcp.jar (package renamed database connection pool based on Commons DBCP) +* tomcat-jdbc.jar (Tomcat's database connection pooling solution) +* tomcat-jni.jar (Interface to the native component of the APR/native connector) +* tomcat-util.jar (Various utilities) +* tomcat-websocket.jar (WebSocket 1.1 implementation) +* websocket-api.jar (WebSocket 1.1 API) + +You can make additional APIs available to all of your web applications by +putting unpacked classes into a "classes" directory (not created by default), +or by placing them in JAR files in the "lib" directory. + +To override the XML parser implementation or interfaces, use the endorsed +mechanism of the JVM. The default configuration defines JARs located in +"endorsed" as endorsed. This mechanism is no longer supported with Java 9. + + +================================================================ +Web application reloading and static fields in shared libraries: +================================================================ +Some shared libraries (many are part of the JDK) keep references to objects +instantiated by the web application. To avoid class loading related problems +(ClassCastExceptions, messages indicating that the classloader +is stopped, etc.), the shared libraries state should be reinitialized. + +Something which might help is to avoid putting classes which would be +referenced by a shared static field in the web application classloader, +and putting them in the shared classloader instead (JARs should be put in the +"lib" folder, and classes should be put in the "classes" folder). + + +====================== +Security manager URLs: +====================== +In order to grant security permissions to JARs located inside the +web application repository, use URLs of of the following format +in your policy file: + +file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar + + +============================ +Symlinking static resources: +============================ +By default, Unix symlinks will not work when used in a web application to link +resources located outside the web application root directory. + +This behavior is optional, and the "allowLinking" flag may be used to disable +the check. + + +============================== +Viewing the Tomcat Change Log: +============================== +The full change log is available from https://tomcat.apache.org and is also +included in the documentation web application. + + +============================= +Cryptographic software notice +============================= +This distribution includes cryptographic software. The country in +which you currently reside may have restrictions on the import, +possession, use, and/or re-export to another country, of +encryption software. BEFORE using any encryption software, please +check your country's laws, regulations and policies concerning the +import, possession, or use, and re-export of encryption software, to +see if this is permitted. See for more +information. + +The U.S. Government Department of Commerce, Bureau of Industry and +Security (BIS), has classified this software as Export Commodity +Control Number (ECCN) 5D002.C.1, which includes information security +software using or performing cryptographic functions with asymmetric +algorithms. The form and manner of this Apache Software Foundation +distribution makes it eligible for export under the License Exception +ENC Technology Software Unrestricted (TSU) exception (see the BIS +Export Administration Regulations, Section 740.13) for both object +code and source code. + +The following provides more details on the included cryptographic +software: + - Tomcat includes code designed to work with JSSE + - Tomcat includes code designed to work with OpenSSL + + +==================== +When all else fails: +==================== +See the FAQ +https://tomcat.apache.org/faq/ diff --git a/test.dockerapp/tomcat/webapps/docs/RUNNING.txt b/test.dockerapp/tomcat/webapps/docs/RUNNING.txt new file mode 100644 index 0000000..127b6ed --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/RUNNING.txt @@ -0,0 +1,477 @@ +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +================================================================================ + + =================================================== + Running The Apache Tomcat 8.0 Servlet/JSP Container + =================================================== + +Apache Tomcat 8.0 requires a Java Standard Edition Runtime +Environment (JRE) version 7 or later. + +============================= +Running With JRE 7 Or Later +============================= + +(1) Download and Install a Java SE Runtime Environment (JRE) + +(1.1) Download a Java SE Runtime Environment (JRE), + release version 7 or later, from + http://www.oracle.com/technetwork/java/javase/downloads/index.html + +(1.2) Install the JRE according to the instructions included with the + release. + + You may also use a full Java Development Kit (JDK) rather than just + a JRE. + + +(2) Download and Install Apache Tomcat + +(2.1) Download a binary distribution of Tomcat from: + + https://tomcat.apache.org/ + +(2.2) Unpack the binary distribution so that it resides in its own + directory (conventionally named "apache-tomcat-[version]"). + + For the purposes of the remainder of this document, the name + "CATALINA_HOME" is used to refer to the full pathname of that + directory. + +NOTE: As an alternative to downloading a binary distribution, you can +create your own from the Tomcat source code, as described in +"BUILDING.txt". You can either + + a) Do the full "release" build and find the created distribution in the + "output/release" directory and then proceed with unpacking as above, or + + b) Do a simple build and use the "output/build" directory as + "CATALINA_HOME". Be warned that there are some differences between the + contents of the "output/build" directory and a full "release" + distribution. + + +(3) Configure Environment Variables + +Tomcat is a Java application and does not use environment variables directly. +Environment variables are used by the Tomcat startup scripts. The scripts use +the environment variables to prepare the command that starts Tomcat. + +(3.1) Set CATALINA_HOME (required) and CATALINA_BASE (optional) + +The CATALINA_HOME environment variable should be set to the location of the +root directory of the "binary" distribution of Tomcat. + +The Tomcat startup scripts have some logic to set this variable +automatically if it is absent, based on the location of the startup script +in *nix and on the current directory in Windows. That logic might not work +in all circumstances, so setting the variable explicitly is recommended. + +The CATALINA_BASE environment variable specifies location of the root +directory of the "active configuration" of Tomcat. It is optional. It +defaults to be equal to CATALINA_HOME. + +Using distinct values for the CATALINA_HOME and CATALINA_BASE variables is +recommended to simplify further upgrades and maintenance. It is documented +in the "Multiple Tomcat Instances" section below. + + +(3.2) Set JRE_HOME or JAVA_HOME (required) + +These variables are used to specify location of a Java Runtime +Environment or of a Java Development Kit that is used to start Tomcat. + +The JRE_HOME variable is used to specify location of a JRE. The JAVA_HOME +variable is used to specify location of a JDK. + +Using JAVA_HOME provides access to certain additional startup options that +are not allowed when JRE_HOME is used. + +If both JRE_HOME and JAVA_HOME are specified, JRE_HOME is used. + +The recommended place to specify these variables is a "setenv" script. See +below. + + +(3.3) Other variables (optional) + +Other environment variables exist, besides the four described above. +See the comments at the top of catalina.bat or catalina.sh scripts for +the list and a description of each of them. + +One frequently used variable is CATALINA_OPTS. It allows specification of +additional options for the java command that starts Tomcat. + +See the Java documentation for the options that affect the Java Runtime +Environment. + +See the "System Properties" page in the Tomcat Configuration Reference for +the system properties that are specific to Tomcat. + +A similar variable is JAVA_OPTS. It is used less frequently. It allows +specification of options that are used both to start and to stop Tomcat as well +as for other commands. + +Note: Do not use JAVA_OPTS to specify memory limits. You do not need much +memory for a small process that is used to stop Tomcat. Those settings +belong to CATALINA_OPTS. + +Another frequently used variable is CATALINA_PID (on *nix only). It +specifies the location of the file where process id of the forked Tomcat +java process will be written. This setting is optional. It will enable the +following features: + + * better protection against duplicate start attempts and + * allows forceful termination of Tomcat process when it does not react to + the standard shutdown command. + + +(3.4) Using the "setenv" script (optional, recommended) + +Apart from CATALINA_HOME and CATALINA_BASE, all environment variables can +be specified in the "setenv" script. The script is placed either into +CATALINA_BASE/bin or into CATALINA_HOME/bin directory and is named +setenv.bat (on Windows) or setenv.sh (on *nix). The file has to be +readable. + +By default the setenv script file is absent. If the script file is present +both in CATALINA_BASE and in CATALINA_HOME, the one in CATALINA_BASE is +preferred. + +For example, to configure the JRE_HOME and CATALINA_PID variables you can +create the following script file: + +On Windows, %CATALINA_BASE%\bin\setenv.bat: + + set "JRE_HOME=%ProgramFiles%\Java\jre7" + exit /b 0 + +On *nix, $CATALINA_BASE/bin/setenv.sh: + + JRE_HOME=/usr/java/latest + CATALINA_PID="$CATALINA_BASE/tomcat.pid" + + +The CATALINA_HOME and CATALINA_BASE variables cannot be configured in the +setenv script, because they are used to locate that file. + +All the environment variables described here and the "setenv" script are +used only if you use the standard scripts to launch Tomcat. For example, if +you have installed Tomcat as a service on Windows, the service wrapper +launches Java directly and does not use the script files. + + +(4) Start Up Tomcat + +(4.1) Tomcat can be started by executing one of the following commands: + + On Windows: + + %CATALINA_HOME%\bin\startup.bat + + or + + %CATALINA_HOME%\bin\catalina.bat start + + On *nix: + + $CATALINA_HOME/bin/startup.sh + + or + + $CATALINA_HOME/bin/catalina.sh start + +(4.2) After startup, the default web applications included with Tomcat will be + available by visiting: + + http://localhost:8080/ + +(4.3) Further information about configuring and running Tomcat can be found in + the documentation included here, as well as on the Tomcat web site: + + https://tomcat.apache.org/ + + +(5) Shut Down Tomcat + +(5.1) Tomcat can be shut down by executing one of the following commands: + + On Windows: + + %CATALINA_HOME%\bin\shutdown.bat + + or + + %CATALINA_HOME%\bin\catalina.bat stop + + On *nix: + + $CATALINA_HOME/bin/shutdown.sh + + or + + $CATALINA_HOME/bin/catalina.sh stop + +================================================== +Advanced Configuration - Multiple Tomcat Instances +================================================== + +In many circumstances, it is desirable to have a single copy of a Tomcat +binary distribution shared among multiple users on the same server. To make +this possible, you can set the CATALINA_BASE environment variable to the +directory that contains the files for your 'personal' Tomcat instance. + +When running with a separate CATALINA_HOME and CATALINA_BASE, the files +and directories are split as following: + +In CATALINA_BASE: + + * bin - Only the following files: + + * setenv.sh (*nix) or setenv.bat (Windows), + * tomcat-juli.jar + + The setenv scripts were described above. The tomcat-juli library + is documented in the Logging chapter in the User Guide. + + * conf - Server configuration files (including server.xml) + + * lib - Libraries and classes, as explained below + + * logs - Log and output files + + * webapps - Automatically loaded web applications + + * work - Temporary working directories for web applications + + * temp - Directory used by the JVM for temporary files (java.io.tmpdir) + + +In CATALINA_HOME: + + * bin - Startup and shutdown scripts + + The following files will be used only if they are absent in + CATALINA_BASE/bin: + + setenv.sh (*nix), setenv.bat (Windows), tomcat-juli.jar + + * lib - Libraries and classes, as explained below + + * endorsed - Libraries that override standard "Endorsed Standards" + libraries provided by JRE. See Classloading documentation + in the User Guide for details. + No longer supported with Java 9. + + By default this "endorsed" directory is absent. + +In the default configuration the JAR libraries and classes both in +CATALINA_BASE/lib and in CATALINA_HOME/lib will be added to the common +classpath, but the ones in CATALINA_BASE will be added first and thus will +be searched first. + +The idea is that you may leave the standard Tomcat libraries in +CATALINA_HOME/lib and add other ones such as database drivers into +CATALINA_BASE/lib. + +In general it is advised to never share libraries between web applications, +but put them into WEB-INF/lib directories inside the applications. See +Classloading documentation in the User Guide for details. + + +It might be useful to note that the values of CATALINA_HOME and +CATALINA_BASE can be referenced in the XML configuration files processed +by Tomcat as ${catalina.home} and ${catalina.base} respectively. + +For example, the standard manager web application can be kept in +CATALINA_HOME/webapps/manager and loaded into CATALINA_BASE by using +the following trick: + + * Copy the CATALINA_HOME/webapps/manager/META-INF/context.xml + file as CATALINA_BASE/conf/Catalina/localhost/manager.xml + + * Add docBase attribute as shown below. + +The file will look like the following: + + + + + + +See Deployer chapter in User Guide and Context and Host chapters in the +Configuration Reference for more information on contexts and web +application deployment. + + +================ +Troubleshooting +================ + +There are only really 2 things likely to go wrong during the stand-alone +Tomcat install: + +(1) The most common hiccup is when another web server (or any process for that + matter) has laid claim to port 8080. This is the default HTTP port that + Tomcat attempts to bind to at startup. To change this, open the file: + + $CATALINA_HOME/conf/server.xml + + and search for '8080'. Change it to a port that isn't in use, and is + greater than 1024, as ports less than or equal to 1024 require superuser + access to bind under UNIX. + + Restart Tomcat and you're in business. Be sure that you replace the "8080" + in the URL you're using to access Tomcat. For example, if you change the + port to 1977, you would request the URL http://localhost:1977/ in your + browser. + +(2) The 'localhost' machine isn't found. This could happen if you're behind a + proxy. If that's the case, make sure the proxy configuration for your + browser knows that you shouldn't be going through the proxy to access the + "localhost". + + In Firefox, this is under Tools/Preferences -> Advanced/Network -> + Connection -> Settings..., and in Internet Explorer it is Tools -> + Internet Options -> Connections -> LAN Settings. + + +==================== +Optional Components +==================== + +The following optional components may be included with the Apache Tomcat binary +distribution. If they are not included, you can install them separately. + + 1. Apache Tomcat Native library + + 2. Apache Commons Daemon service launcher + +Both of them are implemented in C language and as such have to be compiled +into binary code. The binary code will be specific for a platform and CPU +architecture and it must match the Java Runtime Environment executables +that will be used to launch Tomcat. + +The Windows-specific binary distributions of Apache Tomcat include binary +files for these components. On other platforms you would have to look for +binary versions elsewhere or compile them yourself. + +If you are new to Tomcat, do not bother with these components to start with. +If you do use them, do not forget to read their documentation. + + +Apache Tomcat Native library +----------------------------- + +It is a library that allows to use the "Apr" variant of HTTP and AJP +protocol connectors in Apache Tomcat. It is built around OpenSSL and Apache +Portable Runtime (APR) libraries. Those are the same libraries as used by +Apache HTTPD Server project. + +This feature was especially important in the old days when Java performance +was poor. It is less important nowadays, but it is still used and respected +by many. See Tomcat documentation for more details. + +For further reading: + + - Apache Tomcat documentation + + * Documentation for APR/Native library in the Tomcat User's Guide + + https://tomcat.apache.org/tomcat-8.0-doc/apr.html + + * Documentation for the HTTP and AJP protocol connectors in the Tomcat + Configuration Reference + + https://tomcat.apache.org/tomcat-8.0-doc/config/http.html + + https://tomcat.apache.org/tomcat-8.0-doc/config/ajp.html + + - Apache Tomcat Native project home + + https://tomcat.apache.org/native-doc/ + + - Other projects + + * OpenSSL + + https://www.openssl.org/ + + * Apache Portable Runtime + + https://apr.apache.org/ + + * Apache HTTP Server + + https://httpd.apache.org/ + +To disable Apache Tomcat Native library: + + - To disable Apache Tomcat Native library when it is installed, or + - To remove the warning that is logged during Tomcat startup when the + library is not installed: + + Edit the "conf/server.xml" file and remove "AprLifecycleListener" from + it. + +The binary file of Apache Tomcat Native library is usually named + + - "tcnative-1.dll" on Windows + - "libtcnative-1.so" on *nix systems + + +Apache Commons Daemon +---------------------- + +Apache Commons Daemon project provides wrappers that can be used to +install Apache Tomcat as a service on Windows or as a daemon on *nix +systems. + +The Windows-specific implementation of Apache Commons Daemon is called +"procrun". The *nix-specific one is called "jsvc". + +For further reading: + + - Apache Commons Daemon project + + https://commons.apache.org/daemon/ + + - Apache Tomcat documentation + + * Installing Apache Tomcat + + https://tomcat.apache.org/tomcat-8.0-doc/setup.html + + * Windows service HOW-TO + + https://tomcat.apache.org/tomcat-8.0-doc/windows-service-howto.html + +The binary files of Apache Commons Daemon in Apache Tomcat distributions +for Windows are named: + + - "tomcat8.exe" + - "tomcat8w.exe" + +These files are renamed copies of "prunsrv.exe" and "prunmgr.exe" from +Apache Commons Daemon distribution. The file names have a meaning: they are +used as the service name to register the service in Windows, as well as the +key name to store distinct configuration for this installation of +"procrun". If you would like to install several instances of Tomcat 8.0 +in parallel, you have to further rename those files, using the same naming +scheme. diff --git a/test.dockerapp/tomcat/webapps/docs/WEB-INF/web.xml b/test.dockerapp/tomcat/webapps/docs/WEB-INF/web.xml new file mode 100644 index 0000000..8920ccd --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/WEB-INF/web.xml @@ -0,0 +1,29 @@ + + + + + Tomcat Documentation + + Tomcat Documentation. + + diff --git a/test.dockerapp/tomcat/webapps/docs/aio.html b/test.dockerapp/tomcat/webapps/docs/aio.html new file mode 100644 index 0000000..22ada26 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/aio.html @@ -0,0 +1,366 @@ + +Apache Tomcat 8 (8.0.53) - Advanced IO and Tomcat

Advanced IO and Tomcat

Table of Contents

Introduction

+ +

+ With usage of APR or NIO APIs as the basis of its connectors, Tomcat is + able to provide a number of extensions over the regular blocking IO + as provided with support for the Servlet API. +

+ +

+ IMPORTANT NOTE: Usage of these features requires using the APR or NIO + HTTP connectors. The classic java.io HTTP connector and the AJP connectors + do not support them. +

+ +

Comet support

+ +

+ Comet support allows a servlet to process IO asynchronously, receiving + events when data is available for reading on the connection (rather than + always using a blocking read), and writing data back on connections + asynchronously (most likely responding to some event raised from some + other source). +

+ +

CometEvent

+ +

+ Servlets which implement the org.apache.catalina.comet.CometProcessor + interface will have their event method invoked rather than the usual service + method, according to the event which occurred. The event object gives + access to the usual request and response objects, which may be used in the + usual way. The main difference is that those objects remain valid and fully + functional at any time between processing of the BEGIN event until processing + an END or ERROR event. + The following event types exist: +

+ +
    +
  • EventType.BEGIN: will be called at the beginning + of the processing of the connection. It can be used to initialize any relevant + fields using the request and response objects. Between the end of the processing + of this event, and the beginning of the processing of the end or error events, + it is possible to use the response object to write data on the open connection. + Note that the response object and dependent OutputStream and Writer are still + not synchronized, so when they are accessed by multiple threads, + synchronization is mandatory. After processing the initial event, the request + is considered to be committed.
  • +
  • EventType.READ: This indicates that input data is available, and that one read can be made + without blocking. The available and ready methods of the InputStream or + Reader may be used to determine if there is a risk of blocking: the servlet + should read while data is reported available. When encountering a read error, + the servlet should report it by propagating the exception properly. Throwing + an exception will cause the error event to be invoked, and the connection + will be closed. + Alternately, it is also possible to catch any exception, perform clean up + on any data structure the servlet may be using, and using the close method + of the event. It is not allowed to attempt reading data from the request + object outside of the execution of this method.
    + On some platforms, like Windows, a client disconnect is indicated by a READ event. + Reading from the stream may result in -1, an IOException or an EOFException. + Make sure you properly handle all these three cases. + If you don't catch the IOException, Tomcat will instantly invoke your event chain with an ERROR as + it catches the error for you, and you will be notified of the error at that time. +
  • +
  • EventType.END: End may be called to end the processing of the request. Fields that have + been initialized in the begin method should be reset. After this event has + been processed, the request and response objects, as well as all their dependent + objects will be recycled and used to process other requests. End will also be + called when data is available and the end of file is reached on the request input + (this usually indicates the client has pipelined a request).
  • +
  • EventType.ERROR: Error will be called by the container in the case where an IO exception + or a similar unrecoverable error occurs on the connection. Fields that have + been initialized in the begin method should be reset. After this event has + been processed, the request and response objects, as well as all their dependent + objects will be recycled and used to process other requests.
  • +
+ +

+ There are some event subtypes which allow finer processing of events (note: some of these + events require usage of the org.apache.catalina.valves.CometConnectionManagerValve valve): +

+ +
    +
  • EventSubType.TIMEOUT: The connection timed out (sub type of ERROR); note that this ERROR + type is not fatal, and the connection will not be closed unless the servlet uses the close + method of the event. +
  • +
  • EventSubType.CLIENT_DISCONNECT: The client connection was closed (sub type of ERROR). +
  • +
  • EventSubType.IOEXCEPTION: An IO exception occurred, such as invalid content, for example, + an invalid chunk block (sub type of ERROR). +
  • +
  • EventSubType.WEBAPP_RELOAD: The web application is being reloaded (sub type of END). +
  • +
  • EventSubType.SESSION_END: The servlet ended the session (sub type of END). +
  • +
+ +

+ As described above, the typical lifecycle of a Comet request will consist in a series of + events such as: BEGIN -> READ -> READ -> READ -> ERROR/TIMEOUT. At any time, the servlet + may end processing of the request by using the close method of the event object. +

+ +
+ +

CometFilter

+ +

+ Similar to regular filters, a filter chain is invoked when comet events are processed. + These filters should implement the CometFilter interface (which works in the same way as + the regular Filter interface), and should be declared and mapped in the deployment + descriptor in the same way as a regular filter. The filter chain when processing an event + will only include filters which match all the usual mapping rules, and also implement + the CometFiler interface. +

+ +
+ +

Example code

+ +

+ The following pseudo code servlet implements asynchronous chat functionality using the API + described above: +

+ +
public class ChatServlet
+    extends HttpServlet implements CometProcessor {
+
+    protected ArrayList<HttpServletResponse> connections =
+        new ArrayList<HttpServletResponse>();
+    protected MessageSender messageSender = null;
+
+    public void init() throws ServletException {
+        messageSender = new MessageSender();
+        Thread messageSenderThread =
+            new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() + "]");
+        messageSenderThread.setDaemon(true);
+        messageSenderThread.start();
+    }
+
+    public void destroy() {
+        connections.clear();
+        messageSender.stop();
+        messageSender = null;
+    }
+
+    /**
+     * Process the given Comet event.
+     *
+     * @param event The Comet event that will be processed
+     * @throws IOException
+     * @throws ServletException
+     */
+    public void event(CometEvent event)
+        throws IOException, ServletException {
+        HttpServletRequest request = event.getHttpServletRequest();
+        HttpServletResponse response = event.getHttpServletResponse();
+        if (event.getEventType() == CometEvent.EventType.BEGIN) {
+            log("Begin for session: " + request.getSession(true).getId());
+            PrintWriter writer = response.getWriter();
+            writer.println("<!DOCTYPE html>");
+            writer.println("<head><title>JSP Chat</title></head><body>");
+            writer.flush();
+            synchronized(connections) {
+                connections.add(response);
+            }
+        } else if (event.getEventType() == CometEvent.EventType.ERROR) {
+            log("Error for session: " + request.getSession(true).getId());
+            synchronized(connections) {
+                connections.remove(response);
+            }
+            event.close();
+        } else if (event.getEventType() == CometEvent.EventType.END) {
+            log("End for session: " + request.getSession(true).getId());
+            synchronized(connections) {
+                connections.remove(response);
+            }
+            PrintWriter writer = response.getWriter();
+            writer.println("</body></html>");
+            event.close();
+        } else if (event.getEventType() == CometEvent.EventType.READ) {
+            InputStream is = request.getInputStream();
+            byte[] buf = new byte[512];
+            do {
+                int n = is.read(buf); //can throw an IOException
+                if (n > 0) {
+                    log("Read " + n + " bytes: " + new String(buf, 0, n)
+                            + " for session: " + request.getSession(true).getId());
+                } else if (n < 0) {
+                    error(event, request, response);
+                    return;
+                }
+            } while (is.available() > 0);
+        }
+    }
+
+    public class MessageSender implements Runnable {
+
+        protected boolean running = true;
+        protected ArrayList<String> messages = new ArrayList<String>();
+
+        public MessageSender() {
+        }
+
+        public void stop() {
+            running = false;
+        }
+
+        /**
+         * Add message for sending.
+         */
+        public void send(String user, String message) {
+            synchronized (messages) {
+                messages.add("[" + user + "]: " + message);
+                messages.notify();
+            }
+        }
+
+        public void run() {
+
+            while (running) {
+
+                if (messages.size() == 0) {
+                    try {
+                        synchronized (messages) {
+                            messages.wait();
+                        }
+                    } catch (InterruptedException e) {
+                        // Ignore
+                    }
+                }
+
+                synchronized (connections) {
+                    String[] pendingMessages = null;
+                    synchronized (messages) {
+                        pendingMessages = messages.toArray(new String[0]);
+                        messages.clear();
+                    }
+                    // Send any pending message on all the open connections
+                    for (int i = 0; i < connections.size(); i++) {
+                        try {
+                            PrintWriter writer = connections.get(i).getWriter();
+                            for (int j = 0; j < pendingMessages.length; j++) {
+                                writer.println(pendingMessages[j] + "<br>");
+                            }
+                            writer.flush();
+                        } catch (IOException e) {
+                            log("IOExeption sending message", e);
+                        }
+                    }
+                }
+
+            }
+
+        }
+
+    }
+
+}
+ +
+

Comet timeouts

+

If you are using the NIO connector, you can set individual timeouts for your different comet connections. + To set a timeout, simply set a request attribute like the following code shows:

+
CometEvent event.... event.setTimeout(30*1000);
+

or

+
event.getHttpServletRequest().setAttribute("org.apache.tomcat.comet.timeout", new Integer(30 * 1000));
+

+ This sets the timeout to 30 seconds. + Important note: in order to set this timeout, it has to be done on the BEGIN event. + The default value is soTimeout +

+

If you are using the APR connector, all Comet connections will have the same timeout value. It is soTimeout*50 +

+
+ +

Asynchronous writes

+ +

+ When APR or NIO is enabled, Tomcat supports using sendfile to send large static files. + These writes, as soon as the system load increases, will be performed + asynchronously in the most efficient way. Instead of sending a large response using + blocking writes, it is possible to write content to a static file, and write it + using a sendfile code. A caching valve could take advantage of this to cache the + response data in a file rather than store it in memory. Sendfile support is + available if the request attribute org.apache.tomcat.sendfile.support + is set to Boolean.TRUE. +

+ +

+ Any servlet can instruct Tomcat to perform a sendfile call by setting the appropriate + request attributes. It is also necessary to correctly set the content length + for the response. When using sendfile, it is best to ensure that neither the + request or response have been wrapped, since as the response body will be sent later + by the connector itself, it cannot be filtered. Other than setting the 3 needed + request attributes, the servlet should not send any response data, but it may use + any method which will result in modifying the response header (like setting cookies). +

+ +
    +
  • org.apache.tomcat.sendfile.filename: Canonical filename of the file which will be sent as + a String
  • +
  • org.apache.tomcat.sendfile.start: Start offset as a Long
  • +
  • org.apache.tomcat.sendfile.end: End offset as a Long
  • +
+

+ In addition to setting these parameters it is necessary to set the content-length header. + Tomcat will not do that for you, since you may have already written data to the output stream. +

+ +

+ Note that the use of sendfile will disable any compression that Tomcat may + otherwise have performed on the response. +

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/api/index.html b/test.dockerapp/tomcat/webapps/docs/api/index.html new file mode 100644 index 0000000..e3b0510 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/api/index.html @@ -0,0 +1,34 @@ + + + + + + API docs + + + + +Tomcat's internal javadoc is not installed by default. Download and install +the "fulldocs" package to get it. + +You can also access the javadoc online in the Tomcat + +documentation bundle. + + + diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/build.xml.txt b/test.dockerapp/tomcat/webapps/docs/appdev/build.xml.txt new file mode 100644 index 0000000..51d8350 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/build.xml.txt @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/deployment.html b/test.dockerapp/tomcat/webapps/docs/appdev/deployment.html new file mode 100644 index 0000000..fc2a77b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/deployment.html @@ -0,0 +1,244 @@ + +Application Developer's Guide (8.0.53) - Deployment

Deployment

Table of Contents

Background

+ +

Before describing how to organize your source code directories, +it is useful to examine the runtime organization of a web application. +Prior to the Servlet API Specification, version 2.2, there was little +consistency between server platforms. However, servers that conform +to the 2.2 (or later) specification are required to accept a +Web Application Archive in a standard format, which is discussed +further below.

+ +

A web application is defined as a hierarchy of directories and files +in a standard layout. Such a hierarchy can be accessed in its "unpacked" +form, where each directory and file exists in the filesystem separately, +or in a "packed" form known as a Web ARchive, or WAR file. The former format +is more useful during development, while the latter is used when you +distribute your application to be installed.

+ +

The top-level directory of your web application hierarchy is also the +document root of your application. Here, you will place the HTML +files and JSP pages that comprise your application's user interface. When the +system administrator deploys your application into a particular server, he +or she assigns a context path to your application (a later section +of this manual describes deployment on Tomcat). Thus, if the +system administrator assigns your application to the context path +/catalog, then a request URI referring to +/catalog/index.html will retrieve the index.html +file from your document root.

+ +

Standard Directory Layout

+ +

To facilitate creation of a Web Application Archive file in the required +format, it is convenient to arrange the "executable" files of your web +application (that is, the files that Tomcat actually uses when executing +your app) in the same organization as required by the WAR format itself. +To do this, you will end up with the following contents in your +application's "document root" directory:

+
    +
  • *.html, *.jsp, etc. - The HTML and JSP pages, along + with other files that must be visible to the client browser (such as + JavaScript, stylesheet files, and images) for your application. + In larger applications you may choose to divide these files into + a subdirectory hierarchy, but for smaller apps, it is generally + much simpler to maintain only a single directory for these files. +

  • +
  • /WEB-INF/web.xml - The Web Application Deployment + Descriptor for your application. This is an XML file describing + the servlets and other components that make up your application, + along with any initialization parameters and container-managed + security constraints that you want the server to enforce for you. + This file is discussed in more detail in the following subsection. +

  • +
  • /WEB-INF/classes/ - This directory contains any Java + class files (and associated resources) required for your application, + including both servlet and non-servlet classes, that are not combined + into JAR files. If your classes are organized into Java packages, + you must reflect this in the directory hierarchy under + /WEB-INF/classes/. For example, a Java class named + com.mycompany.mypackage.MyServlet + would need to be stored in a file named + /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class. +

  • +
  • /WEB-INF/lib/ - This directory contains JAR files that + contain Java class files (and associated resources) required for your + application, such as third party class libraries or JDBC drivers.
  • +
+ +

When you install an application into Tomcat (or any other 2.2 or later +Servlet container), the classes in the WEB-INF/classes/ +directory, as well as all classes in JAR files found in the +WEB-INF/lib/ directory, are made visible to other classes +within your particular web application. Thus, if +you include all of the required library classes in one of these places (be +sure to check licenses for redistribution rights for any third party libraries +you utilize), you will simplify the installation of your web application -- +no adjustment to the system class path (or installation of global library +files in your server) will be necessary.

+ +

Much of this information was extracted from Chapter 9 of the Servlet +API Specification, version 2.3, which you should consult for more details.

+ +

Shared Library Files

+ +

Like most servlet containers, Tomcat also supports mechanisms to install +library JAR files (or unpacked classes) once, and make them visible to all +installed web applications (without having to be included inside the web +application itself). The details of how Tomcat locates and shares such +classes are described in the +Class Loader HOW-TO documentation. +The location commonly used within a Tomcat installation for shared code is +$CATALINA_HOME/lib. JAR files placed here are visible both to +web applications and internal Tomcat code. This is a good place to put JDBC +drivers that are required for both your application or internal Tomcat use +(such as for a JDBCRealm).

+ +

Out of the box, a standard Tomcat installation includes a variety +of pre-installed shared library files, including:

+
    +
  • The Servlet 3.1 and JSP 2.3 APIs that are fundamental + to writing servlets and JavaServer Pages.

  • +
+ +

Web Application Deployment Descriptor

+ +

As mentioned above, the /WEB-INF/web.xml file contains the +Web Application Deployment Descriptor for your application. As the filename +extension implies, this file is an XML document, and defines everything about +your application that a server needs to know (except the context path, +which is assigned by the system administrator when the application is +deployed).

+ +

The complete syntax and semantics for the deployment descriptor is defined +in Chapter 13 of the Servlet API Specification, version 2.3. Over time, it +is expected that development tools will be provided that create and edit the +deployment descriptor for you. In the meantime, to provide a starting point, +a basic web.xml file +is provided. This file includes comments that describe the purpose of each +included element.

+ +

NOTE - The Servlet Specification includes a Document +Type Descriptor (DTD) for the web application deployment descriptor, and +Tomcat enforces the rules defined here when processing your application's +/WEB-INF/web.xml file. In particular, you must +enter your descriptor elements (such as <filter>, +<servlet>, and <servlet-mapping> in +the order defined by the DTD (see Section 13.3).

+ +

Tomcat Context Descriptor

+ +

A /META-INF/context.xml file can be used to define Tomcat specific +configuration options, such as an access log, data sources, session manager +configuration and more. This XML file must contain one Context element, which +will be considered as if it was the child of the Host element corresponding +to the Host to which the web application is being deployed. The +Tomcat configuration documentation contains +information on the Context element.

+ +

Deployment With Tomcat

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

In order to be executed, a web application must be deployed on +a servlet container. This is true even during development. +We will describe using Tomcat to provide the execution environment. +A web application can be deployed in Tomcat by one of the following +approaches:

+
    +
  • Copy unpacked directory hierarchy into a subdirectory in directory + $CATALINA_BASE/webapps/. Tomcat will assign a + context path to your application based on the subdirectory name you + choose. We will use this technique in the build.xml + file that we construct, because it is the quickest and easiest approach + during development. Be sure to restart Tomcat after installing or + updating your application. +

  • +
  • Copy the web application archive file into directory + $CATALINA_BASE/webapps/. When Tomcat is started, it will + automatically expand the web application archive file into its unpacked + form, and execute the application that way. This approach would typically + be used to install an additional application, provided by a third party + vendor or by your internal development staff, into an existing + Tomcat installation. NOTE - If you use this approach, + and wish to update your application later, you must both replace the + web application archive file AND delete the expanded + directory that Tomcat created, and then restart Tomcat, in order to reflect + your changes. +

  • +
  • Use the Tomcat "Manager" web application to deploy and undeploy + web applications. Tomcat includes a web application, deployed + by default on context path /manager, that allows you to + deploy and undeploy applications on a running Tomcat server without + restarting it. See Manager App HOW-TO + for more information on using the Manager web application.

  • +
  • Use "Manager" Ant Tasks In Your Build Script. Tomcat + includes a set of custom task definitions for the Ant + build tool that allow you to automate the execution of commands to the + "Manager" web application. These tasks are used in the Tomcat deployer. +

  • +
  • Use the Tomcat Deployer. Tomcat includes a packaged tool + bundling the Ant tasks, and can be used to automatically precompile JSPs + which are part of the web application before deployment to the server. +

  • +
+ +

Deploying your app on other servlet containers will be specific to each +container, but all containers compatible with the Servlet API Specification +(version 2.2 or later) are required to accept a web application archive file. +Note that other containers are NOT required to accept an +unpacked directory structure (as Tomcat does), or to provide mechanisms for +shared library files, but these features are commonly available.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/index.html b/test.dockerapp/tomcat/webapps/docs/appdev/index.html new file mode 100644 index 0000000..32096eb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/index.html @@ -0,0 +1,87 @@ + +Application Developer's Guide (8.0.53) - Table of Contents

Table of Contents

Preface

+ +

This manual includes contributions from many members of the Tomcat Project +developer community. The following authors have provided significant content: +

+ + +

Table of Contents

+ +

The information presented is divided into the following sections:

+
    +
  • Introduction - + Briefly describes the information covered here, with + links and references to other sources of information.
  • +
  • Installation - + Covers acquiring and installing the required software + components to use Tomcat for web application development.
  • +
  • Deployment Organization - + Discusses the standard directory layout for a web application + (defined in the Servlet API Specification), the Web Application + Deployment Descriptor, and options for integration with Tomcat + in your development environment.
  • +
  • Source Organization - + Describes a useful approach to organizing the source code + directories for your project, and introduces the + build.xml used by Ant to manage compilation.
  • +
  • Development Processes - + Provides brief descriptions of typical development processes + utilizing the recommended deployment and source organizations.
  • +
  • Example Application - + This directory contains a very simple, but functionally complete, + "Hello, World" application built according to the principles + described in this manual. You can use this application to + practice using the described techniques.
  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/installation.html b/test.dockerapp/tomcat/webapps/docs/appdev/installation.html new file mode 100644 index 0000000..9d74dde --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/installation.html @@ -0,0 +1,115 @@ + +Application Developer's Guide (8.0.53) - Installation

Installation

Installation

+ +

In order to use Tomcat for developing web applications, you must first +install it (and the software it depends on). The required steps are outlined +in the following subsections.

+ +

JDK

+ +

Tomcat 8.0 was designed to run on Java SE 7. +

+ +

Compatible JDKs for many platforms (or links to where they can be found) +are available at +http://www.oracle.com/technetwork/java/javase/downloads/index.html.

+ +
+ +

Tomcat

+ +

Binary downloads of the Tomcat server are available from +https://tomcat.apache.org/. +This manual assumes you are using the most recent release +of Tomcat 8. Detailed instructions for downloading and installing +Tomcat are available here.

+ +

In the remainder of this manual, example shell scripts assume that you have +set an environment variable CATALINA_HOME that contains the +pathname to the directory in which Tomcat has been installed. Optionally, if +Tomcat has been configured for multiple instances, each instance will have its +own CATALINA_BASE configured.

+ +
+ + +

Ant

+ +

Binary downloads of the Ant build tool are available from +https://ant.apache.org/. +This manual assumes you are using Ant 1.8 or later. The instructions may +also be compatible with other versions, but this has not been tested.

+ +

Download and install Ant. +Then, add the bin directory of the Ant distribution to your +PATH environment variable, following the standard practices for +your operating system platform. Once you have done this, you will be able to +execute the ant shell command directly.

+ +
+ + +

CVS

+ +

Besides the required tools described above, you are strongly encouraged +to download and install a source code control system, such as the +Concurrent Version System (CVS), to maintain historical +versions of the source files that make up your web application. Besides +the server, you will also need appropriate client +tools to check out source code files, and check in modified versions.

+ +

Detailed instructions for installing and using source code control +applications is beyond the scope of this manual. However, CVS server and +client tools for many platforms (along with documentation) can be downloaded +from http://www.cvshome.org/.

+ +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/introduction.html b/test.dockerapp/tomcat/webapps/docs/appdev/introduction.html new file mode 100644 index 0000000..225c2dc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/introduction.html @@ -0,0 +1,100 @@ + +Application Developer's Guide (8.0.53) - Introduction

Introduction

Overview

+ +

Congratulations! You've decided to (or been told to) learn how to +build web applications using servlets and JSP pages, and picked the +Tomcat server to use for your learning and development. But now what +do you do?

+ +

This manual is a primer covering the basic steps of using Tomcat to +set up a development environment, organize your source code, and then +build and test your application. It does not discuss architectures or +recommended coding practices for web application development, +or provide in depth instructions on operating the development +tools that are discussed. References to sources of additional information +are included in the following subsections.

+ +

The discussion in this manual is aimed at developers who will be using +a text editor along with command line tools to develop and debug their +applications. As such, the recommendations are fairly generic – but you +should easily be able to apply them in either a Windows-based or Unix-based +development environment. If you are utilizing an Integrated Development +Environment (IDE) tool, you will need to adapt the advice given here to +the details of your particular environment.

+ +
+ +

The following links provide access to selected sources of online +information, documentation, and software that is useful in developing +web applications with Tomcat.

+
    +
  • https://jcp.org/aboutJava/communityprocess/mrel/jsr245/index2.html - + JavaServer Pages (JSP) Specification, Version 2.3. Describes + the programming environment provided by standard implementations + of the JavaServer Pages (JSP) technology. In conjunction with + the Servlet API Specification (see below), this document describes + what a portable API page is allowed to contain. Specific + information on scripting (Chapter 9), tag extensions (Chapter 7), + and packaging JSP pages (Appendix A) is useful. The Javadoc + API Documentation is included in the specification, and with the + Tomcat download.

  • +
  • http://jcp.org/aboutJava/communityprocess/final/jsr340/index.html - + Servlet API Specification, Version 3.1. Describes the + programming environment that must be provided by all servlet + containers conforming to this specification. In particular, you + will need this document to understand the web application + directory structure and deployment file (Chapter 10), methods of + mapping request URIs to servlets (Chapter 12), container managed + security (Chapter 13), and the syntax of the web.xml + Web Application Deployment Descriptor (Chapter 14). The Javadoc + API Documentation is included in the specification, and with the + Tomcat download.

  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/processes.html b/test.dockerapp/tomcat/webapps/docs/appdev/processes.html new file mode 100644 index 0000000..ea959e3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/processes.html @@ -0,0 +1,315 @@ + +Application Developer's Guide (8.0.53) - Development Processes

Development Processes

Table of Contents

Development Processes

+ +

Although application development can take many forms, this manual proposes +a fairly generic process for creating web applications using Tomcat. The +following sections highlight the commands and tasks that you, as the developer +of the code, will perform. The same basic approach works when you have +multiple programmers involved, as long as you have an appropriate source code +control system and internal team rules about who is working on what parts +of the application at any given time.

+ +

The task descriptions below assume that you will be using CVS for source +code control, and that you have already configured access to the appropriate +CVS repository. Instructions for doing this are beyond the scope of this +manual. If you are using a different source code control environment, you +will need to figure out the corresponding commands for your system.

+ + +

One-Time Setup of Ant and Tomcat for Development

+ +

In order to take advantage of the special Ant tasks that interact with the +Manager web application, you need to perform the following tasks +once (no matter how many web applications you plan to develop).

+
    +
  • Configure the Ant custom tasks. The implementation code for the + Ant custom tasks is in a JAR file named + $CATALINA_HOME/lib/catalina-ant.jar, which must be + copied in to the lib directory of your Ant installation. +

  • +
  • Define one or more Tomcat users. The Manager web + application runs under a security constraint that requires a user to be + logged in, and have the security role manager-script assigned + to him or her. How such users are defined depends on which Realm you have + configured in Tomcat's conf/server.xml file -- see the + Realm Configuration HOW-TO for more + information. You may define any number of users (with any username + and password that you like) with the manager-script role. +

  • +
+ +
+ + +

Create Project Source Code Directory

+ +

The first step is to create a new project source directory, and customize +the build.xml and build.properties files you will +be using. The directory structure is described in the +previous section, or you can use the +sample application as a starting point.

+ +

Create your project source directory, and define it within your CVS +repository. This might be done by a series of commands like this, where +{project} is the name under which your project should be +stored in the CVS repository, and {username} is your login username:

+
cd {my home directory}
+mkdir myapp <-- Assumed "project source directory"
+cd myapp
+mkdir docs
+mkdir src
+mkdir web
+mkdir web/WEB-INF
+cvs import -m "Initial Project Creation" {project} \
+    {username} start
+ +

Now, to verify that it was created correctly in CVS, we will perform a +checkout of the new project:

+
cd ..
+mv myapp myapp.bu
+cvs checkout {project}
+ +

Next, you will need to create and check in an initial version of the +build.xml script to be used for development. For getting +started quickly and easily, base your build.xml on the +basic build.xml file, included with this manual, +or code it from scratch.

+
cd {my home directory}
+cd myapp
+emacs build.xml     <-- if you want a real editor :-)
+cvs add build.xml
+cvs commit
+ +

Until you perform the CVS commit, your changes are local to your own +development directory. Committing makes those changes visible to other +developers on your team that are sharing the same CVS repository.

+ +

The next step is to customize the Ant properties that are +named in the build.xml script. This is done by creating a +file named build.properties in your project's top-level +directory. The supported properties are listed in the comments inside +the sample build.xml script. At a minimum, you will generally +need to define the catalina.home property defining where +Tomcat is installed, and the manager application username and password. +You might end up with something like this:

+
# Context path to install this application on
+app.path=/hello
+
+# Tomcat installation directory
+catalina.home=/usr/local/apache-tomcat-<version-major-minor/>
+
+# Manager webapp username and password
+manager.username=myusername
+manager.password=mypassword
+ +

In general, you will not want to check the +build.properties file in to the CVS repository, because it +is unique to each developer's environment.

+ +

Now, create the initial version of the web application deployment +descriptor. You can base web.xml on the +basic web.xml file, or code it from scratch.

+
cd {my home directory}
+cd myapp/web/WEB-INF
+emacs web.xml
+cvs add web.xml
+cvs commit
+ +Note that this is only an example web.xml file. The full definition +of the deployment descriptor file is in the +Servlet Specification. + +
+ + +

Edit Source Code and Pages

+ +

The edit/build/test tasks will generally be your most common activities +during development and maintenance. The following general principles apply. +As described in Source Organization, newly created +source files should be located in the appropriate subdirectory, under your +project source directory.

+ +

Whenever you wish to refresh your development directory to reflect the +work performed by other developers, you will ask CVS to do it for you:

+
cd {my home directory}
+cd myapp
+cvs update -dP
+ +

To create a new file, go to the appropriate directory, create the file, +and register it with CVS. When you are satisfied with it's contents (after +building and testing is successful), commit the new file to the repository. +For example, to create a new JSP page:

+
cd {my home directory}
+cd myapp/web        <-- Ultimate destination is document root
+emacs mypage.jsp
+cvs add mypage.jsp
+... build and test the application ...
+cvs commit
+ +

Java source code that is defined in packages must be organized in a +directory hierarchy (under the src/ subdirectory) that +matches the package names. For example, a Java class named +com.mycompany.mypackage.MyClass.java should be stored in file +src/com/mycompany/mypackage/MyClass.java. +Whenever you create a new subdirectory, don't forget to +register it with CVS.

+ +

To edit an existing source file, you will generally just start editing +and testing, then commit the changed file when everything works. Although +CVS can be configured to required you to "check out" or "lock" a file you +are going to be modifying, this is generally not used.

+ +
+ + +

Build the Web Application

+ +

When you are ready to compile the application, issue the following +commands (generally, you will want a shell window open that is set to +the project source directory, so that only the last command is needed):

+
cd {my home directory}
+cd myapp        <-- Normally leave a window open here
+ant
+ +

The Ant tool will be execute the default "compile" target in your +build.xml file, which will compile any new or updated Java +code. If this is the first time you compile after a "build clean", +it will cause everything to be recompiled.

+ +

To force the recompilation of your entire application, do this instead:

+
cd {my home directory}
+cd myapp
+ant all
+ +

This is a very good habit immediately before checking in changes, to +make sure that you have not introduced any subtle problems that Javac's +conditional checking did not catch.

+ +
+ + +

Test Your Web Application

+ +

To test your application, you will want to install it under Tomcat. The +quickest way to do that is to use the custom Ant tasks that are included in +the sample build.xml script. Using these commands might follow +a pattern like this:

+
    +
  • Start Tomcat if needed. If Tomcat is not already running, + you will need to start it in the usual way. +

  • +
  • Compile your application. Use the ant compile + command (or just ant, since this is the default). Make + sure that there are no compilation errors. +

  • +
  • Install the application. Use the ant install + command. This tells Tomcat to immediately start running your app on + the context path defined in the app.path build property. + Tomcat does NOT have to be restarted for this to + take effect. +

  • +
  • Test the application. Using your browser or other testing + tools, test the functionality of your application. +

  • +
  • Modify and rebuild as needed. As you discover that changes + are required, make those changes in the original source + files, not in the output build directory, and re-issue the + ant compile command. This ensures that your changes will + be available to be saved (via cvs commit) later on -- + the output build directory is deleted and recreated as necessary. +

  • +
  • Reload the application. Tomcat will recognize changes in + JSP pages automatically, but it will continue to use the old versions + of any servlet or JavaBean classes until the application is reloaded. + You can trigger this by executing the ant reload command. +

  • +
  • Remove the application when you are done. When you are through + working on this application, you can remove it from live execution by + running the ant remove command. +

  • +
+ +

Do not forget to commit your changes to the source code repository when +you have completed your testing!

+ +
+ + +

Creating a Release

+ +

When you are through adding new functionality, and you've tested everything +(you DO test, don't you :-), it is time to create the distributable version +of your web application that can be deployed on the production server. The +following general steps are required:

+
    +
  • Issue the command ant all from the project source + directory, to rebuild everything from scratch one last time. +

  • +
  • Use the cvs tag command to create an identifier for + all of the source files utilized to create this release. This allows + you to reliably reconstruct a release (from sources) at a later + time. +

  • +
  • Issue the command ant dist to create a distributable + web application archive (WAR) file, as well as a JAR file containing + the corresponding source code. +

  • +
  • Package the contents of the dist directory using the + tar or zip utility, according to + the standard release procedures used by your organization. +

  • +
+ +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/build.xml b/test.dockerapp/tomcat/webapps/docs/appdev/sample/build.xml new file mode 100644 index 0000000..51d8350 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/sample/build.xml @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/docs/README.txt b/test.dockerapp/tomcat/webapps/docs/appdev/sample/docs/README.txt new file mode 100644 index 0000000..f146b0e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/sample/docs/README.txt @@ -0,0 +1,17 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +This is a dummy README file for the sample +web application. diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/index.html b/test.dockerapp/tomcat/webapps/docs/appdev/sample/index.html new file mode 100644 index 0000000..589bd71 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/sample/index.html @@ -0,0 +1,55 @@ + + + + + + +Sample Application + + +

Sample Application

+

+ The example app has been packaged as a war file and can be downloaded + here (Note: make sure your browser doesn't + change file extension or append a new one). +

+

+ The easiest way to run this application is simply to move the war file + to your CATALINA_BASE/webapps directory. A default Tomcat install + will automatically expand and deploy the application for you. You can + view it with the following URL (assuming that you're running tomcat on + port 8080 which is the default): +
+ http://localhost:8080/sample +

+

+ If you just want to browse the contents, you can unpack the war file + with the jar command. +

+
+        jar -xvf sample.war
+      
+

+ Note: CATALINA_BASE is usually the directory in which you + unpacked the Tomcat distribution. For more information on + CATALINA_HOME, CATALINA_BASE and the difference between + them see RUNNING.txt in the directory you unpacked your Tomcat + distribution. +

+ + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/sample.war b/test.dockerapp/tomcat/webapps/docs/appdev/sample/sample.war new file mode 100644 index 0000000000000000000000000000000000000000..0a127e6bd1f6991c32f591e577b42a50210c60f7 GIT binary patch literal 4606 zcmaKv2{@Ep8^@nnjKR!Awi4pCGj_>ZgOFupmy9ftrIBSOCQFRTPO_vdq3lVrB(i7A zzEqTK*(+X@-lXIky{~wEeczeud7g94b^q`CKj+MI&iNVYL7?=&R?~|7A^)@U&y5a% z0$5E`HE|sSEy*7p0ATn}C>+qFhEA@7>&{X`U8xrf_4*ZxRWs1h(ljxZz-oQMc6I9O ziA(e&^~6Pcx_ZlurC!KR%y@Na?Ds^U)bBZI21J4cx>xltSEWT6GwT_f5O0gBy~ln= zOd`982?%{wxnR9dEdH_yQ6HnkqV$XjQLHMT;y=q>t|C?a@&f<{lz&@?Q~g+Is{eGp z?HT}1?TKRC6?G18M<6&7B>#6b$8VzDE_>LWyI|+!xJ$R!3u2cJ?_&RdB5A3SE^gFp zJ2v1yO%LCT6XAsbz%v>E5ZIM&+w_i&la6@2yTs4$V@%%|GpjMGLdXc-NZ1PM0SUxX zI%!=R@rO@DxVp{_vt#&pY0FWE!O;lyul#}2QEbQ7KvxnSdly6#+2w91-Bx_AI!bsV zYf~Ta18lp$@E~U!RJ)E{{(B^MGBe=QBM$d#Pwl=qG%A6*gG^ntwXGW8iou0Ah zQl^fzA=>a91eY#ZqVm~J6M@j4{*pXI!9h!AM1W(lfcbEDBz$Nz@|6Aqbm4=|7f97w zgJ+4ZB&MdfUIa0Z!s3x957|SOI>8ziSP6K`vP1dzfqdb@!PDcTcQF-z81qyG-2ljZmQSQ^@>w**Ekh%-L9eeReHIFMsbcj z0*gwn>b?h0)c)au&MrCmA_X62CcWemA)|G@2GuhOHIP{qE-4_$Z^$K;l7eQ?9i)7# zJMG3CVwNgTOL?zaWsOa9&4}0}4vw6kV7Q5^pWnQviE`(SkZgGZ*#%3 z;Uu#HiyXk%-wS-XN(taDOad{?8lup+7PP`0aaXcXO$Kj&0zN=-`^&tXd zew-3N#!aO;qpzmKi3^-@4G`n8=Se^L#>eWCAGSZ}Wp~<_7n(9Ih&HXZA2PukftfmF zO!0R%)kAIbFZ(i3QmVmM^PC+M938490>IyFD^4+cANu$QjIOK%66z6(ri7GDYc}G; z@sX8_E4Vh4lCo4Cg{7(E#DfofPlUW&C?mG9jnR!~DV7vk1h?F)$6<;N%MTkz(nqgQ zv=OKSD!P?cUu8K3YG`~x{b3@AOw1!CQvws8upRizd`?;`*GQXnmo2L7w4i_VWxOq@ zw=hDb_5jHD|3gf@6J1s^?%xg(o+Ae&n$e*&}czY1hPsh69?? zIQb*j0%^Bjb@!Ge$I)JbxCLQfCeby0vGuAXmQd z+IzjCti5Q-Vl8mXyeDdYTk6A{|Er~aYn@FSrfjDpO%KvPedd<E`FP6H z!^hm6NL+R4rK~etIqW}w>0xr#pVG+9#S;r zhV#c^frsvoMjC@J;OjK#y?O> zSP^Z(ySns&R^V}PoSJM(zjG<)cNb29rp5alD$RmtbkayTuktJB zc+8CV>At5mFN@1l884cmw~)p~b?92YQ;9m-kMJs_?^9-;!)gx}%>MZ@n@@iO*x zp=U$b`br69;h;m*Py+Y)@O2b}6MJ`=v*@Ww8WdO3XY~z-jj{TF4@3Sp*v(w(UT}wc zF;R!%pG|}4?sm?ODBj*};bm^wc*;E)8UJQuA$YZt{MGQab>E-nwn&0HB-8?K*|E3N~fe zeoPS1TF&YD1i||X7C<8+DRcmgj*f;Q zB{h|Xh7RVc3XXSAU8NSM3|g9I}(L^ znfT!wkR%mr86LiU5sa~>C1Q-3li&+rFb_{9Jz0%MW|P!NKMR8d@qWl$q{m<5$f$e%h8X<{R0b>xmZX z@!3+nc6N_3lU2NWSWZ{YS;kmUFdv=j2cSq-cnP6={lbNlM?hApm+uKzd*^bL=Gg1_ z65&pw0BSDy65PAyznD+1!Y#5IWup9exA5$>^{WPD=5Qg84Nk8uODsm zDW8jDmPLrmL4N;7!dKW@7@Xm@Cy(4;PNQtrn~1|)yf`+{NZ5EVL|8V?_l-XD^@H`v zrnacF{Ur^-oRiv=z&9n$?e<32NgVdV>*76aWXBs6 zrY_uwi^u@CR(_oYh~|pOBOuFWV@xR*A%a0f-wAAtK45|gGvj_@d;Q@e*}+F=)P&{a z5}60e0O``9q`8}46^KG1Fs7Q&#QrotUA!VRg_raN#0{#1=iLqW%E#QkRC+zgh1;4P z87-++(3NphN@OsIIXW{W%3bCIdNWLe_zveFsUy}7{`9$mA9hpg>%!ySr|*DpP7#;; z#134LcCMKh{h!syTWzC;WJF^MQ=L(tVLroCMS&XNXkTVAr<$E9vma~x9mwYJuzLaM zxU!V*tpAN7CY#7*v!)((_L63F`Qz>e_Cuax}PK&YObfpwF+(dGtTX~b~{G;uoUMokBxNaUQdTEX9_o@FQ zX2uY7bq+0g&93<|2{Ki})3GU*X=`lB4bo>;tbsUjww`tVvaDfJoXCO`_6a$*K6r%a z=FaN3QJuPvRi*VZtXQZ|cmBnR`#>9V%&!Tg@m)-!!n^kFQP|Ufbe3sFi*`}}NXe5; zf3=UbK)RLSZzzKkv(P#^m?Y^NEd!qyLx+yYJUWemf4TFUR834qqmVNWV9X=4ihsDm z=*NtFmPeVba<>w)wKisa8heO86h6;9oNU}zS7r1kw2Kn*>Z0ATq!T?Vwh=rG>zZ%| z`HOTN8syS=bp@96PV!o^sf9dyv|z)Z2fR8DO-8O390-1>kGmI)U?j@(f+y??CT^un zs2yG}xoU~eLZ)P9mg*W9^@p8@V>)3IbXfiwTAgsSu$r|N!LH@V9#IW0?qyb7e?*KM zln)s*TWxV)GIkn1_1ch>pw9785CP@i|KvK4@<0SEGMazmEK?AbP?Z0@sEc?JNNBS~eeQ5dW%aPau`~mCQvu12q_DyndldpU0YhIS#c~19<+bx%9RJzKt2BDJ$ zqOyhuXKoC8_=KK!eqFL)kfiQ^Ek4(%C^SdoHS1%|(m0|ZcMOE&;zJX29%BRJe(9iW zn33tIHS>IILn!qwi}H|rlFB?gI(UZ3&Kxpt*$~t#Gn+~q)rJB?6d$kg2--S4ut;Zj zVN%+Uhjbo14U_E`D66!1#4KN*16F*}C&#~J>Flbr_}#Zf&qJ<&3HxqQ+k@21r<87V zQAI`k#oNF9e#lsu=gJdGlz0l|51%t&zB_Wz03C)*yG$O`56XBYp+p;hOt*_e)o<{< zf%I)H#WlZ|X9n05BI9AA5c7xQtnx`U8_NWv`UM-4Kr@&3iy5!({w1s(_Lg2O!KK)kJooBE2 zE$ZFLqrEH7-weFtf3I?jf_IdjROK%w-WL6yinnFi + */ + +public final class Hello extends HttpServlet { + + private static final long serialVersionUID = 1L; + + /** + * Respond to a GET request for the content produced by + * this servlet. + * + * @param request The servlet request we are processing + * @param response The servlet response we are producing + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + @Override + public void doGet(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException { + + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + try (PrintWriter writer = response.getWriter()) { + + writer.println(""); + writer.println(""); + writer.println(""); + writer.println("Sample Application Servlet Page"); + writer.println(""); + writer.println(""); + + + writer.println("
"); + writer.println("\"\""); + writer.println("
"); + writer.println("

Sample Application Servlet

"); + writer.println("

"); + writer.println("This is the output of a servlet that is part of"); + writer.println("the Hello, World application."); + writer.println("

"); + + writer.println(""); + writer.println(""); + } + } + + +} diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/WEB-INF/web.xml b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/WEB-INF/web.xml new file mode 100644 index 0000000..cbcba17 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/WEB-INF/web.xml @@ -0,0 +1,40 @@ + + + + + Hello, World Application + + This is a simple web application with a source code organization + based on the recommendations of the Application Developer's Guide. + + + + HelloServlet + mypackage.Hello + + + + HelloServlet + /hello + + + diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/hello.jsp b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/hello.jsp new file mode 100644 index 0000000..bd5680a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/hello.jsp @@ -0,0 +1,37 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> + + + + +Sample Application JSP Page + + + +
+ +
+

Sample Application JSP Page

+This is the output of a JSP page that is part of the Hello, World +application. + + +<%= new String("Hello!") %> + + + diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/images/tomcat.gif b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/images/tomcat.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6f863e43e3924a35854c556a9c1b6d125cba GIT binary patch literal 2066 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/index.html b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/index.html new file mode 100644 index 0000000..1c6938a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/sample/web/index.html @@ -0,0 +1,39 @@ + + + + +Sample "Hello, World" Application + + + +
+ +
+

Sample "Hello, World" Application

+

This is the home page for a sample application used to illustrate the +source directory organization of a web application utilizing the principles +outlined in the Application Developer's Guide. + +

To prove that they work, you can execute either of the following links:

+ + + + diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/source.html b/test.dockerapp/tomcat/webapps/docs/appdev/source.html new file mode 100644 index 0000000..8556a1a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/source.html @@ -0,0 +1,321 @@ + +Application Developer's Guide (8.0.53) - Source Organization

Source Organization

Table of Contents

Directory Structure

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

A key recommendation of this manual is to separate the directory +hierarchy containing your source code (described in this section) from +the directory hierarchy containing your deployable application +(described in the preceding section). Maintaining this separation has +the following advantages:

+
    +
  • The contents of the source directories can be more easily administered, + moved, and backed up if the "executable" version of the application + is not intermixed. +

  • +
  • Source code control is easier to manage on directories that contain + only source files. +

  • +
  • The files that make up an installable distribution of your + application are much easier to select when the deployment + hierarchy is separate.

  • +
+ +

As we will see, the ant development tool makes the creation +and processing of such directory hierarchies nearly painless.

+ +

The actual directory and file hierarchy used to contain the source code +of an application can be pretty much anything you like. However, the +following organization has proven to be quite generally applicable, and is +expected by the example build.xml configuration file that +is discussed below. All of these components exist under a top level +project source directory for your application:

+
    +
  • docs/ - Documentation for your application, in whatever + format your development team is using.

  • +
  • src/ - Java source files that generate the servlets, + beans, and other Java classes that are unique to your application. + If your source code is organized in packages (highly + recommended), the package hierarchy should be reflected as a directory + structure underneath this directory.

  • +
  • web/ - The static content of your web site (HTML pages, + JSP pages, JavaScript files, CSS stylesheet files, and images) that will + be accessible to application clients. This directory will be the + document root of your web application, and any subdirectory + structure found here will be reflected in the request URIs required to + access those files.

  • +
  • web/WEB-INF/ - The special configuration files required + for your application, including the web application deployment descriptor + (web.xml, defined in the + Servlet Specification), + tag library descriptors for custom tag libraries + you have created, and other resource files you wish to include within + your web application. Even though this directory appears to be a + subdirectory of your document root, the Servlet Specification + prohibits serving the contents of this directory (or any file it contains) + directly to a client request. Therefore, this is a good place to store + configuration information that is sensitive (such as database connection + usernames and passwords), but is required for your application to + operate successfully.
  • +
+ +

During the development process, two additional directories will be +created on a temporary basis:

+
    +
  • build/ - When you execute a default build + (ant), this directory will contain an exact image + of the files in the web application archive for this application. + Tomcat allows you to deploy an application in an unpacked + directory like this, either by copying it to the + $CATALINA_BASE/webapps directory, or by installing + it via the "Manager" web application. The latter approach is very + useful during development, and will be illustrated below. +

  • +
  • dist/ - When you execute the ant dist + target, this directory will be created. It will create an exact image + of the binary distribution for your web application, including an license + information, documentation, and README files that you have prepared.
  • +
+ +

Note that these two directories should NOT be archived in +your source code control system, because they are deleted and recreated (from +scratch) as needed during development. For that reason, you should not edit +any source files in these directories if you want to maintain a permanent +record of the changes, because the changes will be lost the next time that a +build is performed.

+ +

External Dependencies

+ +

What do you do if your application requires JAR files (or other + resources) from external projects or packages? A common example is that + you need to include a JDBC driver in your web application, in order to + operate.

+ +

Different developers take different approaches to this problem. + Some will encourage checking a copy of the JAR files you depend on into + the source code control archives for every application that requires those + JAR files. However, this can cause significant management issues when you + use the same JAR in many applications - particular when faced with a need + to upgrade to a different version of that JAR file.

+ +

Therefore, this manual recommends that you NOT store + a copy of the packages you depend on inside the source control archives + of your applications. Instead, the external dependencies should be + integrated as part of the process of building your + application. In that way, you can always pick up the appropriate version + of the JAR files from wherever your development system administrator has + installed them, without having to worry about updating your application + every time the version of the dependent JAR file is changed.

+ +

In the example Ant build.xml file, we will demonstrate + how to define build properties that let you configure the locations + of the files to be copied, without having to modify build.xml + when these files change. The build properties used by a particular + developer can be customized on a per-application basis, or defaulted to + "standard" build properties stored in the developer's home directory.

+ +

In many cases, your development system administrator will have already + installed the required JAR files into the lib directory of Tomcat. + If this has been done, you need + to take no actions at all - the example build.xml file + automatically constructs a compile classpath that includes these files.

+ +
+ +

Source Code Control

+ +

As mentioned earlier, it is highly recommended that you place all of the +source files that comprise your application under the management of a +source code control system like the Concurrent Version System (CVS). If you +elect to do this, every directory and file in the source hierarchy should be +registered and saved -- but none of the generated files. If you register +binary format files (such as images or JAR libraries), be sure to indicate +this to your source code control system.

+ +

We recommended (in the previous section) that you should not store the +contents of the build/ and dist/ directories +created by your development process in the source code control system. An +easy way to tell CVS to ignore these directories is to create a file named +.cvsignore (note the leading period) in your top-level source +directory, with the following contents:

+
build
+dist
+build.properties
+ +

The reason for mentioning build.properties here will be +explained in the Processes section.

+ +

Detailed instructions for your source code control environment are beyond +the scope of this manual. However, the following steps are followed when +using a command-line CVS client:

+
    +
  • To refresh the state of your source code to that stored in the + the source repository, go to your project source directory, and + execute cvs update -dP. +

  • +
  • When you create a new subdirectory in the source code hierarchy, register + it in CVS with a command like cvs add {subdirname}. +

  • +
  • When you first create a new source code file, navigate to the directory + that contains it, and register the new file with a command like + cvs add {filename}. +

  • +
  • If you no longer need a particular source code file, navigate to the + containing directory and remove the file. Then, deregister it in CVS + with a command like cvs remove {filename}. +

  • +
  • While you are creating, modifying, and deleting source files, changes + are not yet reflected in the server repository. To save your changes in + their current state, go to the project source directory + and execute cvs commit. You will be asked to write a brief + description of the changes you have just completed, which will be stored + with the new version of any updated source file.
  • +
+ +

CVS, like other source code control systems, has many additional features +(such as the ability to tag the files that made up a particular release, and +support for multiple development branches that can later be merged). See the +links and references in the Introduction for +more information.

+ +

BUILD.XML Configuration File

+ +

We will be using the ant tool to manage the compilation of +our Java source code files, and creation of the deployment hierarchy. Ant +operates under the control of a build file, normally called +build.xml, that defines the processing steps required. This +file is stored in the top-level directory of your source code hierarchy, and +should be checked in to your source code control system.

+ +

Like a Makefile, the build.xml file provides several +"targets" that support optional development activities (such as creating +the associated Javadoc documentation, erasing the deployment home directory +so you can build your project from scratch, or creating the web application +archive file so you can distribute your application. A well-constructed +build.xml file will contain internal documentation describing +the targets that are designed for use by the developer, versus those targets +used internally. To ask Ant to display the project documentation, change to +the directory containing the build.xml file and type:

+
ant -projecthelp
+ +

To give you a head start, a basic build.xml file +is provided that you can customize and install in the project source directory +for your application. This file includes comments that describe the various +targets that can be executed. Briefly, the following targets are generally +provided:

+
    +
  • clean - This target deletes any existing + build and dist directories, so that they + can be reconstructed from scratch. This allows you to guarantee that + you have not made source code modifications that will result in + problems at runtime due to not recompiling all affected classes. +

  • +
  • compile - This target is used to compile any source code + that has been changed since the last time compilation took place. The + resulting class files are created in the WEB-INF/classes + subdirectory of your build directory, exactly where the + structure of a web application requires them to be. Because + this command is executed so often during development, it is normally + made the "default" target so that a simple ant command will + execute it. +

  • +
  • all - This target is a short cut for running the + clean target, followed by the compile target. + Thus, it guarantees that you will recompile the entire application, to + ensure that you have not unknowingly introduced any incompatible changes. +

  • +
  • javadoc - This target creates Javadoc API documentation + for the Java classes in this web application. The example + build.xml file assumes you want to include the API + documentation with your app distribution, so it generates the docs + in a subdirectory of the dist directory. Because you normally + do not need to generate the Javadocs on every compilation, this target is + usually a dependency of the dist target, but not of the + compile target. +

  • +
  • dist - This target creates a distribution directory for + your application, including any required documentation, the Javadocs for + your Java classes, and a web application archive (WAR) file that will be + delivered to system administrators who wish to install your application. + Because this target also depends on the deploy target, the + web application archive will have also picked up any external dependencies + that were included at deployment time.
  • +
+ +

For interactive development and testing of your web application using +Tomcat, the following additional targets are defined:

+
    +
  • install - Tell the currently running Tomcat to make + the application you are developing immediately available for execution + and testing. This action does not require Tomcat to be restarted, but + it is also not remembered after Tomcat is restarted the next time. +

  • +
  • reload - Once the application is installed, you can + continue to make changes and recompile using the compile + target. Tomcat will automatically recognize changes made to JSP pages, + but not to servlet or JavaBean classes - this command will tell Tomcat + to restart the currently installed application so that such changes are + recognized. +

  • +
  • remove - When you have completed your development and + testing activities, you can optionally tell Tomcat to remove this + application from service. +
  • +
+ +

Using the development and testing targets requires some additional +one-time setup that is described on the next page.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/appdev/web.xml.txt b/test.dockerapp/tomcat/webapps/docs/appdev/web.xml.txt new file mode 100644 index 0000000..593b800 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/appdev/web.xml.txt @@ -0,0 +1,166 @@ + + + + + + + + + + + My Web Application + + This is version X.X of an application to perform + a wild and wonderful task, based on servlets and + JSP pages. It was written by Dave Developer + (dave@mycompany.com), who should be contacted for + more information. + + + + + + + webmaster + myaddress@mycompany.com + + The EMAIL address of the administrator to whom questions + and comments about this application should be addressed. + + + + + + + + controller + + This servlet plays the "controller" role in the MVC architecture + used in this application. It is generally mapped to the ".do" + filename extension with a servlet-mapping element, and all form + submits in the app will be submitted to a request URI like + "saveCustomer.do", which will therefore be mapped to this servlet. + + The initialization parameter names for this servlet are the + "servlet path" that will be received by this servlet (after the + filename extension is removed). The corresponding value is the + name of the action class that will be used to process this request. + + com.mycompany.mypackage.ControllerServlet + + listOrders + com.mycompany.myactions.ListOrdersAction + + + saveCustomer + com.mycompany.myactions.SaveCustomerAction + + + 5 + + + + graph + + This servlet produces GIF images that are dynamically generated + graphs, based on the input parameters included on the request. + It is generally mapped to a specific request URI like "/graph". + + + + + + + + controller + *.do + + + + graph + /graph + + + + + + + 30 + + + + diff --git a/test.dockerapp/tomcat/webapps/docs/apr.html b/test.dockerapp/tomcat/webapps/docs/apr.html new file mode 100644 index 0000000..4ff4290 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/apr.html @@ -0,0 +1,190 @@ + +Apache Tomcat 8 (8.0.53) - Apache Portable Runtime (APR) based Native library for Tomcat

Apache Portable Runtime (APR) based Native library for Tomcat

Table of Contents

Introduction

+ +

+ Tomcat can use the Apache Portable Runtime to + provide superior scalability, performance, and better integration with native server + technologies. The Apache Portable Runtime is a highly portable library that is at + the heart of Apache HTTP Server 2.x. APR has many uses, including access to advanced IO + functionality (such as sendfile, epoll and OpenSSL), OS level functionality (random number + generation, system status, etc), and native process handling (shared memory, NT + pipes and Unix sockets). +

+ +

+ These features allows making Tomcat a general purpose webserver, will enable much better + integration with other native web technologies, and overall make Java much more viable as + a full fledged webserver platform rather than simply a backend focused technology. +

+ +

Installation

+ +

+ APR support requires three main native components to be installed: +

+
    +
  • APR library
  • +
  • JNI wrappers for APR used by Tomcat (libtcnative)
  • +
  • OpenSSL libraries
  • +
+ +

Windows

+ +

+ Windows binaries are provided for tcnative-1, which is a statically compiled .dll which includes + OpenSSL and APR. It can be downloaded from here + as 32bit or AMD x86-64 binaries. + In security conscious production environments, it is recommended to use separate shared dlls + for OpenSSL, APR, and libtcnative-1, and update them as needed according to security bulletins. + Windows OpenSSL binaries are linked from the Official OpenSSL + website (see related/binaries). +

+ +
+ +

Linux

+ +

+ Most Linux distributions will ship packages for APR and OpenSSL. The JNI wrapper (libtcnative) will + then have to be compiled. It depends on APR, OpenSSL, and the Java headers. +

+ +

+ Requirements: +

+
    +
  • APR 1.2+ development headers (libapr1-dev package)
  • +
  • OpenSSL 0.9.7+ development headers (libssl-dev package)
  • +
  • JNI headers from Java compatible JDK 1.4+
  • +
  • GNU development environment (gcc, make)
  • +
+ +

+ The wrapper library sources are located in the Tomcat binary bundle, in the + bin/tomcat-native.tar.gz archive. + Once the build environment is installed and the source archive is extracted, the wrapper library + can be compiled using (from the folder containing the configure script): +

+
./configure && make && make install
+ +
+ +

APR Components

+ +

+ Once the libraries are properly installed and available to Java (if loading fails, the library path + will be displayed), the Tomcat connectors will automatically use APR. Configuration of the connectors + is similar to the regular connectors, but have a few extra attributes which are used to configure + APR components. Note that the defaults should be well tuned for most use cases, and additional + tweaking shouldn't be required. +

+ +

+ When APR is enabled, the following features are also enabled in Tomcat: +

+
    +
  • Secure session ID generation by default on all platforms (platforms other than Linux required + random number generation using a configured entropy)
  • +
  • OS level statistics on memory usage and CPU usage by the Tomcat process are displayed by + the status servlet
  • +
+ +

APR Lifecycle Listener Configuration

+

AprLifecycleListener

+
+ Attribute + + Description +
SSLEngine +

+ Name of the SSLEngine to use. off: Do not use SSL, on: Use SSL but no specific ENGINE. + The default value is on. + This initializes the native SSL engine, then enable the use of this engine in the connector + using the SSLEnabled attribute. Example: +

+
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+ +

See the Official OpenSSL + website for more details on SSL hardware engines and manufacturers. +

+
+
+

APR Connectors Configuration

+ +

HTTP/HTTPS

+ +

For HTTP configuration, see the HTTP + connector configuration documentation.

+ +

For HTTPS configuration, see the + HTTPS connector configuration + documentation.

+ +

An example SSL Connector declaration is:

+
<Connector port="443" maxHttpHeaderSize="8192"
+                 maxThreads="150"
+                 enableLookups="false" disableUploadTimeout="true"
+                 acceptCount="100" scheme="https" secure="true"
+                 SSLEnabled="true"
+                 SSLCertificateFile="${catalina.base}/conf/localhost.crt"
+                 SSLCertificateKeyFile="${catalina.base}/conf/localhost.key" />
+ + +
+ +

AJP

+ +

For AJP configuration, see the AJP + connector configuration documentation.

+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/index.html b/test.dockerapp/tomcat/webapps/docs/architecture/index.html new file mode 100644 index 0000000..b28f7a7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/architecture/index.html @@ -0,0 +1,77 @@ + +Apache Tomcat 8 Architecture (8.0.53) - Table of Contents

Table of Contents

Preface

+ +

This section of the Tomcat documentation attempts to explain +the architecture and design of the Tomcat server. It includes significant +contributions from several tomcat developers: +

+ + +

Table of Contents

+ +

The information presented is divided into the following sections:

+
    +
  • Overview - + An overview of the Tomcat server architecture with key terms + and concepts.
  • +
  • Server Startup - + A detailed description, with sequence diagrams, of how the Tomcat + server starts up.
  • +
  • Request Process Flow - + A detailed description of how Tomcat handles a request.
  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/overview.html b/test.dockerapp/tomcat/webapps/docs/architecture/overview.html new file mode 100644 index 0000000..ae7deaf --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/architecture/overview.html @@ -0,0 +1,146 @@ + +Apache Tomcat 8 Architecture (8.0.53) - Architecture Overview

Architecture Overview

Overview

+

+This page provides an overview of the Tomcat server architecture. +

+

Terms

+ +

Server

+

+In the Tomcat world, a +Server represents the whole container. +Tomcat provides a default implementation of the +Server interface +which is rarely customized by users. +

+
+ +

Service

+

+A Service is an intermediate component +which lives inside a Server and ties one or more Connectors to exactly one +Engine. The Service element is rarely customized by users, as the default +implementation is simple and sufficient: +Service interface. +

+
+ +

Engine

+

+An +Engine represents request processing +pipeline for a specific Service. As a Service may have multiple Connectors, +the Engine receives and processes all requests from these connectors, handing +the response back to the appropriate connector for transmission to the client. +The Engine interface +may be implemented to supply custom Engines, though this is uncommon. +

+

+Note that the Engine may be used for Tomcat server clustering via the +jvmRoute parameter. Read the Clustering documentation for more information. +

+
+ +

Host

+

+A Host is an association of a network name, +e.g. www.yourcompany.com, to the Tomcat server. An Engine may contain +multiple hosts, and the Host element also supports network aliases such as +yourcompany.com and abc.yourcompany.com. Users rarely create custom +Hosts +because the +StandardHost +implementation provides significant additional functionality. +

+
+ +

Connector

+

+A Connector handles communications with the client. There are multiple +connectors available with Tomcat. These include the +HTTP connector which is used for +most HTTP traffic, especially when running Tomcat as a standalone server, +and the AJP connector which implements +the AJP protocol used when connecting Tomcat to a web server such as +Apache HTTPD server. Creating a customized connector is a significant +effort. +

+
+ +

Context

+

+A +Context +represents a web application. A Host may contain multiple +contexts, each with a unique path. The +Context +interface may be implemented to create custom Contexts, but +this is rarely the case because the + +StandardContext provides significant additional functionality. +

+
+

Comments

+

+Tomcat is designed to be a fast and efficient implementation of the +Servlet Specification. Tomcat came about as the reference implementation +of this specification, and has remained rigorous in adhering to the +specification. At the same time, significant attention has been paid +to Tomcat's performance and it is now on par with other servlet containers, +including commercial ones. +

+

+In recent releases of Tomcat, mostly starting with Tomcat 5, +we have begun efforts to make more aspects of Tomcat manageable via +JMX. In addition, the Manager and Admin webapps have been greatly +enhanced and improved. Manageability is a primary area of concern +for us as the product matures and the specification becomes more +stable. +

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess.html b/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess.html new file mode 100644 index 0000000..63e6f75 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess.html @@ -0,0 +1,85 @@ + +Apache Tomcat 8 Architecture (8.0.53) - Request Process Flow

Request Process Flow

Request Process Flow

+ +

+This page describes the process used by Tomcat to handle +an incoming request. This process is largely defined by +the Servlet Specification, which outlines the order +of events that must take place. +

+ +

description

+

+TODO +

+
+ +

diagrams

+

+A UML sequence diagram of the request process is available +here. +

+

+A UML sequence diagram of the authentication process is available +here. +

+ +
+ +

comments

+

+The Servlet Specification provides many opportunities for +listening in (using Listeners) or modifying (using Filters) +the request handling process even before the request arrives +at the servlet that will handle it. +

+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess/authentication-process.png b/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess/authentication-process.png new file mode 100644 index 0000000000000000000000000000000000000000..e23c33359c42abc6303b216e24275cae80305430 GIT binary patch literal 42682 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 W+8Ty}kKL=O{kGk1Th`X27ykz`$F?Q_ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess/request-process.png b/test.dockerapp/tomcat/webapps/docs/architecture/requestProcess/request-process.png new file mode 100644 index 0000000000000000000000000000000000000000..33ae3c3766459f39c8bb19c035234afa44be1dbd GIT binary patch literal 109471 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
>6&dn0#WXIvg!d4Bj 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/startup.html b/test.dockerapp/tomcat/webapps/docs/architecture/startup.html new file mode 100644 index 0000000..297f317 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/architecture/startup.html @@ -0,0 +1,84 @@ + +Apache Tomcat 8 Architecture (8.0.53) - Startup

Startup

Server Startup

+ +

+This page describes how the Tomcat server starts up. There are several +different ways to start tomcat, including: +

+
    +
  • From the command line.
  • +
  • From a Java program as an embedded server.
  • +
  • Automatically as a Windows service.
  • +
+ +

description

+

+A text description of the startup procedure is available +here. +

+
+ +

diagram

+

+A UML sequence diagram of the startup procedure is available +here. +

+
+ +

comments

+

+The startup process can be customized in many ways, both +by modifying Tomcat code and by implementing your own +LifecycleListeners which are then registered in the server.xml +configuration file. +

+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/architecture/startup/serverStartup.pdf b/test.dockerapp/tomcat/webapps/docs/architecture/startup/serverStartup.pdf new file mode 100644 index 0000000000000000000000000000000000000000..34aa59808b3a7bdf36d07278bdbfe8d9750b68c0 GIT binary patch literal 46175 zcmc$`1yr0%(lCr$a0w2BySoN=_h7*WcLs+90>Rzgoj`C265QPh5FkK;yIcMtxw(7y z?!M>U^M8BJd*ETFyUV((`swcKDyUQ>q?p*4IZ>#-Zj4W(Ah7{h0S+eCD1w3j6c!Cn zM<9Sj#n=J}E~pqg1MNWoc1|#a8n~*#D>zcd!S6L0kYFe^e*}&8&>Y z96SJe;0jg%Hyb;EhmRd#0LB(~c5wXnEou%RV-OGwjv_1!KmppDJ&E(g;!m+uoE=Qn zfgmtd7O?aH77d^W=qFJrumAwC;R5mVm%RIk@NsbtN$eX)GDpc2H@ZZQ&a=| zY!!E~b#PX9G&TkPL>71925|i9!c+5Kq36eO9@I_*XKB`Iv*@7l-{xWys;wJv=Qq06wM`UNqclgkkB zLfH~5WhtqpPA`O#(`n<2uoD}M^f+2G1YE`p#`GiIqDI{mzGbi25*s{lC+*wg(sd^q zJ4L+eWfr>1vYX!aJ$J@5P^3nhi@#EhuqsaND89F5j1~&d+z_oEq{qAw*VU;SjCfp@ z#?7acPYQQEwLK-f1!5j#%9AyF^w=yVWBU_M@9djoQ0;lvWJXUP%!8KPHmTen&7{A$ zlt&5Zj!Y%dY+=vuYA6r&3cl`{wmh?oFU%kH${edvyi@p0OR`*=Rj1jSUNSWq?s-bL z_cn@2$E=|6O6eS!Koy{5@yTM5hHllCXVJXjWkYM~T9eR?iWaRs2w|nt(08AI@w?3N znrZ5i0r{g@^`>p2gE&N?APcR!lxYMpIX0Yr^~pBcLTlGHbY!IY6@r}G@Z*hk6<=XY z?-v$>{ia++NGHnv!m#G^sHl_E@7v1!vTI+yA~rL9dMhvYVl$vXT~Hx)w|cFM1BLW$ z7d3p*XG{O}_2=)(-DyoL1;rcqlN{zIAydv$*laaX>v{C)8zTCsqUx5}hAI4>w+aVV zzx^OG)~Da^Z$Kb|#~8CAX9H2}Xv<==sZ>z8nk+G5xfe>^l$)nA83>KEq>R<3aHD%R zW8h9-p27UxlU1>gKw&3k_f@1F-(kUe(*cBpj2%WfKn&iV?wvfj#7L$lG?stnGpsSn zw}zL|=+!Bj5*k{t7@I}165ofA3ZooRJu{}KG-E$xU3Vmk(c{mLmWfsJeX=Mca8FSw$hA>A|KD!SN}& zGuYfLYg3-wPIcwgc#Vh_L?LSdm|UHiydMT>cxXLYDg)Iy8^(yU)Kc-9-!aM}hqor6 z#nAMe?KIG>`4Yb~lY{nUPiNMWHk8PtmQY0kFY)w-nVC#z5kAqp)#G#AV3%`7dGLOY zCKaSVH75w#t@>O>E+#nD6p>iaXze)cM1#?92M_4ddH*fu(;Rtpg%zfgv+#Wi#Q?v1 zQu_3EgP2S1K`ID7p$={dUag6|rH-!2ZJGEeQp+;~cdB8LxSVl}G)qOXLW}Zb&x5u< zv)X0Z4dDWDa-(!p$JpxC7!03lzwkp%-#@GkNf@A+L+a_SE0eZ`id5C@DAT2dfZ0`?wl0;Q@{-8lg)2x1jJxoZW{NwVW( zF%kOaSBG3M%t#H>*l~9d%zRPj z`P)c|Xb5dobZKEw-sN1WL$A%~V%g^;QSrHveOh7mjxD(WrVdaLb;Bi^?c| z>Nbi^qG2A`SPGCR(zNHgbQ~P;>g16$QbRtrxxRfDsHg zz$!s4*M}?rvTNq}e2p@;<^`ULuXSr=s;G$ow!%9vjFK%K4NbbQUT`%2q3)cJTf_=3 zQo;9zHOnmOZq-8+G94__=|%HkVvoawjDy4_MP9X_}b75@>Yzi zr`71K2%KxacCA+Uu(<8T-?li?{(j1}!F14Ttj{WmY0kZ6=e*bFUFKnpU7TG5tGqjD z?P&21sOIHp++|}mc}pe-`^5uuA?0=<3!WWDgEsj_g^%AA5OW9Y zGhRQ&Ra(%syrgsoIp;96_7)-J+SPnC|G?uO{<6l5i#al1JbGh@Y_c0efrf}!OydRb z)oS>8mH}Ju;`_}Frju%Y%2oBgFO=?d>VXfN3lN@IeTZq6ze zIrRFw*C**rgDpA|vSv>4uv*Uo$fS{KDTb(b@NVvexaLWmIkB-(?4ahVbfz_ZcR?4W z+7^WU-w3J0$IaW*T5s>_&D_&Nk@R7{wHX^$PY)ED?AbaCcnV~;rYYgH7B|Ls6jntc z`jkm;GRI&&|Loo-n-;EH&47J54)95uh8?747j&>fiz-?M#?Zus)7Afl)~8&4*+YuzYk zOK>T?fGUo$5qqRlMmIb_@1xENllGlIrCv=aMo@aO{jkjNioekhj|JN+F?r=4 zriB5qZ#O=pNZ(rBunjLo`lca}v|YXfzkS6LqtEWhF*?OP0ox%N1{*C{K|~!Bd$pu% zXUaZzneBxA?W}YQRCnWVVD%;z5&5gszgPKE7J4G2WzzT4Y1)20XpCq0EWOzo%x-;Q zi5(r)j8{!>XL|I02GyTI@(Y|(SlIIgpEO?a?{hkvRBOdfQpgXN&ukjizAmo>T3$g2 zmv%75mMthX7d%T#`uKqYJNInR^&Mx0TgM5~&Z5Wz^M`fy1rbu zrJgFsc)b)`hU)+W=WG)}ELw@V%H>NRk*@-Q3wCz(;-UzVilxkC1#<((l8CCzi!;q( z6XGGzQGv}GS)}Rc3BlNLxwR_O6$r+ZS6!s<(5DCwOUs3VF$~p;Nw5*8k8Y=N&h#tYflS?M$w%AkreIPGO||0321} z1bnsxcLj3w`(RsQl*J|-GjWT!%3(A+Q`d=CQKVpjC&2>W{}kA=B!BLnRmsJ)?_02x zq98vHb1}M!BAV&sa`beVOqWezHjO!u&Gw>-0^=c4eK7)v!5;UMS>jE%!R@^4r~Zj<;M< zz*izU_B%{Chd}vP%!?XzVH4`N&`}$SU%t|_cC5`z&rW1`E?0q$vs7+!Q%++s5M9wZ ztF84TCZFpXoERzE@Hg#r8@ENZi22YUe5E%SU`zo}Q1%j^i%CLR>zU6F_ZgKc3n=94 zik@Q;^DHfTdAm5DDfV_J!>X$#hk!twpE-@FT=ypXu%_`W4`CsdcweewDghGJvE3)+ zO;dWfIQ)w03a7eBi55>fHJaWKWx@r+>y`18H*qv@ZG|F!HF*9$7dJnm)Cy+6JpdqJ zNlZ#-Y}`awOL!WGCy>4|%hCdzY!7*854?A49&3N~#r*8WcTcwy=?17r2bM1n*NhOxgKa4GpKQw7{@wSL6U1 zHg^%RaQfTiTcTo2sr9kC7{wva&#>PRS?p{GU^i9(SG~vB$hpCN5YN&3#0}BMtD9x- zM73gX8+u_Qm`HLbC7g>EpG^&moERaCOxG3oTdQZKp-;qw8X{8{6=48YQJ`2UE&@z+ z0wo-ucm`o-kOmTsxcd=76CA$#uxgnWMr$iyt|UpXu8R@suds`X9BDNYrXi~K9+o6* zAFd5RCppuN%wTCtb^??MT3RM?v?N+P%8AI2;ISSw{!ITeij>&P(u4r=cm>db zsYo;$sDMPdtys7LYwyj6z!&IYq``E@TN*uQ`uQ#1Z~$`VTaBVR0G?>%1u-_kbP8}xO`)-$ftA=C3uSe#jd69Wv4-KPUCerni zSa9hqE;^bLVBOKngq4YWIPpy_P?A|jbtf&cgig(uTRRJGX|WxRp795XB+m%LwsBMC z*hHUy)U#8hcxwnRdpwiH@9RKcic6B`+FiBbS_kkiZ?+ZPvrSqhMe(p9`(OfpJ(K|D zAb5!<&|;@x3iS$BmW&I1FPA5AX4r&)Aj9+-4Dzj_<;94#DtGEAhGVb_=bW442L-xA z^dzyCF>}J{lqPLaHHkv#yatxU8F?%H=I)MsPRI^Zs2HYWi%(2vz5IHSVXfyunQ>oH z%FqSy3S=ZXi`ZCKp1o}%=q^ArbJkD$YKVV4wSA;jBC0USKsHuiw;W7CD-Eq$UNxAA$>k+L~Mq#W1EKS%) zpA(=CbDKZfwQxludf`yMTM@-bT14>_b%$l+g^In#@Rtq2JJFY(E_Hc^}Yu=*kAABr`#i*89Q+O@Ii>9gBLarQzeV~GMMNc%1objpf4dbm8ahBL&& z2<|sZ$eVDY`J9F25ca7{e(~J;!^X4pJE#_Fw*+?|%3dxx)4qFrF0fUiV8u6)9)LoJ z6bbBc)?iaBfXrufA$0Dt%z=k3@5?kr?jG#)_kK^%&j=kvP~K9U$4&(d+01mVW{c1c zq?dqlC?IU337?^IeDU74{-VILpwAWquBeIUs0jBc+c4mh2cfLk=QZKkzB5{xM{C;a z91WWxnzXp6&B9!2&He)NqG=hZ+Lz^Ak&a}M87E&(ZyryrdLFj)rt|dyCnk=RlUBps z*VN;Sf9!4E)UwF?P}x@fQtA~tDCeC!?Y^Mu-wS#M&JoUzwLZJ(ePskG#&_;7pf#`q64~=FA1sdCy4ly%VwGuz@Q!%uN*DK==#pw_o){J(P zUWI5;*>*80>?g%XQi{;&JAV?l=hy}*KEk1l$Oq0DL z?#{^_IO4xM=hGYIaBIK+fjKR@(~q1&=8s|x?f8*iZlqrAcu;vee{TN&!!rrnlMnLA z!}#Z+1nf8bRrB9FmHcG#r)2+U$C95t`}?_sjf?v~aVfTH+c+#~VLpt#a`J!p`uyU; z_r*O^eQk?Q57?zq3;VUpi1M>ac`yT;?Aeib(AViay8gm>C}d~Ov{di0WzP(QeWLV( z6h`5eMSi}!d5M}9gFLF}Fi(dR?R`$?(gkjL`*_mg!9`G6j!>H-6mFjt^)Vf3Vca**&F z8nXwJ+IE9w;@gn8a+T|tuGkjS*9jBLS6SsQX~X-kn{U$W&;+f?n%=;Si96`Z9^SSY zFdxzc82| zB@JDh1vw1uVrh*afYk9V=_ln!`QQ+l*KO{4!q(#kM$80qxI}p@;S9v1 z>x+nAkL%XjI*O1y&`fzWI@BfUg|>xnw#u<#y4h0`jN zuwn#~0TxC~DaT5x=nHysud6a1w`R2+eYHZFyQq~GM|yCs9) zcblk`V(X{MurO8X5~YerS?dg62}4DdMTz*=(N@VpyBar(HY8HYteNI}(j%^J%6U$p z^iC!Aj(;5hG2}KOf6Q&Mgnlgb39vj{Sn<(`mtT47o(JdpKG_4P5IlO?7JZ#xMp5N& z(P1CDxUp*`)Irbmb9INAYJLJo_H9-TVOo>S2+#e z$MpEH5Y2;v-OP8^^}ZjXmj$O@M9gr;&EBZBUlq=&&SF@yrubuDI95=Ed3iL?lnK!- zJ4v_nxTx(}MWp+=-;7vwE|@G>vwh)7oYUo6k3L7i3eTFVYI<`-b)T|}z^N1Z`g=(@ zG{MaQh%{<`)UxerjZG;3B`l-MmBb{3`J)tE|8ek(}d9kOOP` z826Tvs*(m25V*7zde)0)XyLDJP9YOE)@X=dqtl8suAZTD@CO#4s)i;p#rFDaA%`A| zD{2;CJou)NewJW0bll(yMV?o>^t88GZ`p>MPM~&Apf|3n#9=+EaYlaJ+8w>FGC7zf zb2DO+wA0a)h*i(*p3TEBX0mI56vqk?enQMOAPWdKuHU8~@zVCcH9z57f))@iD@lP; zS}IA(<1VX%-5r~x9}G!3RBY(Pj1$=MzIRI?M=IwFqP5TFiu!hrIg>qqwX=V<@?+{? zJ15OA2wMOr2eV#;Ya4^j?a-Kl0Bvr_{2BXwH#W(wU}HV&!L|Io7`Anfj2}5Po>$+{vx*I#QL; zl*0#feT;x&Q#g*=l8=wf%E`mktYvVN#DZ!O*68iMIn;!c2ms=RK*E3vF$qlLVk(vZ zxs*fGnSjtj(^#FjzVl>1IX=q9s)Osg#GJW^uvve_rq0`SHh&%+6nf%*xm+#l`9AB0 z(J4VfVtOhlp2_;$G6_?$S!ea!9M;a}h0Zc%c@id_Awt^(IoQwIh-G)67D7_G$bI+T zI&02I`ZA12znLeR)EML|Obk`tD!Bx6P#*SGT2>$hBUxGcE7LFhckHj_a{X!L8Fj6i z;v&spGDy+_u|~|hyfKaa>l0MO99o#&%jpP3#WIKebb^mY#X;_TKrts4LegnC$z6M zfQe`JKuxEtV0*b!nCYMiH(;;)G}eg0tCS&l9;&Hv$GW<`+)=zs2v%SaAbGJgI;Y%$ zQJ*OP9=ceKPahs>MG6~pi(r!7Nz5g>`cflLU&3xF54|}N)c#q6>E`;u<@m>^ckV_$ zo|df#M-v_tUJ3deu_a-$?`-N=s(z^KllR8d>J$@ok8zXwvQ0WtSF_eXkC&U#Rp6A% zJ79hlY1!IaP_wAZR~Kks<(nm-3&~|!wI*Y2pkt+PL+9!G=EWm--aDAdQFgWV=*I9F z)G{IQUOyOH?pSD8jTeU(YXeQMBbyuxButsf!M%52fZBlQ*ofqbIFwU z9uP1^65e$iGuEzlGwCZtZ{H4i)G5Z04xj0ykmLz$D(}sAlhn-G@Uy+W;nDqRdcE%m zKp~6mXMDOnhqt%0L~SP3!;Mz$i(*Vm4_OX}A3hYP&oYiW?2nFXJ6v10n_W+T@5)DZHay7wUJ!T_=ZE=!wH?_^M6+n|E@x6BRyNDB&#SFzfied@Otto$Dbj%qYhnX)5SqYWdZ?KXQ{ zW=S16A|#wUFM9cIAH-wrJd+GhRqWv2xLu>B=}qt5l_`AZ**X2@!^Tn@y`_Z*ByMC5 zlBMKnA*VAd^q#aPZyP(RCC_#^lF{qEAYhWt4idMrAt5t&QFq|`t~VJmXJegJ!(vK= z8x2TF{E!@eXZ!NoVww2tCxoQhSWQ|;IjnQIprd@uU6nUgo;3NNG3hkTGZS9#$qx~9 z8Wfw+CTcGnS;!(}LCD=sRd06fT|4oIJHfW&j>BiBoG}OrU_e8pmY-=?-QXx6?JUAw zb`%&T?~i|iX(_!df(VmYsGhF!vpMQS$V!wn%wm6W*Dfct9*U^Be<4lL>^?#jHk@+T zhf(&5!lJjXc(wnnNT}lsqV}3^R+*z>5j&Lipn7^8)(i}hoI>^Dt!#OqKzG>WY}!lb z=59y4&tX%FA~pa90nawr^B ziADUjrMs8;w+5TCosD~^GwU=YjRYgRrMMTwL3jDgu3fOYpR3)j*MKN3$Rt(i-CZQe z^TKsiG#c5LR#nhYwjbX;#A+F&OTx9TBdiYl#ihYXMeg5LCkJE}-PPv!K>)4au36r5 zA&!}z-G&nRs1n^r#sd`_B3p^#Y_>W}mHGAa=WtxMeo=z5mg3 z(IQpNSMYXSB5Jj$_YGI^Nn)^pQHh#t7!gMtj@i|Qk zm&ki?fATYng3&$R>dC4>^LOxr-Rc&4F^wiZ#N-g(2uQ*F=pwL#h|vrw*2!UGm}vrL zXh|}6GAjnnw_yr0?cAxh9vP7;mq^H@dKoVnfXXv-eTWkf_vM0K46v{IQlJz+TIXHu zIM?50oq-VS0J*Gl&$kh~eboC-ggT`s4^<1t$)e52B}&*<;4)-Y{e4O)My-~4t96t{6azU46Vxq+keYO%el_&NTe9#!cRrz~|jOF;)(Bp!gmjtrvigJY; z=zu;*Awp`cbGk%KjDIl5Z`WFR!@sP&!YAO+GE`FxWvJAEUu5YsD3sQcU35C`a$A)X z0los6-qr(~9%JGn1+o5{AfIRL(0BKJM)~g!L#-ZTDlYHu1x&;Dt`_Ueu10(P6{GBv z!|{iOvue)Glg4lQUpg&t!wVtP6hzC2(WlqR!%yI+Gf#F*Bw!-*Gv;0d)6T-ZkCkx=u8fY7#liOyz!Qavf(A&S65AeI+EZGvWg$J zh+c7r?A^tRY7~WeP zZp&rx?P|;92BoBa%4HjAnZjufwumYd4kXJDxWL@SUSgxvO32I8SfN7Hd|Mr22B3K&;tILR;h_}VdLZDV_{`yVP|IoLom5`+JlTe znCx9BXpsIuw9@$#&)$XE7#vjxWHxoMW3kdzi|~E%>ItX#>LOd&Ckxo1V(0M{e}A*>^B;CS7_#H3Un40 zHFb6{F$Mu7tXx1=wzl91J}zcf0IjwaIOx#bh3*&jpU}V2MO{Ib4q#+6J1cuIqO&o` z!TA^HA1%KDe|8NFsiOXKK)IOBY;6HrKxdbyq2*#`|4YxnP`|M>tU$IvVYQ!wVr&ag zb8rCym;f3McBaOlS6r_&6&0B6%zmN%0tM@h<;h6?qPYJDWqKGp{xS%#Jikm1T=Vah z`6uX4*}$^`yhCx21p-+-R_{8R5K7Qi*;+k~7r(8sy@e2s2a_4l+}PC?MDxFE@`;qK)lW*l z6!`~TL6#?>fAjo*)Ul(hv+d6}g_$V}&=zR-6sHT;GuvM#t(obcYW|<0f2!Kdl;8Ae z+WzY-_)E*vpn;2^|ID2Kg#7o`{Hyoi*Pt-cKi;U|xF;bRXYgC{DN6XCW1-mi{(oFN zfFpVTcJaXe`zqqUcR>Bg)wRqt6>xlX$ED{h%Y`m%jQc44LA0ud)pgk8ZA*t;a!CrbHpA(=dgQj+76X&)3ZJwQ-Aoj zt@sWcCfkhN#B%H?XB!qvLn>Wo_V|whAi*F+%RB*V)2I4XN@36*(Tzu0iiyE08BXH;@Tu#k0 zHow8VhPA(59sPPa5S|z(%r_jK7--t9w(Nb+v%3QwN-opN+-3%36n*(Wy; z2217f(mHB~AA_6g2|o9ajt{SP8eR7NWjlqd-~3=)@CnR-w_8|19400sYMzdb#9@Yu zdW+TiM&LFUl?)bFtaP){hdWNMSKo12fPY}Uo^jRmsH5&Xe^vEbyU4et0Yq~D>JSCq zZv$4Ro};_no9IWR;xolDS>+v!ura6!4m+(m6^C+YVZtw?Dv?U88cDiI??jT7-!0P} z!qVm)=Oj`otxdBTyvQh!@Uc9a%&8ohYOV_kM<2gt1)m#THg6J1**-RldKky4o=r#>CSaf(AZ?Va5WRdn=+F)d+=nh*TpikRO-?qM>A zdXl9=6)n*h+*!_$AlodzSas8amxeq-K-u65VcjFy~Wc` zL>rZy`A)4b`b@;Oj#BXGP;!W&w$+c;eg+>_qLWCsLRCZ#Nz>u{)N4o6-e z)=#4cu%zAj4AU3B3r3% zFFn4#u1$!XBR*S$@H@HjE2UF|p?Mm1=D2QbzJ@hz{)bnXB5)r`1KDFeB=v0wo#iR+ z13nAjts@`$m3k+mWHp^BOl^7dXYy|uY~@F~`4)8-ezESZfSs9>3t97^zo3>8!$pvl ztGi6wQz7RBIg&gSeZ(X%b8U~Rz)EK>u34dDe$zAA$L*K!c8bi&j1<^bXUlAClfojM zQ<-m2D`_WrH-yGm)@DG6+6rs86~y zsunnvjf&Vu>_~zom~mK|i;`+U^kQ~gh^y&Q?tGJoA)7jh!Oruo_h#{E`8-Q2pxV2p zk;9tV!{Kz6)mY;8x`ELYdK4uk^XZ%WugSg6hBN2Mia`ZPmS$1@C`sQCh&1TbSx{ml zDQJ!vR4vsslbYtjDs78#*v<0y#^8z3eENz7H}UbY6=751eS@)b!V4><^5fV)8WKQ_ zJmH)Mu{Dr8%2L%#%fty@tmx3AY>k$D%VWVv2>nFm^omHn;`B=dmIoz^T5F8L(2kcC zIxAXc2TOfNO2>>~0r$KW6%|^STYf1pk23T{Hit{15Hegra1cJBMe}p|$Z$+|ni=`w zzPJm0n=nHLbjhJ_QxJ}%{GuR&To0s$JmlMn=W^3SlRk6MJW^5w4keaNM2B__E&9se zXG6Hry(4=I@Le&Rn*3B4W~a~{N%;I<4QMF~_3FT0sv+*yIa>yaT~*-*!0y(-h9-JZ zUFIFQ>R8v{V(8Lb(W*0{41Vd7jZf|>jMNpg(v_`aWAR=fMBy-8UyA#fT~xkv z;J2(8vscnwRfOo-JmaUI-yC<;$G2AqNyd`N*)hXeRY<*Lhttd|gbcq)wA+QJ%6@NN zJ;;p9v$*fnFe3bzC9yQSd6!N7OTAiE?iwz%(~c{Mh9nuX6YFPSYFa9iLUCO^A31g0MVjHUsb z6skQkJxaZOaPOipb_;=~h{d>Rhn2m{fDBt^l$bbinh;c~6*_5o2#tEl8VhWZ`>co* z1lcvb(o~ZWe68=ADdiz{`3@$A%v`M6mImY~@UybuuCal;wx$7SimAxuta!V@c0NJ} z$Bv$oFD7b$`R#1q{C3INz1nbv(f$>rH?|9KljO2j4a<9*tzNpu8Yr{rLaHdEsPOfU zH>L<9A#a!Nw2yDM6v^ZZEZG_4$>Zzh6h-&&3u~kEy(vS@bh(t-S#y!dg=4+4Pah>f zy7(I27iXjJ*t0#QJmc!{0DTuyHK0S*a9UfDm-zfF(c zdj*JT69E=sbzUZjexpO@roJBN935Oik>&Z$)Ohny*%y0?Qt4;vKVA6V{Vr%eOC0wr zyAjQT=smtT%ZHbdaSCtlu0se&Lcfxv6sqH_kRR-zx90j6p66~;3^mDAPrq&}%B&mR z@G=q3RJlPQPZYmT>g0&k)b08-@@?&l>f#Rhy+cO6YJZM0AC06577yhLp@JSD}^VRSUvh9nR&4s$1WOR}r9Bq>Bj#7O&LFhPYomG>j}H^ORpi`Rdr# zEZX15P`A8dzi%(3bL7ZDXh^G4(dXawkU(WJY2%d8jmm&HM&Prjg;z0#Abu@S5hJ*^ zlKGrL5G_a+go({JG(_)>hut4SLS>58X985gX83?3m|~i#u816MS0GZXCL}iJFR-{SmBVL=v7X*RvSg%&peZB} zTApwH%uY>4&(Ev5Y0x~n7AR1rrN^x19zw~FJinfLkb874WmG&Nh#%ONP#Cr^m~Oo7 zI+h^a&DosJ>{#$gD#e9r6Y-Q*eHwg+&Rv`6mpqzWX;Z&^r zN9hZ#t)Y36-s2z7kFwus58DT@qPJc#T&6%5u0J$MN(#Z!sZC`uk|paP;IP6I(K=z^tL!yNsT`S=m5<)>P2>REn;(|WnY4-Nc&-e(aZd}Y2zWatlay{on z97zNBTH#U`FtH*Qxf+YuLZ-ns2Hd>$#M(6hsoO6SZ1GzL_`lPi)y$t;&drA%^PYSO z&-7EGE5uaWuvZ~>R{a!?YA^sGM7L_Gy>3NJP_A<~wAA-`CWo8m$2{0wx#6lH{W5{? zgQb`qPD8#VEMEA#v2R|ynm^#|;X5oCzm!j`%AH6mZ>9(GdT4SBimM)Je8bH2Afuhp z0}2cSY}(&nsx$}!cJ@qcSturGEoq4|vt`F4lX8_-c;=9A&;Hfr^)tQm&*RBIBDP$> z@mTU!W-j2QOZKO;l^WPH_VoAHo!-wlFL2ebtjV8;FSTE3o(`_yluYh_%A#cd%iY*h zBIrN-KLA<@{wEg@8#@~~t&)`s?ERqwr=tAw^8B@tjf<80r;mq*m6Zkz^4muPp#AqQ z9sS=v9ep}5^e?vn81}Co9B};~{u%)7|KzX%!~8ss18Dyj_YB=%vqsr@|Me^?4t62h zI#_@Q^(ng+oI?BiZuC$8BHNSi@hJ-KsYg-{&UOIKKaQt=Nl5*vihrZ6pLGAHbX|^r zIp%WwgZqCgVfQDKKPCG=yNBiYH~Gv@S;D`4We(0yBkW@Ol-bP3$^|Zn8#~GXtt>1- z03J48aQO-Hsg;Qx95RUVl;LXuPH<*_`U<8a_A7^(iJO}Xz{CNzY<5<#y4hGcc>YXC zRx-8&Cs8XYNh*tpF^D=_fqi-?EV5wrTbYX5TiE{0bY@Wp0qwK^e4OAWoj=%ffp3d{ zF#%^61Ht*se_WRTMg2choc|o;Uz7D`4m8R?ywe)auE3uyU|LqrE+BDBW9MJ;D;WP# zVq<^mj<%H<$nxj>=6Nz$Rsa_`4Dspn>4yWH5dHJveVY92KOvs}K0Qxxe}7Q^Uhy00 zH$iYVI5*GFhX>64>G@d(k1-FJX(XNi{zL?Sf0FH~?)USQ zbi zpGcVjz$W+8du8zC4SO<*pR@W8>-h72f{*Jza`C*^wsTnKMt(eeMP~GBDo^u*nQt|1 zS<6-?%%u51o&&pb1IFIhedVU+{oMrx)y>6z%d-hM%kDT#QsDxb+fksMj3L(Hn_ZvG zR!{ftLGer(#R{@HdJ|aBgAx}rJ<6-WUUtt~eWWVGFEmL-%lKVuG>>ICu8uu;X-GBt zR3i*0CQ?a!j~59U2DaQSUX7#eZ91=IUmH?qx@YMQ&D1UVTD%pYFK)|Z8Vb()g0m!q z+ofy0JjlG?8lG-)r(E4ee-wW2ZHS`{RHR!$3r&DoNYHq8G~;9)^)V5g^e}C|s+m6i z^1@ryfuzw>HU9_QCpknf=McG$jC@^C34$t#$tT^54@zNuk zw0MNB@#c^4A3pGWvXSDe8l%)jos6_;V8a|mRkVm`5zg8$`pJ&s$o&rn`V-t!^>IiW{&?!lvm*LzBqqV0X_O0B&l6cd{ zIfK93W4sF!9ELN!9Qnn>X16&YOl8+|8Ig`KBrA?qxyF6@QsOaC2BSnRx0}o#FF34D zqQ0)r9an=;b_=Gn8d50TDE&5xRr0t5i%XD)MsPgljpO8o=a_O?EPgx`Yw+u_oa%!x z*W~s-zsZC^_sjSDvdrn%zEXLDscjn#H0H`C9>*%M#r7{eAI^KUh^L`fbh8skN`)BW zcko^J2TZ-Yis8fFX2%ehqPQ)Hx_!KvR#vwOwW>jS^Tseu?T4JeZh&BBQGP>l5#0qk zRbYSACf!Km_jdBa5!>)=BG7^VaR{fc`3JQsk#i*8ka$XxTESQ`AlE&QIVo-wTY&0t z3o{jtmRk1_Zk!)%1YybqD~%TG7f%|k$P)F48ZkY~pbCU_0GF~^i4K+0x)U^x!(~*x zE=85hNmBC(k#6%lcz!v9W@h(fO|5zD^!>_(xkigd7V66o84dC}@o0jNp_n=!-ijLL z>-eYSQH)~OSH>rv$*av0Ic$xyyg85T-YZ*oJvhi;()COdG3I@qj4H`haIDu*@$78@ z+i9Bmn7V9I_~!e|+INpFWz-0X`hY?$7oyh?$OI_uNdRc}@5w4ZH1rU?s-o$#BFST} zp&bYfH6tr`D@nfK6ux|bu5#8hhjgAp73JIpG90?iIEl}7hVGj-_L^Fs?`WcmpO!RMFBKSrs+d>+a8uw3N zg?mgO>9iYgtT%Nxc~eAngJ2wVi)1)D6eN`^`CqDR01x_KF}SNRBnbwzZYU_`V$ebY$@tI#p z2#bmO=r$1uA$ja1s07=7goTEP1#`&-p@zRJ)ANMz$bpnEk-z`ibt*B;*H+U6M+9M; zpDBujarDvS*45ys#`QG>t4m51s$)zsL}L;L`m`}i#&ma#7Ce3swg``Z7@Pm<#|7Vk zhTe~#_D7-SC$3X>{G>ghJS_12tZ3PR{A=D`!2+j{%T~0m-&-J{NJsq)W3dW1C^08E zB`7XcQL!!iOI{R;Qjx4HuBkDJ`O-uHeMMhfegW2Kpf%}RWe>AGTY zfyZc90@!D0+(W)$K?HT1Sy&iuQGBkSn=+SSkpF#Afek^#mg}6$7`Moaj&M26mDiA3cM_H^J_ccYv zq-i7H_4{{c;R$sO_{KDA@03xe`w2JcS}TA((4)Z@Cs7v@5Ix4NQn}Acog@zkEFZbN zX`lDDWoxBh5IL4e&BBvx(ydhhVW{^Ag_+PaME|pu&~ikbg6a!YN(8tCi#0~W4PjD z)7w&wcw1j-`>+*Mx3t^K%L8IY9$?#&dCTbYk+9o6`?G^fx8|2yi-+-#=lvHr1}mB{ zj{`16x+5iM2*@zWH zy*{PIlC7&!B{v!{OVexu-*+4H1#>~ye4jC%xFwAQ%RT#xh==hS4{`^DV#?@Mf^5eg zj8jN<36Jyp9}u>|aFG9cX#2S}{JqluyZ=S=d-(@%XxKS^2P-`N6C5sH-hT>LkO|e- zc;=y~{rqwM%lBo%LB+rzLCefNnHXt|jm*#(Z*gf%PZge^p+pHx346hOlsvf+s*-5r zGJYw|nF*|T^dNj+ci~99gSy!rk9y);mDC&I+0u^|b8QjEW4B{`HXquuei(ZDLj>kM z$K=C0gQpxnZ$gD8411Yops{|Lp*yJt`+f;-A}O!;Sv}l%b8qVvz7am}u)1z_!O>&7 z-z;2-)Xs8Yt@ZfTGdN6dD6F8Q#HR37;wwe&I~()#Tp;7N?j(@HNT7317>M(%yqGAn zzuGq0FC^B5A$*y$cn6`%4D$mq&Y`t(aeiIm0rC3}qb}MBGg*6tNHZ3vxA4kaZ{KC` zytoK`^c}y)9Or>AuY_=mBK46Lin4rdI^!Fn^%Wg9Mf;}h+mE}UQJY8KAFq5y=PIrY zb1>jbiQrFYT1AO%F9@P?@sG$bQTHWK8gfvdD*y*S#Pk=`_&k$LAI0-q$r!h~{hc)1EQB@36js)T=Nr@HRzuRtfbQ;>0y3V5To;MNUnDN1IJ!b_r-+^uhObQfRmM zB8p(5(lcZJy7;xp>mbU8g|LGrnRJ1AKxF<*&A0HBXkzD&V&qDoL;C_4&`@`@K19F57XT1qJZ6K+jmjx@eTd*E8g7SBr-TC2y;a$Z=SiAxxv zQ@b?WEu4~qBO9GkO)Mc43uq+YsM5I&-XMGp2}lW39rJK7 zJ;J5+k3vYdO!iKI9B+I+X8g5M#XNX#sl@-K&>5@73l@ z_88}Vm{;}MKV93W4t^upbbj%EbHC99SKAHwfOi~(p)FI0j$}GDpakBj6m4lJe=3yv ztUOAz#b}WGVfz&*-u@ZuO9?b%+_qE@+bc#4y&k2>F_4xI!y^*~&>Y5o{;5w8U=tXN~n%*=ekwk*$D>Xh%Zs5f*oX&zR@R6i)d z1rOr1$c!vyl>TiJ8Da~d{LT=V=Z zA1A$fZjDvQ+`p$=cB%>H8L&5NB21I{qsmdqxp znqUL-#Y0WsuVS!-9`(|uN@CHH*7oMKd||{GD!-Rk{nF#Q1vBp!B&4lpTc^KVwcwZn zka8Sp+!CP@&FU*YC4ZT?a-EK;5DPNckLO#4rAgG7g>6|56|V_P%9Z5x_?LNtR!>45&bqzCrL-L{bL#Ym3FC20afqpN855sNw8RJQk{ker| zrAIHt407)N_gyI!(l~3Fto$A4;H@CuXh}=$w@#vuQMC@Z!DdNQx!+XrSN(uG0rW0Z zNoCAiM2TWk@gbVbC!q4!!LZC93?5|)8>w!A4p&ZD(57b3<@1_c*qd3X&jJ@Z>mt7g zb`figx%(g~S94f4C}395YIcVdqvm8>ZW))|AT^{HrdZfZVU7pz*9Hl3f0ehDps2VM zf<`0RNO$pPpGBUmG*6N3Vi*henLIweVgFo>{q935Dj9U?F6o-4u#~V=`rha#XZNcO z#1>+XlV?7iny>pY`i9l<_J^MCe&J)B zd5*bEH(;%bLx&KmB$Thh@f8V$N{RG^@ZhJp6-LJw09sDY=Rm>trk3v@xekm+Ip;Di z-lSQ%b4?%Gs5K?MO(>8UEwzzK7oXR)vaSrj@d`G~!Jmir(ehixUK3AkTv`-ykxJy_ z3_#*4j;(GQ*<%D%wG_pyfrQ#9dFe0|JIO|ZSS=)Wv#7%q3Lz-SGbz$x-iqUGZFtR}Q!j*Fm|SrtldZr$;{AUBLO{L0T@pC1!-#zPi>UuC*?HG=SKWiVJ*3we zRj&D$UT>Xd{3h4+;I7^OEhu0gY%5|j3cVQ|dOd?UAz$NYVs(Mbpw%2w^H<`p>TZ1{ zy3;QyoUIw1^s#!GcXlBkO^nw--ctMFn3%L<<|V{9HSZ*sZZ}5v&=KF|FZbIUYHYZ!d2fO{K)?R&!xHyBi6u7tCj6|w zPwuxG@Bf!K5)zE~cz=sn)A>v}$JD@jNK)eBR-x;jaE*TqA95I5cfrU348Ps(Kj3w( zX_(0iqc+!dcdg+++*fOGRaX^W=bU}cy-<)qyimwc5<&_TLP8?12y%I)Km-~>Ubj@j z!%7JV7F*G2%VokNToSD)ObV1H5hNx!Tp+c9sS=oJBXtVeF;p!+`pArJ97{X2Gli1l zxAxiRa&urBtop~y{qpU#_G|66*Is*{6-g&3m@%d_s+Vz1t6LK&9rYSEMEyz`f#Z^P<9oc}6yc!R0^_ zkgvZ=>%><{gTJ0JJIG-8iP%qn0j7ynv=FieI}6Na+Q%}mKw_hPLmZ%5<0?%?-S@1$ zSO>mj`Q@m8Od0w=DBVh<&4{nr7=H_J5M%yb#=|OFg89dRvqguDq3u8w=6c`t6Z;18 z7VPU{%=M|CW4MtDfcvp8VPGxWgZVSq=e+M)QP&i-eFtrpGN2zMfwgl?av$!GvC>o= z*572RN1JN+^>1JS1lR@_GR_oG_cF#A3|PQWU>wi^)C1)}4)6jn3Ud?YHDtUZW;ixw zd>}T=Huw;>$(VK4a8T~2b7tz)SUgXPb(G2#Qg}>0FC4S5<+wXGpDB(Rmt}mHbKGkm z@H#oBVvMsVI_ZA4L7qXxmdkwZU^AbGy?P;4g7+bgD>!D^K9|`q9Ba}iI1`Ge#;r9| zo)NG?l&WIA!e!SNFFF3GoizJ&^D@f(qcc} zwb;u=ke~5z4a3*2tub4%&L;S?ot}kHza`rB;i6qL%_jR@leF_@lm3(}-@;yKtxg>? zBfjq6)qfu7m&_*Q%qIIiv)#6_p51&Ve4Sb*knA$_Cx9?;pMQ*2<1g1*e1()?5nTn= ziy-BgL7F65u|EOid7K643(Ys_j8RQHMZ5h+Elgp(owoY|v>e|b{dg|@5>+sGeDH?2 zIO-O2-dJ+kjaM&o&Q~!t3~b^2T~K&O;bY(<#L-VQXO2mnpXL3491U!D;?=$ui_i0P z7`)4kPfwhdd*ZW?H!i&_?-t~D_ng9xo$mTMKXQ)a9Laf(^Nicx%W?f9dL!bP^YE(_ zQs;WO!hG2HmOA^$!`Sa)+qQD;BUZEBU<|MutSprO0GRd>tb0@JPA##!)O|YIy-OWE z-R0h+W;U%;`RtI)Hy_fE^pLxw6|8BLHHAPmy0s^d>>U|9fOS> zIFHZ+OW7xKFNp5udx7snV-NhycTqJ}7;oUcz|ko1M@kGBZN7yANZS^-)t-xHnmoLNZ4I74;5Fx6RwICBANz!-IJh-%Om{o#;PI;JE7;k)A=pK zZv;Lsz91!9VfhXqX#>AgFu(CG)fw}t5^+4kzXyKUM(MaOG{oLLz<38zeoCRrfz%~9 ztfd$U^rX~h(`$O8aTns2@6c0X3q2x=D9ad6gGGNz7r(<<{e<=#{b-qZh4zaUs$y9r z(kKJ(T%#FpOV(ec2UxGa2DyepVk-Jq(l^C2+Grd{?ERj4i-)n-=x2T(aWVq^Kg75S z+S?Q|ig32Jqx^||l-tQUn(bnSm`mxhUmT>ZE<85tdGOnO>?!Q!ayNTnYs^m9#@pB@ z*U96eAGZ4B$xw~t91Ye6n;)~B_9X!amP>4 zo&d&)3G@Q61?92eUjfG)8E>}<^aijEW1j_|TdXt?E5^x{%!^ylK%ZC1yl@uLAyl5!A0OA<1yOA zfSeAw)b*!!6|u%>pdU$nZ2ufRVukRIo95MfW$(WBBqi8Sjwkct^J5eexhx z5Zyp7`7{IgDe}+~@axdw_U;-D^hLQpbl(6!OLYAslplq@-GQx(B&t>K%E8e6LiP2l z@d}*&*MCiP4H0$inA87yBd`YL4}d38{xkS2xCZUtL%*%yb58w@Wsn~SUWD8Uc`ZG2K?u*8M`+U|nj?36j^@j&xD)lo4(ffc67&Hw3Gk`_FGT;ZmbATn= zv1UE688`!6ku^bM(23pI!4}XiNhjB=&647BM_l@l6i*hHI=mp?;o0+?W;sr?@n3S( z<7PTMa;(Dx(z3$Lz58ah&KPJ6q~8MizZkFj*e1?1{=V-yzO#evJI9U~>CJCRhHVsODGG$yU2MCOnaw!z=YjdF(EDB6X_k>m#Q zF?tm+31G;_aDGHSf_Lt9xSbuq3BU+o5^x1D2QZWCaDE8q2jl}#y^k6I3BXps2w)O0 z2Vlwjz&v@6J{%0DegZ(qd%!$-7pCONI=P%&MH+xWXIG)|t4IcP0tNtk0A}#6fp-n5fENI#0U7}Q zc>wbOnalt#1FoUv00qzq;K&~e(2Y*66e4X>vX=awTtXgL)ZdZc8ul`|XxO*N8-{%o zYyj*GxmXBDC|M181a)|@JlF=vSCQWo>zq<4DUeB69tpSskN|W5wgQd<%w&=*F6@+? z(8zf-1J6B)6woJz{RMi7L&{T<5?Kd(Or{iBvlcv{5qTs+l*oybP^1(&@2dlIXR%sus z(mrG&`{;>oo9NhnQmC(o6+5Lwm()w@1XeF#brV)!!s;Ma_ha<{R^wRRg4HNiMXUy} zs$lgzZi1yyvGUqO#b(8e)fudw#cCd_5v+!>T8C8`#}u6e3twJon6zPvNqS#_UEA8| zfH4MPMT4-dgK*nV0$%}?jFJK(d2w01FhK3%Vtt}qUbd$3>EwDc4Hc*1GEAcn0VcRW z)3A-Ep^<55zyX{9Yz0gK<^Uyt8Ptnm;71L105<>ojFf}XAn@l|7B z4V6K6&=Q%3b1|Gj5>))W$Vd70%ux|L0=Oek3XmA8h3|Fb6gWZ0wz1D`Uwm#umZXIo zAxDuPF2oBJd$e%dFX{Nlg~)j+>BcXjfC+XTZblIt2HOOmezd$Ai5#`7kVswu+gK2L zpqir)St?CnJFPV)-4YZ#L*0L@q>h3}!+$ zq~l_fbauv&9)QHDg0!ESG3gnxUD_=giNSJWOCCy!L)sMSlh#9fDRH}`~gl%?zmHp_OfPqK~dQZ~p+te^Fq->9P?5{bQ$ycJ@F&FZc|sY;c&=fNpbbc?VKOAs)rK?L z)DD!{E^D{CLOQl??9-}3ZCG<=P^P<0Yl>!cwzNr$MKc=P`St85#z%4x)yNNYjJmTr zF453IpXOYb9Y+`o2cP#*`}o1_ttx7dot056ZkOV|Sf)^ptkcfDZA?bM_X{bmJ-M)0he)yYYv234768DwQmvluPp%vH05xj`t@b zvDYvzkG+<-J@$pf?X@i;Zl6_TTt2Ixad~Y4v*5K!X2EB*`g~zzaUo=}dA(te-R1Gv z-6ZT{7{s$-!K~vkrO9r$*{oIz@_D@;53;&lE`e{gvt~0xT9Nmd&2!8awktw&hke9O z?88CpF`wlavCB@$N6}fVX454mzlo{OC~fo z03WJa7JY_){m?QmHIDx{RxHPxH-Fnx6I#8pCb&9Svy!1$=?*bLcaRCy1euy(P4FAN zFJIa)KZhH7PxRuJ-WPk%zLmkX^Ot*1^vqxE9mZ=i^KUG~XO83D$MMRuR|{`xeCTjLb01uY{jI zXUzEStsDHU8!){@oQ@Vph_EX5Wb9vTR|`;7*BL(N+}G}X?B3mb_q{9&tBbmdM4p>q zxVAb?hy;^}uev1(j2hM%YA{5Rh#Cb&qu3N*qZO?-#Y$`t;tCi|lZllXng`aInAVsM z8pjF7cBswN?9%@((xjd2-Fwf@?#?;?`Tp|KIxJBr-`RMqb9qYSbg(4^vo=zzj#SpP5amkcgAk zA6{PxAWKe05Uy;y!)}vFd?OBp(r0GWZR}f8@?qjBd>wz$cXm(nl27i(uii=gBVmBm zHL8OA8CG|qMy*)D0`I{dp5~3B$t+tqR=~t*x2Xz;Xv*NQN*u>BPMBS>T4b{%3M$P} z2F$aJfROB0v3j0mkZ>Fb)~ZR&aim$49OQES93lqggi1!@L%MV#g+KwTBMfhB85{NC zp)3?p^6d`T0?Xy)J6O){;DQ+}mywqr)G`l0rr_O_x_nD!L*2~kH4m2-7u2qvv61fB zSunYKc13H>)SXjIxm(Lhx4u?fwky-6`;rrhYxq?(fOzy|HxGjU9fUSd3u3B}5X|F3 z#KSR>Dnx7n_i!mHN7bkSwLx)c6OQZylt&^XL-KHv#rjhomgB<^F+`f3n{89|$nx^v z9+FOiW0RjkbQ}EMMknXL7l}XyhsUPt z85kHyda2PbNf>fMp=Zt_YV=yC8YZ#PYnopT@1-!I4pXP#a9fKo2pmH>gPKL%LgW@O zrM(*=`g9%44C)(}$Jn7OEdm{c-Wk1)>~LG*HiHvXRf#jZsSr-L1-<$i`yTR7kI1+>0s$_;m9f!K?V8?!>!2HyzCivyA^292GTQv zifqrGk!O*Efpm^7iw?HccCP+W)!>oKYj>Y*udi=!UteDwA%mF4Gf$SEPK;hnBogm+ z>^p-GCH8)O7q7rocV1}JbMZL zld)U%9U-hM+buGhWX@s6x0J5iLkyy6bYpT zEG*0A0>`q+{jOPq^Y{L3`f7UJqxGq8{-nQLkFOB&%|U!V^re>f2=fTr%baI>xr>HN zUhZ*mu{hrp6)R13);eXIwa8X(bsM~H;GDtjr6ivmBgamcS}>fhoZXU7WsomMdNng9B46Vegn0CP;$E^5 z`H_qZG||#sM9N7uX&^M|Arqhp?s{u1p}@|2A)TbjR$4S1j|^GH%R!SVGh_n7jwua| zXSo1HaOA~_wzObAAd;7tn*-@hN)U1nVuZ5Gay0jCK5l_wetNrO(TToeTc3LfkX$f&lePnrAvCB>VkEmX zM{1PlIhKW%S`YQKeWhHbR@z^Z)~bzCv%1Z5T;dr&r5}$3L6l51hXay`b$~ROtQR}c zWF+C-E>X16&K`0MxyTA_g3ae;Xy0VXT2t~V2<#e7^cSXFWws0!^i_gj6}vn5eNLj)1g4=K#t)EECS?!NO%>LRb3HD$hiFf zejGQKvdT>@iCb6R9mTIY z_c#51Q~eS3S7gmA6`MA1_IF=g-dS0GFw=K#=Y_;SZ$iXwV5iLVfO;e}qUBi^i7Uhd zV!L=rWad(HrC-vN6}W{&mf{#*pg1IolGIPpU{q*ILPV6Hzx0w`WB}XNrtyfT;V-D4 zr(2-K>NIsrChF- z8{}OwEdvjoNgg^ea>`EPZ1G$Ba4s_AR$y^Kr>Xmg_?Y^?eEg1)db+icft{}Stbf0U}^Dh*ZEO8;uZOWrMpM(-8FWxIs~L3d^N1O7B!*_KH@O`0bW zpppjh&#jukY3J0( zqYGx0Jx^x!E$@oI{L$tw5<`c!-Rk&jJim13lP?}Sx~}d7{fwz9t0e2uJAbKoHu0}d znupipCvZJ(fA>FJR|`;7*BL&K``o>|d-ut*u$Q|oTwW?K6%h9p8YTza0-}N#oZ@g4E~lUDhz^!dvGvl;cVFf1ckOsH>WDt*x!Q%l z!=Js!I=K0e-LDXlg`_*f1tf8dbZoa*g1L)Aa}%9)$*8)$rV{GiSeB zy=L3a=)EgfqW9WYY+YTy<<;7{)@ifa=5Olk+Pv{FP0DIewt^^a#TE z?5=ZoL4C_B%WAf@42@K@%{|n-`J+zYRWCqfD`&voi)d;{=XfNDG7(BRT7m@*d~OaZ zMTGgE_oYz}-N-TxZZx*2*t(oxcPX5`V0mfP`SU}E!TOSsVTAZ9&ykUngNrJF+zMMo<|I#1<*ayJp=}CQ*u82KFNkEL*enupx9!r`@x>;>35ORJ>`PP!2a&h5#5Y)a zql7gQgFkP3V><%kvrQcsunr7tWO9=|L*9a>gaW+qDZ zYp_cxnr26m*ANz@8H#VbU(;i5H=JF(BnE1rG%&nkaLn4l3B|1h)V3(cUc|gf+?qg< zE3gM1@g7zZ#DV;{u`_}oo%w}NkofmK#OVAyQd_rW*E7xMc0_mM>6@m`E-%}>FM1WP zS!&E!G;P6~JEC2DUsdnQrH2aAPdC>ctInhI?4H_+S!**Nbco8-)n)Tu$Yb@bcH~?B zH_%`CQBSD4hOF`fTJtS6r~$3>H=`DR8`{esp&wX!=}F6HmW$|y|E}L|b@=UmKg|*{ z>{-cr$}cPnUC+1|Cf4(-{l9f=ckHF_SobD(;)A5q{*~2{Fdl3T-5$S-pq=(o}1GZ{etgv`=447y)bY%8vSs2e%F+|nYRz!`frxT zP;daa@K0E$87&UE1zwXRQACtu3pL4_8A&3`S+eSwBrc${b(3x(CZC0qM^~*BFODaQ zwQaFf{ct1ualq&0Lh$au=y`xk9ok2;hrXgMd|y|z^y8?di$&52k!*oTWKSF%~Bbq&|TKdb=`^a2Oc z(B;s~Bv+D~RHx&mk`p^5s1P8Q3~z!DY9l)^kT>5=>C%@aOKtg7{6|G2UeU~yQTm6z|?J+ zv~Rfc1S$O(4}a4X>BUPgU&4`-bvdz|3LJ|=H-Rh&N6urxHB$>se0Bq z0Og(TNgUN=Q-|rIiI{jo%o3167eyi5Y{3>{jwh5s%?Oe;kmjf+9CAyC8Al{+F!#0@i0C%Y>RvMs7I^GP*8m?+=Dj5!s<%zXl45$V6GyP1h zAlAZ>Z|U-wLREy+m84EsN7f6imR7qU6Y$%!`bWEBY=C8O|20lXEC*MRu40`5Ki`n*>bwviiif9rkGpz&EDZSXV1>t znZ48Od-MMDd+=(vPr`$TDaxb3@2O~my^X>OXW$6OY!r8jV^qE)(1*N-xFPzdUXP9yS*~HR!LpbWC8>tx zz~scomB*0{P{VP&PY@(YmQ{-5agRQzV|^44L19;WhPAjXsFJ3MtWo&olGsHH`n z_7?^sA`G-^tII&pL3qA|onKSp;hO~&&!JQzh$B}IG{DxMBT8A3+x*+MuHhzPK#NTuR+ z41ok!^P5$wzK+rwFn|%Y2JJ>o@1fS8zv+y;b;TJS8bi_Re?pPXH(vR`xsKmO>(Of$ zoge@CFU}ih$I!~(IRAC7pav8fM#A@%3uUB z1}R7d&HQ<-r?{{cM(`gtrGiF;ro(Z6=5wuvcXGL3&}jd*?&tjytn?V{Q~+UEXDM1_E4m;f zy{UL*$&=jr5=PHX{(V>vH$Z=DxU{@MBlpqr2DQ*Dg&yYrFdR+g=izy^(35$40F0!( zpm>3`Oz19NU;G_@le}5k;oGgeDxFZW$|v&2iYkkur74D{DViekdIZPA0iQ?LR7qq_ zo(}}Wp;$0T#YUt%ypCrZtN@5*KmeF-}d`_Q;aD3hp3!G$mk z#RZfV2sn9{Jfn(*+KM=J3JEB32H8H&R?>?4pr$`a_BZNxWkiNF35U`eB$5tIwu{qh zsR6A7+EiwAO)FLaM~lkn85p8d=0=Kysw{pC@4fW?mUn-@xMKOD$vYR9KhseiU-&n4 zY{#J`uO4@5*wMDJ%}1|AlZho8oPJdM!v0x;H@AVVZ{9rbTRVx$bWeWF{0pe8hH~tq zYv?u10R0@pB+DD=bn&C~eD9*@+>$wo*79X^m$y6GQL(2;u8>j*oS@5-O-e)AoaEe@ zE3Fk}%aiMbZ%b?CCyicnv#>?lqHI++BnFZ@>Ak`pX|M94x+C#?@}P7`IpmKe6S5?* zabWxi=k+i&_Ml{<6vhBWBh@d%F1{I{s#Rp6cGQFV&;jIullYXKtd7M3G#jhtBdPEL zK1Efc%5YsgrK6PobvI{gr?7DRrux--M$Ki$q219SXb>}vD4tsuQkj0p=%VHruCFUl zexf{;YHVm~st5NMDjmNO3@|}A8gP~;Qr+jI)ni+q{n@hi?%B?|rB6Tgz0ZDd{C_*y zQRU=`Q^(S?&>uSox9psF?Xq+G2)eF5^J2#%19Rp+RTlh4RrB%QXMg*|)9-JW_r0`z zRa<@i+KSm{H*UBx@Z1e}hZ@NHQOG7Q)n-d9j)8js$UQ8>XYs(W3j+w9^H>Paq!A7F zS(FDlnB_)}$v$l-cVv z3$MSf^xo+YoqNY$LedSo?cSNU&VKVEGRWF_P@h&V=AQ zJBJ3j1038VWJ}ntNUz4|W&AqEn2cx^+s@(|Ad~~_1@;!p0;TL87J7#Al+r(*>8~Qq zRBsY6Yzc>Mnh&)Q76Gv!ECLxgs!YuU+9XSp8&B^B^klM5x( zI0(F6o9S%Da*1G}>>^ zsiaa`rJgd=RFjt0o6PytJZ-){&+Mc+v`)RlR1b596-+aLcpfkK$|r~-FUg7`8b!M9 z4+KrqpPg(OW+~Gmy{K!Xw^#asIw&YR06h$ZD3j&5nBO$~ep45DKIYfK)HP92ELAg9 zRnvKqGySZhsj#nDzsS<2ssM0v90r{>bzRdaE*uPo)rWbsl(Hxhu6}4X#iFGnmW2=s zg|cYh>4Ij5LyL1jgt>4iXD*rBJLjV*<-SjZM7AOQwfhaYXYq7C{AveEyh~OuU4l!? zrTf9Kv^jsp(BNa7I0{QwSPeApcL9d|46qh*Fsm?6`B!R-m;aAtj)2}mJ8Px zw&cdk)&#Oa4sJ`?0gbaqN+@tQ+tTl`q?4`Z`99C{dEj95Zoo#FQ-mXjc!M^|tr#|$ z0aQi;sK~G=B>;-yh>bz$t;}Lto%6hd4y5jnNyGwmA`1Y z5+ctJ1u|Fvv;8o605B=_a!&p9+wa`Tj4Ft?f)^NtP$d1x%i%(~P$@@cWVyZEQ7%-7 zrE;0V%1VwLjLYUuY#+XO2v%Wqb&Rf%5*Lj>gF%^Bk>+k4TF2oqRmc=@Q86q(Kvmc) zIP;D(?DMFUeG#`%oF^|s^;DyM1=k?f%gxlYcC$IGlh-L*sBO$PwuNf9ACpf~r|f^B z{%Y?Q&&rpnetW-oNgfNTb2t#xJ(A=kNpXsTfFwz9$%?|kvtfZFd4=VWO~Q(URg@gU z0rkK^VnN8^NjJ}vkmw|du_6dOPuPn*$O9_M;SC=1?P&3_9Cjz$!IEq{YCp1gG^g7Q z)^^yCYNalTl;9$R%_015&nH1Mr(?4QO>L!oeg1*eKne^?Ua9-^^&)+rln7H`iG zswZjhymuK>+)X9p)CB0HGmSkuC$#VaZt zQ&c!+S{SU@eJ^y64I~5Qrv%+CK6g~>z-1Z!GGgcE6;DBtuZD(j?0RO09xV1`cH-~x zA2M5;D{B{^%|kWc-^ARw(%LZ@WU6(0rUCn`zE^JO6d6NUqHQsPks*YP?EppRTWzk@ z{^s&KTsxSwx*J#{4Nh?dJ$bGY&vx`mcXy_NnbUH!yT!aWF?<;(fO1G;rV&C2P>X== zmr(zSox~nM*tH~fn_59|2}|}9?P%XI+>a1-=vnwN7%okSNRHI*)DNUbn~%LOv*0!K zzMsB&%MHI2$uywD)>Fg{jiO_WO(JoOK(dXd5k5eX`3%wO*tHPuI{1H{00m27`Y8>f z!(stX z!=_E<1o7~2Kc!I*5(PvV$~Ing2#%;<2t*5oXfz=_;3>!*e7`2^Y1S>>i@W))8AF_rRQ9M{UI;XRoxdG8;vKZ#Mmlo#@I*gkHwy}H^kQR zFY>4Oo5IbQt1K=eN-7G))rmp3Z*k$OLR_d7iIw6Gakn@u(!0er@tR1AqDHFic)#KG zwYW8nA*M#yi5kfjE|HcH`N2>-e%z2E1`(FRIpGQ6wlEzoPFM;blNXvn$6< zdMxcrZ?86%JUo8=_1l{#m7{Y7np99zG^6hE*^|~m1h+s0bx@N;WD{qNRz&m85M4@7 zrRhrjppJDtS1Zweq^;I>>b43c=}iV^dS?bw_LT5rXUhANK%@OBVYzdqcV(bM@8)~d z9{)d-tLjz%x7ioRA}Gq^f#BS&%1AXf=dLgr)Kfq>5Upo8c-qI6V=W+M{$$4oC9X~pTLWQ{a5XmWSj zfWkH3x2i{H;|2VGrwBcD7?oXaU5lj@VuAb!hefNF?X?Z zm2-oWbRtu%RTF?XYKb~xwN*1N64#-@I-MNgx~y@GPop@^iJT!ZHw*qnh>Ph^U4Tuh zG*76DK{`{(V5T@L-f2~@^Z@Lds^{iaTY!K}Kp1Em9B8s;70{|HQ6#~@lIp!Ppdi&0 zDdCFC=2-H>RAM@dOn#Vs?LbfFzfJ#q={JAV+x#0AZr#84=Z&wT&FZl(l#SR{gr9GF zJ8Q*LpMG`rlTDzkY2c*`pe&cAtPfaB3Hd@?cu1g2-KE+BJdb_EJy%~lFM+_xi-2e*E4eH1k=S_V1^mW z^xbTRWc*{|wWGqS830K^U6zKDz1B2gZg-_+CUvmXOlrvL5r=`yko&H*$nyHm4c|03 ze*Hq->qUo#a$1|$zWe@j>)+n;*2}lw*^S6;b0%Z))-)`C@!20w_I%L^KC6ao90SVo zfX~hwOLao?;Q3^VPC4dt_2deAm7|`sON4|Z9Fe=}TkabHrdY1<7i*K{n!sdjj=aeK zh_*z2IULxh=MYjj0BUf=yDu=2dEfRTy67nK1;+ zE2btim`q5Y%s#ho<#NZhgMG@Ta8YvQ&L>crEgZU{*3cUPD& z(;0g|?ON;I``vTCa}H)Rk@e29BHOl)gH1!RQsmObuocU2xX_x5{P%i`Kkd1j`3&oS z{Rlho!#hgni))UguX2lQ)0e&U{M&e$@2xHzgjrz2lQK6l_qEWu-VONJq1hYGFg^Bw zJT-$J`_P5t1YO3?z&8R@1Ia)`;3u}%?Qh$q9Q!1DN1!i20&I1Ya)R-E$tmiI@tFki+)Y9tnB9%Z=G})btT-2G1!Td})Z~#XESlgLG$EL;0 z%K%rvLqh#0z>lCy-oJf~7MG0&zL-k2FvOuv87hc#c)x60S-BfcF@ zY@&(5f=kW;=S}CBlLVcW&RUp?foSoLFe4=RVn#?1UW=3Ip;53j!%THkL#!sOs0vfe z=QDg+?JNRxaam^i!13so{(7FE=lXMM>Fga%hy4!R*l}&-*(bt=-P>px)!tA7v0=k$bfhI*Q7inoA zOQ06q9MmD24rC%)~4eAWR6Ie z(Pw1dY5%t{O8M{byA;k%L!NM4>K+@p;4X?ogd6FC>K3dEVe3Njhj4`wA`n_G&xP*L zuPJrPE`FzSmH(KEXDE))LeZ2e=ybW#UTa@YmeV?Mx!gqd2q)#s^bh1ubco&+|4Z*n zUbmtMJWn`EMOl{MM3y8|q`D|lo)A+|bU{!Q*m)vh*k6H)lBB9gA>G*7DNK~0BqJfq zzvQ%n^r$A{Oz?dOa!4)UEnu_X4$ocxRo`K-g3^qp7Gz@+VQht7dvb>vL0p*XKA*-AZS7hTS=sV~Xibmm%9z@6b zI>Qyf=DtpYl^dN}1j~=sca3)X+0FkvpPT(U zPA#|0Dx+gI=ZXMm{LbCXCVc5e=F|^_-iH@)N2W2omJ9C9tN;WY1Q?WC=swbe1Q4b2 z>2ZOHQ+!&sPA$pSiKbPPCQK!#5ER;kn*ynY!-&8Kg$AKn7!wFg6@}xogNFSlYvAO7 z0<|IB2R4*@V(O5`oQy`Zth9#jc55YU1qUIWep#KJjIxV%~OGbm_~8}nlfnORATAa$@gTy?FLOb}(88lYf!U3BU-*iskP*^DU{HoXPo--tx`GJ?O@@JD zK?z`kE#_vKYSTT1y3Lh~-FENzxMZ${t105%K+Kfz36-P*_eKRhG+sD~29*%D~r9u1$+2K~4EV}25nbcb%ZK~OL??26rCa}=nS zs;C%#)Ed9FkxW(mBYv*I-|p}5_xXvR=VD&tk+8V`Pgs28qVjnnn{+`|fMHBoV8lJv z6@$8DMN&kCr&^(lI&!g7aX)IG*d!-CSL^mE*yXSdEe+Mm7%sG9?RxCnY;M*;NPWXdfn0oz>ql(dX4m%dLoN>W^# z;htek^H*u}-1Ceof4xvIFV<4-l(E>qRoE)8)wa5~8f*Q#uveyneFeW%SgNeBZQ<7m z>y#}v#g|7!7eG!g5Lqic1!jDzh>@s?A+WY3HyP02dVrZ<`0OY^N%#r_8iz`9nDK>H zMTf!krbbh#sFgs6fe$PlF#5|&geCH7VYN(v;~uRXI)S{F7eP;YkvXSddjA?W_T78= zW@fmjv*l3dg%?{oIS(#+wJ~!${rh__;0f5?|6%`?_domq9^I1J_&>VKKDLSTj^oes z+@0^9$9KLr$M*R>wqrYX2sCj>lK?(m+CWl>fWbycSTrCkfff={UIwf|(1vytC}@I8 zol1d0r_vP)DS?SDT7iyLh-kcQbgDpV)=}1I)s*o^S&}_x18TL+vYxv~zLWg?UcSHY zhb^RW(WuM2YW`AG#wnAPdWFq~PlQn@Tr5TdWd&t{X@NE2Jz=5RUG1xL*ZGZ|2{=@5 z)W9tvB&CqD49ZrT8OFY3-$P{oqcH}T=)=i%Oa?m6c@_q^x5_q{yN`=cZGt>bWhnQg4kUBKN|thcjM(;NNDRdUUQ z^0X+~W9MoFTrc?M)wxF$1%|GXnc5daDhBqLFX(*9cpUV2bY3lN6i#-UT~I1cMy*4p zm|V3u&cwgz9UH+;I=bfZ%8Bn6^H{^ZsJap^#Sf@Ze?;h{3J7?U@vhO|(%WO%E| zdyp{gByu>=3I`$wXn58#H8&X3M|LNfh!@*NN4g42Zc7x~)`&F}_rx+{CR;1`oR?a2 ziMomPv5q8nz38U zzOSutk#u%P-5cK(3Szw~QWh-6B*Ef?))*Xn@u4vB+KuwA)0TNDlK+gxyVF|=C`R|(1gQ-TXH)4x6xMz>jrXo z?hvXL`&_9!*&ch9SjrCfg1}2j-&@otZLc@k`W-!UNtbl8YoS8`bF=7qe46X)6T!_A z{=D>W*qy4U71^R@m}9N$e7#fhk@VmQK8#@tjb*^|if-uJ9sLBs!447J@XlU;ZplaG zojuMPUOnHaWQ)ncr6d?3s!ZKFEJa=b^lCdkHvX> zXyasLt)QXi^uMf82d+0Jv?fsF)$iuI>?2q0R`Zpp$K>LQ;hoRa3Z0elk=RBwqX`CW>~N$WwIu%?ntT3AfVWy zbm=j*rgn`NvIsBcM6AcxEwAOCcVG3Zum+K6kMJ#Iy0C?yxEH{({dr4#w^O7}B0!8U z+26B7z2>~e)GRQAR?(M@alj>v2Bu8&NOVQK%s-uJeJ?V@)iTRoj0`o<75xc6qxdl5 z0==JByWeY{lvxUduM(W4Qh9`|$lj4$bgrQN?8ZZ-+caKg){kG3tD#XnWHKt17cZik zYp3X&#gnz?GL3ju=5o;Y-3ins!Ic)oVxTSHc|4pWY zwGfBwTtt+v%d|ktYrh?0(PtqV!$VzL)0;1hLg+5-a;n&86AR5sQl4zN3A2ruyYIkL zHYdn6{*>n7DLZaq-g7)5e#W|NAfhXoN}h<)mGk#Ayi9AH*Y3K|wKF&b+^E`IBQAY@ z!+YQ%nYws?B$h5CK$fnX%8&;VocunNLNiYDx{=e>nCm#B89%+WTN#8Q`IZS8ofK!a zO54<4q=YF+&Cdpk3ciIeZHQ?r=R*!z3Hk;q z(NYqmS9cy>2&`nW>r+*bv!+gf5uUQe%I zO0|?6)Xb$@WD?n!KljdIW_jdc2G=ziDdOs(F1t5L|ADZZKW6(t4#erMJEO zus$^T`{dylW2!BIdTpVU62T>IIBWH)lthsqnbcO-J*PzRZ6Tt`(WWo5cIN#jIqk6wm~AmR1Td$Bx_PoNBpsC%V&pyN!7g4L6?2dNI_oGE~;NwgIsrG6CCAk(81f*AYN`&E|InrphXsh;`l#5`Np@%7Nh>F*-GqvJ;; zjk9zX^6OT`F;^NUXW~S!^p`P#s;ycTy)B(Q!k60&m=C>>PR-1(T==lE`!mTSB^JXw6Qs0Rx~7_e z){9>#$c%8}jqSB83tpQWyO~9~cRn)P+J4jQPc?l_5Gk<-uh>CEi7stzE{U`)Z;IU* zd^UMuKHO9IGDd54jU-Gwk3@+`+3Lb`Vut2fDb!nC$6)^eC{Jc{v96A9#`XA@x|kT) zPYTa~LQV1~XXXv-!|Us7yZoQAAcoUKxkD6CU)q3+8qTuXC(rf*ZgEoF9OXXJa?Cb2S*&lx5{0PHZzw-lZFBChyoL+55E(oB8`fQk+ z#W}GUv8E=KP4Xa;C;w5X+6%AbbeZdV7HDm!pBNW8_qeNq-Ma~C`n)t zx1$_0n;bdT36l;)O2@Hvexj6~%X`|LvfRPuBLZqFVI(2`;K%OdTOu#5)(#d?(C?FH zH|Da6vb_9~snx=a@(G<&M2ksD#~um&WPI|C1*spSaLxz2ktlx^RKtg^K0BR8os855Vid)lj5m`YHu-tG5YLrT^Tsmgc7``Z%r>~YUm&JKW; z6sRLv%~p*|8S)a#@zb7c!o`m%s1#q@Fk}x!qNf%JU#szUHm$p5nq>3WOIUaLxamzd zWEKi7vE-AMJ^slw;pFaZ*(dbHLwzrPMt(tld955eML$3I<>^e$vg}lLxyHJP({LC? zOT(Ess2}HrZAy0&Y7y)smql~#tinQ?eC7#MgrM>XL*Mg~<`M92`)b2?J;~(5hAN2{TZQ$J2|4+$8C>Fz zs@U}#rwhyspXti48a`+-;V}_NhPYsf7R>@H8>E?L<1@S2;p`pb!Yj$X>v&|o!`eM|@ zGU3Wd%_3u+gB#r%qgXPNnd zQ;tPl9L~8^=DfyNH$DubpQ00@R><>SqF*{SfdgieW~LU*L+NN$D3yzDvkrE&B|Fr% zlsP}yw&7L)mHucIMTYxyau~!1B?Qy>(4V;C;_%cFluaamo7A!W>M1Xdry^cqa?H%t z8|qgI*>^6H64pS=Exrg!3a&A@r_AGPNBJ4vDgC3|Cnj0bU4svf zRVt`g_83T^iPe6o8ivVgJ>Q=fY`T7?Vu_Pdc)`>^2&>J)7QVMlo|Vo%@o1vh?1p`B z@A=)t^%m>~M~SE6%>C`p{tbxGH0^g^Oe=SE;Gbi5bD*kQ)AAApEp@0 zNx8P5QlQAX_k@q$5y&qRu%cyI%pokjk|5Z8bs|lsD1-I^nKvQb4MNSwQLnd8#+}~O+T)R`v42p1gP^a`=+RyO zx-+i`VOUZ-I^t`xu12i{`LU$>4|i;8_GZ)CSiKo>jsN+zM@>LNRJtWKcAlI~uF&!< zLC4$MH_6V4hxX32flr<%^}SV_%j!LGNdlhRkEddDp);o zntft2>-`)OtuoFiNmrLkW`|~Y^T-=6;ZK#MmG0~OGw))B(b=UUA#y>>-ZN4)k><{C z#>3*}lZb{At}}=ba((DHf9fd`MYz3aFyOV``!@gSx}Bw^jh?D%U0y0F*^?y&SM_f?ZsYC@@wtf54NKz%VA;eHpNLn?+SVubr(YISC zSNZ&vt|z%HTTn)&d#M!b{M3$V(XW&iJFR*zLc4+WUfXM8@I%6 zDt$BESEszmHjnR)X10_zLAvm;1(CAV3Nixol?jUfWu@GGq`_ar1bG)nMQuj_KMSm; zuPqI-fTIE8DsXrc1i22`CnMa};sXI3hy$MIp9}HtFS-Bky1VKiU}aqZ-HF86?)w4^ zoKOg)mZHqR>+OR01cU_sKYYdLP}keq&U6hP*blJ*AvrY&Dx(KEqyYkGcp%e>TPKxI z64J;h^^r)+k(`&8^UMh0>%llGXvoK0&q8FL?s1>*Al`t?&kE<$_4>!q3oFK`Tc&g_ zvn+3lY&tJ55092@#;g&xNJgJnxBXQ}L^#qdjkyL{30V0U|m}z~`EIomY&N zY%Hi=HOFv>{JU?g30VNDj7_bn60)-QjJJ1=ia?4%n2am<9WGkTJ}X0LR_z-@v}+D<2~(!6HCGo)?&e^(WV#oPHK}TuI^&ByJYA&tcXZk|d)ntbkbN4k z8@+{vh-|{_KC+zas|2g>DG8=J2(^M(YG@vR7qj*omFY9rs-)E<}YOw`Sc z^nGbQbqAMNZhOCN-GGQFj)-H7@ai4v=!arwh&;{^RZGL3l6?R%0e{iWIo~KP(oP_e zM#dY*WrqjAeW83DT<2G5M41O60yLd1NHweIZJH%3DwEp4dHy z+;ma7OtURV2=xq?y9Uxd6ZNdDHnWzvcCuErwxrg8=9#(tDw}*jhcaK#!!G#&nE}Ne zKgS5zO*i$FK&Hl@pHJXe4OEvv)Ipm8H?Ej+jIviGPS70o7TLVw%Elwe}A4~9y5RL;`3=a%4B3mSN>E!>%g+rtIiZF@GN67r?Ct; z;nLi~EU+G2XGOvdIOKw@pOpe@O{IQAUyE?vR^-$aZ40S7dB5hM=E|MchNE-$@bnf8aaWjk47+C#afQsku>}H zZ2L0Hc*)n~?>zTe_CR~0d&yog@_t?&X3y*H`!>_HUBg^U7YpL}LxK5d$boAH=^s}uL%@a=B6 ze|}euhQokEgxS0HNrtvN$f zomDM^WP`%4yi$)(HBUX2dhg|YM23b$C~4}IRE%0lSvx-7Y1~CrDJ%u6R`HUxG3~>a zEC-aI-Qn^Y*dXCe=$p6wLtiGoNc3wsm^tj=Y^RE6E;?vTL)Uy(on|DOUouqJR=C*ArzAYZPi`;Ypw+_91IJiL6*PF_1Ix=y%ugv`(CtcD=oQ zXPf<zn**Z&zts4 zxy-^W-mLg+x@_MZf*gF#eD0mxo;=mO>bJsgv+}RxN54Dw&ZmH|z_noIz191%LW9Cj zMJh$r#bU+pO0Jirma>*cmC=^HD5og*EZ?hetJtWttNc=BSv6U0T0K~!U(;24tG2aH zwXU&Vp}wX;x}l;`qOtUY=!c>v;imV^g3SdV1wOuO5omeWD%e`kCe&8gF4A87N&HiJ z$BmAvPPxwdF6FM~ZuRa@Jvu#oz5n!%^_ln0_M`j14mb_$4n7zn8S)uEGaNd?IFc~R zJ(@ixI94_;H~w)#dtz`BF}d*B;q&(?&uOaZ&>5DQ^jW^y(m92>_IacEsRg@*-7ilT z&n`wUaV_O9OD%s~(O;SRiu<~^>bJ(QmbwmGuinty82N_zw!7)G#jusOExg^Zqqj4& z>-?SUd-xCTAH_dae-7^*9TA#VIZ&>4(S90jez5@w!jXBL*OwMXrv1WY>st=BM!K6U@N?>B^-yxpy7B& z5EyHTwME*1z_@)Z7!}wNg*Hcm_(ecqdpy<==>SLpBAkdI2yBUi1HPdEO%7~^N28H| ztvTG%5{dhFZ*H~^l0%}=C_4v~0|<=7n8O{cfW7VE-U5vU8UcYVaBzepYCk|rJPLi# z0vc%nxchaAJHXvhfiWmsJmAO3VvEOHh4h}*Ft{vJR-oe2Y zs>9>s@`H8{ojBs)=12@22V}tl1^l3a4^*Rpbdf@t$^#lPvHps{>LH)4}uB< z-;W1c=KFMNAE`n1sE>-m+kRz9AI{EYz0RH0Uoq< zBnE~VR0Oya>BGVTOCPl?eY|X?59<*u{W~oHv2Y(?Ck^zB?C)sgkG#kqd67TvMgF(7 z@{ykMk)HA~J%C;JTT$K-C|&iV<~5G2G>)t^j#+^<{#E*A3{);2?TE5NyMn+PM|Gid zFo0>ck; z1qV7582pDl2L=jaeckGc7 z_Lvb+H2-S-wl+sOp@2sY7<-f`{E-9vkpui64)DJXU5^xiXTyG?Tz_2w-aN;i*Dg4u z1r-DYa2Tl||84;2Q9uBI6j@MF{3`0+g~#1KGku5J0|0Y0B^59Wl#|jfQ0#{ zj1LO?k3T*>VSpX^ryg(ypdf(_dOQ{gz_k2Z20e`Bn4SR8$lv}1_R)XLz+ivp4=Nx4JVgK269%}hf5`;-kLuu94g~pOf7c)INEZ6r z9}FTW{I?zqA_VYX|7-&|177Rdn~~C zg^t${@L~l>u{bJmabQM;azg@x5O~JgT3~^{JRVH@sK8oS;0*@MDGo@XU}ZTYadVgu zQivapfC6tgIhq6LP$Xf l0*Zv0iNHi8je+q`<=_aseGUdcOaRI+M0MqgyoLhR{{U{hcx3

System Loader + sharedLoader (shared)-> commonLoader -> System Loader + catalinaLoader(server) -> commonLoader -> System Loader + (by default the commonLoader is used for the + sharedLoader and the serverLoader) + b) Load startup class (reflection) + org.apache.catalina.startup.Catalina + setParentClassloader -> sharedLoader + Thread.contextClassloader -> catalinaLoader + c) Bootstrap.daemon.init() complete + +Sequence 2. Process command line argument (start, stop) +Class: org.apache.catalina.startup.Bootstrap (assume command->start) +What it does: + a) Catalina.setAwait(true); + b) Catalina.load() + b1) initDirs() -> set properties like + catalina.home + catalina.base == catalina.home (most cases) + b2) initNaming + setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, + org.apache.naming.java.javaURLContextFactory ->default) + b3) createStartDigester() + Configures a digester for the main server.xml elements like + org.apache.catalina.core.StandardServer (can change of course :) + org.apache.catalina.deploy.NamingResources + Stores naming resources in the J2EE JNDI tree + org.apache.catalina.LifecycleListener + implements events for start/stop of major components + org.apache.catalina.core.StandardService + The single entry for a set of connectors, + so that a container can listen to multiple connectors + ie, single entry + org.apache.catalina.Connector + Connectors to listen for incoming requests only + It also adds the following rulesets to the digester + NamingRuleSet + EngineRuleSet + HostRuleSet + ContextRuleSet + b4) Load the server.xml and parse it using the digester + Parsing the server.xml using the digester is an automatic + XML-object mapping tool, that will create the objects defined in server.xml + Startup of the actual container has not started yet. + b5) Assigns System.out and System.err to the SystemLogHandler class + b6) Calls initialize on all components, this makes each object register itself with the + JMX agent. + During the process call the Connectors also initialize the adapters. + The adapters are the components that do the request pre-processing. + Typical adapters are HTTP1.1 (default if no protocol is specified, + org.apache.coyote.http11.Http11NioProtocol) + AJP1.3 for mod_jk etc. + + c) Catalina.start() + c1) Starts the NamingContext and binds all JNDI references into it + c2) Starts the services under which are: + StandardService -> starts Engine (ContainerBase -> Realm,Cluster etc) + c3) StandardHost (started by the service) + Configures a ErrorReportValvem to do proper HTML output for different HTTP + errors codes + Starts the Valves in the pipeline (at least the ErrorReportValve) + Configures the StandardHostValve, + this valves ties the Webapp Class loader to the thread context + it also finds the session for the request + and invokes the context pipeline + Starts the HostConfig component + This component deploys all the webapps + (webapps & conf/Catalina/localhost/*.xml) + HostConfig will create a Digester for your context, this digester + will then invoke ContextConfig.start() + The ContextConfig.start() will process the default web.xml (conf/web.xml) + and then process the applications web.xml (WEB-INF/web.xml) + + c4) During the lifetime of the container (StandardEngine) there is a background thread that + keeps checking if the context has changed. If a context changes (timestamp of war file, + context xml file, web.xml) then a reload is issued (stop/remove/deploy/start) + + d) Tomcat receives a request on an HTTP port + d1) The request is received by a separate thread which is waiting in the ThreadPoolExecutor + class. It is waiting for a request in a regular ServerSocket.accept() method. + When a request is received, this thread wakes up. + d2) The ThreadPoolExecutor assigns the a TaskThread to handle the request. + It also supplies a JMX object name to the catalina container (not used I believe) + d3) The processor to handle the request in this case is Coyote Http11Processor, + and the process method is invoked. + This same processor is also continuing to check the input stream of the socket + until the keep alive point is reached or the connection is disconnected. + d4) The HTTP request is parsed using an internal buffer class (Http11InputBuffer) + The buffer class parses the request line, the headers, etc and store the result in a + Coyote request (not an HTTP request) This request contains all the HTTP info, such + as servername, port, scheme, etc. + d5) The processor contains a reference to an Adapter, in this case it is the + CoyoteAdapter. Once the request has been parsed, the Http11Processor + invokes service() on the adapter. In the service method, the Request contains a + CoyoteRequest and CoyoteResponse (null for the first time) + The CoyoteRequest(Response) implements HttpRequest(Response) and HttpServletRequest(Response) + The adapter parses and associates everything with the request, cookies, the context through a + Mapper, etc + d6) When the parsing is finished, the CoyoteAdapter invokes its container (StandardEngine) + and invokes the invoke(request,response) method. + This initiates the HTTP request into the Catalina container starting at the engine level + d7) The StandardEngine.invoke() simply invokes the container pipeline.invoke() + d8) By default the engine only has one valve the StandardEngineValve, this valve simply + invokes the invoke() method on the Host pipeline (StandardHost.getPipeLine()) + d9) the StandardHost has two valves by default, the StandardHostValve and the ErrorReportValve + d10) The standard host valve associates the correct class loader with the current thread + It also retrieves the Manager and the session associated with the request (if there is one) + If there is a session access() is called to keep the session alive + d11) After that the StandardHostValve invokes the pipeline on the context associated + with the request. + d12) The first valve that gets invoked by the Context pipeline is the FormAuthenticator + valve. Then the StandardContextValve gets invoke. + The StandardContextValve invokes any context listeners associated with the context. + Next it invokes the pipeline on the Wrapper component (StandardWrapperValve) + d13) During the invocation of the StandardWrapperValve, the JSP wrapper (Jasper) gets invoked + This results in the actual compilation of the JSP. + And then invokes the actual servlet. + e) Invocation of the servlet class diff --git a/test.dockerapp/tomcat/webapps/docs/balancer-howto.html b/test.dockerapp/tomcat/webapps/docs/balancer-howto.html new file mode 100644 index 0000000..9b18492 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/balancer-howto.html @@ -0,0 +1,61 @@ + +Apache Tomcat 8 (8.0.53) - Load Balancer HOW-TO

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/building.html b/test.dockerapp/tomcat/webapps/docs/building.html new file mode 100644 index 0000000..ac01610 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/building.html @@ -0,0 +1,278 @@ + +Apache Tomcat 8 (8.0.53) - Building Tomcat

Building Tomcat

Table of Contents

Introduction

+ +

+Building Apache Tomcat from source is very easy, and is the first step to +contributing to Tomcat. The complete and comprehensive instructions are +provided in the file BUILDING.txt. +The following is a quick step by step guide. +

+ +

Download a Java Development Kit (JDK) version 7

+ +

+Building Apache Tomcat requires a JDK (version 7) to be installed. You can download one from
+http://www.oracle.com/technetwork/java/javase/downloads/index.html
+http://openjdk.java.net/install/index.html
+or another JDK vendor. +

+ +

+IMPORTANT: Set an environment variable JAVA_HOME to the pathname of the +directory into which you installed the JDK release. +

+ +

Install Apache Ant 1.9.8 or later

+ +

+Download a binary distribution of Ant 1.9.8 or later from +here. +

+ +

+Unpack the binary distribution into a convenient location so that the +Ant release resides in its own directory (conventionally named +apache-ant-1.9.x). For the remainder of this guide, +the symbolic name ${ant.home} is used to refer to the full pathname of + the Ant installation directory. +

+ +

+IMPORTANT: Create an ANT_HOME environment variable to point the directory ${ant.home}, +and modify the PATH environment variable to include directory +${ant.home}/bin in its list. This makes the ant command line script +available, which will be used to actually perform the build. +

+ +

Checkout or obtain the Tomcat source code

+ +

+ Tomcat SVN repository URL: + https://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ +

+

+ Tomcat source packages: + https://tomcat.apache.org/download-80.cgi. +

+ +

+ Checkout the source using SVN, selecting a tag for released version or + trunk for the current development code, or download and unpack a + source package. For the remainder of this guide, the symbolic name + ${tomcat.source} is used to refer to the + location where the source has been placed. +

+ +

Configure download area

+ +

+ Building Tomcat involves downloading a number of libraries that it depends on. + It is strongly recommended to configure download area for those libraries. +

+ +

+ By default the build is configured to download the dependencies into the + ${user.home}/tomcat-build-libs directory. You can change this + (see below) but it must be an absolute path. +

+ +

+ The build is controlled by creating a + ${tomcat.source}/build.properties file. It can be used to + redefine any property that is present in build.properties.default + and build.xml files. The build.properties file + does not exist by default. You have to create it. +

+ +

+ The download area is defined by property base.path. For example: +

+ +
# ----- Default Base Path for Dependent Packages -----
+# Replace this path with the directory path where
+# dependencies binaries should be downloaded.
+base.path=/home/me/some-place-to-download-to
+ +

+ Different versions of Tomcat are allowed to share the same download area. +

+ +

+ Another example: +

+ +
base.path=${user.dir}/../libraries-tomcat8.0
+ +

+ Users who access the Internet through a proxy must use the properties + file to indicate to Ant the proxy configuration: +

+ +
# ----- Proxy setup -----
+proxy.host=proxy.domain
+proxy.port=8080
+proxy.use=on
+ +

Building Tomcat

+ +

+Use the following commands to build Tomcat: +

+ +

+cd ${tomcat.source}
+ant +

+ +

+Once the build has completed successfully, a usable Tomcat installation will have been +produced in the ${tomcat.source}/output/build directory, and can be started +and stopped with the usual scripts. +

+

Building with Eclipse

+ +

+IMPORTANT: This is not a supported means of building Tomcat; this information is +provided without warranty :-). +The only supported means of building Tomcat is with the Ant build described above. +However, some developers like to work on Java code with a Java IDE, +and the following steps have been used by some developers. +

+ +

+NOTE: This will not let you build everything under Eclipse; +the build process requires use of Ant for the many stages that aren't +simple Java compilations. +However, it will allow you to view and edit the Java code, +get warnings, reformat code, perform refactorings, run Tomcat +under the IDE, and so on. +

+ +

+WARNING: Do not forget to create and configure + ${tomcat.source}/build.properties file as described above + before running any Ant targets. +

+ +

+Sample Eclipse project files and launch targets are provided in the +res/ide-support/eclipse directory of the source tree. +The instructions below will automatically copy these into the required locations. +

+

+An Ant target is provided as a convenience to download all binary dependencies, and to create +the Eclipse project and classpath files in the root of the source tree. +

+ +

+cd ${tomcat.source}
+ant ide-eclipse +

+ +

+Start Eclipse and create a new Workspace. +

+ +

+Open the Preferences dialog and then select Java->Build Path->Classpath +Variables to add two new Classpath Variables: +

+ + + + + +
TOMCAT_LIBS_BASEThe same location as the base.path + setting in build.properties, where the binary dependencies have been downloaded
ANT_HOMEthe base path of Ant 1.9.8 or later
+ + +

+Use File->Import and choose Existing Projects into Workspace. +From there choose the root directory of the Tomcat source tree (${tomcat.source}) +and import the Tomcat project located there. +

+ +

+start-tomcat and stop-tomcat launch configurations are provided in +res/ide-support/eclipse and will be available in the Run->Run Configurations +dialog. Use these to start and stop Tomcat from Eclipse. +If you want to configure these yourself (or are using a different IDE) +then use org.apache.catalina.startup.Bootstrap as the main class, +start/stop etc. as program arguments, and specify -Dcatalina.home=... +(with the name of your build directory) as VM arguments. +

+ +

+Tweaking a few formatting preferences will make it much easier to keep consistent with Tomcat +coding conventions (and have your contributions accepted): +

+ + + + + + + + +
Java -> Code Style -> Formatter -> Edit...Tab policy: Spaces only
Tab and Indentation size: 4
General -> Editors -> Text EditorsDisplayed tab width: 2
Insert spaces for tabs
Show whitespace characters (optional)
XML -> XML Files -> EditorIndent using spaces
Indentation size: 2
Ant -> Editor -> FormatterTab size: 2
Use tab character instead of spaces: unchecked
+ +

+The recommended configuration of Compiler Warnings is documented in +res/ide-support/eclipse/java-compiler-errors-warnings.txt file. +

+ +

Building with other IDEs

+

+The same general approach should work for most IDEs; it has been reported +to work in IntelliJ IDEA, for example. +

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/cgi-howto.html b/test.dockerapp/tomcat/webapps/docs/cgi-howto.html new file mode 100644 index 0000000..04e7d44 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/cgi-howto.html @@ -0,0 +1,154 @@ + +Apache Tomcat 8 (8.0.53) - CGI How To

CGI How To

Table of Contents

Introduction

+ +

The CGI (Common Gateway Interface) defines a way for a web server to +interact with external content-generating programs, which are often +referred to as CGI programs or CGI scripts. +

+ +

Within Tomcat, CGI support can be added when you are using Tomcat as your +HTTP server and require CGI support. Typically this is done +during development when you don't want to run a web server like +Apache httpd. +Tomcat's CGI support is largely compatible with Apache httpd's, +but there are some limitations (e.g., only one cgi-bin directory). +

+ +

CGI support is implemented using the servlet class +org.apache.catalina.servlets.CGIServlet. Traditionally, +this servlet is mapped to the URL pattern "/cgi-bin/*".

+ +

By default CGI support is disabled in Tomcat.

+

Installation

+ +

CAUTION - CGI scripts are used to execute programs +external to the Tomcat JVM. If you are using the Java SecurityManager this +will bypass your security policy configuration in catalina.policy.

+ +

To enable CGI support:

+ +
    +
  1. There are commented-out sample servlet and servlet-mapping elements for +CGI servlet in the default $CATALINA_BASE/conf/web.xml file. +To enable CGI support in your web application, copy that servlet and +servlet-mapping declarations into WEB-INF/web.xml file of your +web application.

    + +

    Uncommenting the servlet and servlet-mapping in +$CATALINA_BASE/conf/web.xml file enables CGI for all installed +web applications at once.

    +
  2. + +
  3. Set privileged="true" on the Context element for your +web application.

    + +

    Only Contexts which are marked as privileged are allowed to use the +CGI servlet. Note that modifying the global $CATALINA_BASE/conf/context.xml +file affects all web applications. See +Context documentation for details.

    +
  4. +
+ +

Configuration

+ +

There are several servlet init parameters which can be used to +configure the behaviour of the CGI servlet.

+
    +
  • cgiPathPrefix - The CGI search path will start at +the web application root directory + File.separator + this prefix. +By default there is no value, which results in the web application root +directory being used as the search path. The recommended value is +WEB-INF/cgi
  • +
  • enableCmdLineArguments - Are command line parameters +generated from the query string as per section 4.4 of 3875 RFC? The default is +true.
  • +
  • environment-variable- - An environment to be set for the +execution environment of the CGI script. The name of variable is taken from the +parameter name. To configure an environment variable named FOO, configure a +parameter named environment-variable-FOO. The parameter value is used as the +environment variable value. The default is no environment variables.
  • +
  • executable - The name of the executable to be used to +run the script. You may explicitly set this parameter to be an empty string +if your script is itself executable (e.g. an exe file). Default is +perl.
  • +
  • executable-arg-1, executable-arg-2, +and so on - additional arguments for the executable. These precede the +CGI script name. By default there are no additional arguments.
  • +
  • envHttpHeaders - A regular expression used to select the +HTTP headers passed to the CGI process as environment variables. Note that +headers are converted to upper case before matching and that the entire header +name must match the pattern. Default is +ACCEPT[-0-9A-Z]*|CACHE-CONTROL|COOKIE|HOST|IF-[-0-9A-Z]*|REFERER|USER-AGENT +
  • +
  • parameterEncoding - Name of the parameter encoding +to be used with the CGI servlet. Default is +System.getProperty("file.encoding","UTF-8"). That is the system +default encoding, or UTF-8 if that system property is not available.
  • +
  • passShellEnvironment - Should the shell environment +variables from Tomcat process (if any) be passed to the CGI script? Default is +false.
  • +
  • stderrTimeout - The time (in milliseconds) to wait for +the reading of stderr to complete before terminating the CGI process. Default +is 2000.
  • +
+ +

The CGI script executed depends on the configuration of the CGI Servlet and +how the request is mapped to the CGI Servlet. The CGI search path starts at the +web application root directory + File.separator + cgiPathPrefix. The +pathInfo is then searched unless it is null - in +which case the servletPath is searched.

+ +

The search starts with the first path segment and expands one path segment +at a time until no path segments are left (resulting in a 404) or a script is +found. Any remaining path segments are passed to the script in the +PATH_INFO environment variable.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/changelog.html b/test.dockerapp/tomcat/webapps/docs/changelog.html new file mode 100644 index 0000000..e38c551 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/changelog.html @@ -0,0 +1,8612 @@ + +Apache Tomcat 8 (8.0.53) - Changelog

Changelog

Tomcat 8.0.53 (violetagg)

+

Catalina

+
    +
  • Fix: + Treat the <mapped-name> element of a + <env-entry> in web.xml in the same way as the + mappedName element of the equivalent @Resource + annotation. Both now attempt to set the mappedName property + of the resource. (markt) +
  • +
  • Fix: + Correct the processing of resources with + <injection-target>s defined in web.xml. First look + for a match using JavaBean property names and then, only if a match is + not found, look for a match using fields. (markt) +
  • +
  • Fix: + When restoring a saved request with a request body after FORM + authentication, ensure that calls to the HttpServletRequest + methods getRequestURI(), getQueryString() and + getProtocol() are not corrupted by the processing of the + saved request body. (markt) +
  • +
  • Fix: + JNDI resources that are defined with injection targets but no value are + now treated as if the resource is not defined. (markt) +
  • +
  • Fix: + Ensure that JNDI names used for <lookup-name> entries + in web.xml and for lookup elements of + @Resource annotations specify a name with an explicit + java: namespace. (markt) +
  • +
  • Code: + Refactor the org.apache.naming package to reduce duplicate + code. Duplicate code identified by the Simian tool. (markt) +
  • +
  • Fix: + 50019: Add support for <lookup-name>. + Based on a patch by Gurkan Erdogdu. (markt) +
  • +
  • Fix: + 60490: Various formatting and layout improvements for the + ErrorReportValve. Patch provided by Michael Osipov. (markt) +
  • +
  • Fix: + 62343: Make CORS filter defaults more secure. This is the fix + for CVE-2018-8014. (markt) +
  • +
  • Fix: + Ensure that the web application resources implementation does not + incorrectly cache results for resources that are only visible as class + loader resources. (markt) +
  • +
  • Fix: + Make all loggers associated with Tomcat provided Filters non-static to + ensure that log messages are not lost when a web application is + reloaded. (markt) +
  • +
  • Fix: + Correct the manifest for the annotations-api.jar. The JAR implements the + Common Annotations API 1.2 and the manifest should reflect that. (markt) +
  • +
  • Fix: + Switch to non-static loggers where there is a possibility of a logger + becoming associated with a web application class loader causing log + messages to be lost if the web application is stopped. (markt) +
  • +
  • Add: + 62389: Add the IPv6 loopback address to the default + internalProxies regular expression. Patch by Craig Andrews. + (markt) +
  • +
  • Fix: + In the RemoteIpValve and RemoteIpFilter, + correctly handle the case when the request passes through one or more + trustedProxies but no internalProxies. Based + on a patch by zhanhb. (markt) +
  • +
  • Fix: + Correct the logic in MBeanFactory.removeConnector() to + ensure that the correct Connector is removed when there are multiple + Connectors using different addresses but the same port. (markt) +
  • +
  • Fix: + Make JAASRealm mis-configuration more obvious by requiring + the authenticated Subject to include at least one Principal of a type + specified by userClassNames. (markt) +
  • +
  • Fix: + 62476: Use GMT timezone for the value of + Expires header as required by HTTP specification + (RFC 7231, 7234). (kkolinko) +
  • +
+
+

Coyote

+
    +
  • Fix: + Log an error message if the AJP connector detects the the reverse proxy + is sending AJP messages that are too large for the configured + packetSize. (markt) +
  • +
  • Fix: + Relax Host validation by removing the requirement that the final + component of a FQDN must be alphabetic. (markt) +
  • +
  • Fix: + 62371: Improve logging of Host validation failures. (markt) +
  • +
  • Fix: + Correctly handle a digest authorization header when the user name + contains an escaped character. (markt) +
  • +
  • Fix: + Correctly handle a digest authorization header when one of the hex + field values ends the header with in an invalid character. (markt) +
  • +
  • Fix: + Correctly handle an invalid quality value in an + Accept-Language header. (markt) +
  • +
  • Fix: + Improve IPv6 validation by ensuring that IPv4-Mapped IPv6 addresses do + not contain leading zeros in the IPv4 part. Based on a patch by Katya + Stoycheva. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 62080: Ensure that all reads of the current thread's context + class loader made by the UEL API and implementation are performed via a + PrivilegedAction to ensure that a + SecurityException is not triggered when running under a + SecurityManager. (mark) +
  • +
  • Fix: + 62350: Refactor + org.apache.jasper.runtime.BodyContentImpl so a + SecurityException is not thrown when running under a + SecurityManger and additional permissions are not required in the + catalina.policy file. This is a follow-up to the fix for + 43925. (kkolinko/markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Remove duplicate calls when creating a replicated session to reduce the + time taken to create the session and thereby reduce the chances of a + subsequent session update message being ignored because the session does + not yet exist. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + When decoding of path parameter failed, make sure to throw + DecodeException instead of throwing + ArrayIndexOutOfBoundsException. (kfujino) +
  • +
  • Fix: + Enable host name verification when using TLS with the WebSocket client. + (markt) +
  • +
+
+

Web applications

+ + + 62395: Clarify the meaning of the connector attribute + minSpareThreads in the documentation web application. + (markt) + + +
+

Tribes

+
    +
  • Fix: + Ensure that the correct default value is returned when retrieve unset + properties in McastService. (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + When logValidationErrors is set to true, the connection + validation error is logged as SEVERE instead of + WARNING. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + 62391: Remove references to javaw.exe as this + file is not required by Tomcat and the references prevent the use of the + Server JRE. (markt) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.17 to + pick up the latest Windows binaries built with APR 1.6.3 and OpenSSL + 1.0.2o. (markt) +
  • +
  • Update: + 62458: Update the internal fork of Commons Pool 2 to dfef97b + (2018-06-18) to pick up some bug fixes and enhancements. (markt) +
  • +
  • Update: + Update the internal fork of Commons DBCP 2 to 2.4.0. (markt) +
  • +
  • Update: + Support building with Java 9+ while preserving the Java 7 compatibility + at runtime (requires Ant 1.9.8 or later). (ebourg) +
  • +
  • Add: + Implement checksum checks when downloading dependencies that are used + to build Tomcat. (kkolinko) +
  • +
+
+

2018-05-08 Tomcat 8.0.52 (violetagg)

+

Catalina

+
    +
  • Fix: + Fix a rare edge case that is unlikely to occur in real usage. This edge + case meant that writing long streams of UTF-8 characters to the HTTP + response that consisted almost entirely of surrogate pairs could result + in one surrogate pair being dropped. (markt) +
  • +
  • Fix: + Register MBean when DataSource Resource + type="javax.sql.XADataSource". Patch provided by Masafumi Miura. + (csutherl) +
  • +
  • Fix: + 62297: Enable the CrawlerSessionManagerValve to + correctly handle bots that crawl multiple hosts and/or web applications + when the Valve is configured on a Host or an Engine. (fschumacher) +
  • +
  • Fix: + 62329: Correctly list resources in JAR files when directories + do not have dedicated entries. Patch provided by Meelis Müür. (markt) +
  • +
  • Add: + Collapse multiple leading / characters to a single + / in the return value of + HttpServletRequest#getContextPath() to avoid issues if the + value is used with HttpServletResponse#sendRedirect(). This + behaviour is enabled by default and configurable via the new Context + attribute allowMultipleLeadingForwardSlashInPath. (markt) +
  • +
  • Fix: + Improve handing of overflow in the UTF-8 decoder with supplementary + characters. (markt) +
  • +
+
+

Coyote

+
    +
  • Add: + Enable strict validation of the provided host name and port for all + connectors. Requests with invalid host names and/or ports will be + rejected with a 400 response. (markt) +
  • +
  • Fix: + Implement the requirements of RFC 7230 (and RFC 2616) that HTTP/1.1 + requests must include a Host header and any request that + does not must be rejected with a 400 response. (markt) +
  • +
  • Fix: + Implement the requirements of RFC 7230 that any HTTP/1.1 request that + specifies a host in the request line, must specify the same host in the + Host header and that any such request that does not, must + be rejected with a 400 response. This check is optional and disabled by + default. It may be enabled with the + allowHostHeaderMismatch attribute of the Connector. (markt) +
  • +
  • Fix: + Implement the requirements of RFC 7230 that any HTTP/1.1 request that + contains multiple Host headers is rejected with a 400 + response. (markt) +
  • +
  • Add: + 62273: Implement configuration options to work-around + specification non-compliant user agents (including all the major + browsers) that do not correctly %nn encode URI paths and query strings + as required by RFC 7230 and RFC 3986. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Enable ECJ version 4.7 and later to be used as a drop in replacement for + the ECJ version that ships with Apache Tomcat. (markt) +
  • +
  • Fix: + Enable Java 10 to be specified as a JSP source and/or target if a newer + ECJ version is used. (markt) +
  • +
  • Fix: + 62287: Do not rely on hash codes to test instances of + ValueExpressionImpl for equality. Patch provided by Mark + Struberg. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 62301: Correct a regression in the fix for 61491 + that didn't correctly handle a final empty message part in all + circumstances when using PerMessageDeflate. (markt) +
  • +
+
+

Other

+
    +
  • Fix: + Avoid warning when running under Cygwin when the + JAVA_ENDORSED_DIRS environment variable is not set. Patch + provided by Zemian Deng. (markt) +
  • +
+
+

2018-04-13 Tomcat 8.0.51 (violetagg)

+

Catalina

+
    +
  • Fix: + 51195: Avoid a false positive report of a web application + memory leak by clearing ObjectStreamClass$Caches of classes + loaded by the web application when the web application is stopped. + (markt) +
  • +
  • Fix: + Prevent Tomcat from applying gzip compression to content that is already + compressed with brotli compression. Based on a patch provided by burka. + (markt) +
  • +
  • Fix: + 62090: Null container names are not allowed. (remm) +
  • +
  • Fix: + 62104: Fix programmatic login regression as the + NonLoginAuthenticator has to be set for it to work (if no login method + is specified). (remm) +
  • +
  • Fix: + 62117: Improve error message in catalina.sh when + calling kill -0 <pid> fails. Based on a suggestion + from Mark Morschhaeuser. (markt) +
  • +
  • Fix: + 62118: Correctly create a JNDI ServiceRef using + the specified interface rather than the concrete type. Based on a + suggestion by Ángel Álvarez Páscua. (markt) +
  • +
  • Fix: + Fix for RequestDumperFilter log attribute. Patch provided + by Kirill Romanov via Github. (violetagg) +
  • +
  • Fix: + 62123: Avoid ConcurrentModificationException + when attempting to clean up application triggered RMI memory leaks on + web application stop. (markt) +
  • +
  • Fix: + 62168: When using the PersistentManager honor a + value of -1 for minIdleSwap and do not swap + out sessions to keep the number of active sessions under + maxActive. Patch provided by Holger Sunke. (markt) +
  • +
  • Fix: + 62172: Improve Javadoc for + org.apache.catalina.startup.Constants and ensure that the + constants are correctly used. (markt) +
  • +
  • Fix: + 62175: Avoid infinite recursion, when trying to validate + a session while loading it with PersistentManager. + (fschumacher) +
  • +
  • Fix: + Ensure that NamingContextListener instances are only + notified once of property changes on the associated naming resources. + (markt) +
  • +
  • Add: + 62224: Disable the forkJoinCommonPoolProtection + of the JreMemoryLeakPreventionListener when running on Java + 9 and above since the underlying JRE bug has been fixed. (markt) +
  • +
  • Fix: + 62263: Avoid a NullPointerException when the + RemoteIpValve processes a request for which no Context can + be found. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Correct off-by-one error in thread pool that allowed thread pools to + increase in size to one more than the configured limit. Patch provided + by usc. (markt) +
  • +
+
+

Web applications

+
    +
  • Add: + Work-around a known, non-specification compliant behaviour in some + versions of IE that can allow XSS when the Manager application generates + a plain text response. Based on a suggestion from Muthukumar Marikani. + (markt) +
  • +
  • Add: + Add document for FragmentationInterceptor. (kfujino) +
  • +
  • Add: + Document how the roles for an authenticated user are determined when the + CombinedRealm is used. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Ensure that SQLWarning has been cleared when connection + returns to the pool. (kfujino) +
  • +
  • Fix: + Ensure that parameters have been cleared when + PreparedStatement and/or CallableStatement are + cached. (kfujino) +
  • +
  • Fix: + Enable PoolCleaner to be started even if validationQuery + is not set. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update the build script so MD5 hashes are no longer generated for + releases as per the change in the ASF distribution policy. (markt) +
  • +
  • Fix: + 62164: Switch the build script to use TLS for downloads from + SourceForge and Maven Central to avoid failures due to HTTP to HTTPS + redirects. (markt) +
  • +
+
+

2018-02-13 Tomcat 8.0.50 (violetagg)

+

Catalina

+
    +
  • Fix: + Prevent a stack trace being written to standard out when running on Java + 10 due to changes in the LogManager implementation. (markt) +
  • +
  • Fix: + Avoid duplicate load attempts if one has been made already. (remm) +
  • +
  • Fix: + Avoid NPE in ThreadLocalLeakPreventionListener if there is no Engine. + (remm) +
  • +
  • Fix: + 62000: When a JNDI reference cannot be resolved, ensure that + the root cause exception is reported rather than swallowed. (markt) +
  • +
  • Fix: + 62036: When caching an authenticated user Principal in the + session when the web application is configured with the + NonLoginAuthenticator, cache the internal Principal object + rather than the user facing Principal object as Tomcat requires the + internal object to correctly process later authorization checks. (markt) +
  • +
  • Fix: + 62067: Correctly apply security constraints mapped to the + context root using a URL pattern of "". (markt) +
  • +
  • Fix: + When using Tomcat embedded, only perform Authenticator configuration + once during web application start. (markt) +
  • +
  • Fix: + Process all ServletSecurity annotations at web application + start rather than at servlet load time to ensure constraints are applied + consistently. (markt) +
  • +
  • Fix: + Minor optimization when calling class transformers. (rjung) +
  • +
+
+

Web applications

+
    +
  • Add: + 48672: Add documentation for the Host Manager web + application. Patch provided by Marek Czernek. (markt) +
  • +
+
+

Other

+
    +
  • Update: + Update the NSIS Installer used to build the Windows installer to version + 3.03. (kkolinko) +
  • +
+
+

2018-01-24 Tomcat 8.0.49 (violetagg)

+

Catalina

+
    +
  • Fix: + 47214: Use a loop to preload anonymous inner classes + when running under a SecurityManager, to be safe for + future changes in the code or using a different compiler. (kkolinko) +
  • +
  • Add: + 57619: Implement a small optimisation to how JAR URLs are + processed to reduce the storage of duplicate String objects in memory. + Patch provided by Dmitri Blinov. (markt) +
  • +
  • Fix: + 61916: Extend the AddDefaultCharsetFilter to add + a character set when the content type is set via + setHeader() or addHeader() as well as when it + is set via setContentType(). (markt) +
  • +
  • Fix: + 61999: maxSavePostSize set to 0 should disable saving POST + data during authentication. (remm) +
  • +
+
+

Coyote

+
    +
  • Fix: + 61886: Log errors on non-container threads at + DEBUG rather than INFO. The exception will be + made available to the application via the asynchronous error handling + mechanism. (markt) +
  • +
  • Fix: + 61932: Allow a call to AsyncContext.dispatch() + to terminate non-blocking I/O. (markt) +
  • +
  • Fix: + Fix NIO2 handshaking with a full input buffer. (remm) +
  • +
  • Fix: + 61993: Improve handling for ByteChunk and + CharChunk instances that grow close to the maximum size + allowed by the JRE. (markt) +
  • +
+
+

Jasper

+
    +
  • Add: + 43925: Add a new system property + (org.apache.jasper.runtime.BodyContentImpl.BUFFER_SIZE) to + control the size of the buffer used by Jasper when buffering tag bodies. + (markt) +
  • +
  • Fix: + 61854: When using sets and/or maps in EL expressions, ensure + that Jasper correctly parses the expression. Patch provided by Ricardo + Martin Camarero. (markt) +
  • +
  • Fix: + Improve the handling of methods with varargs in EL expressions. In + particular, the calling of a varargs method with no parameters now works + correctly. Based on a patch by Nitkalya (Ing) Wiriyanuparb. (markt) +
  • +
+
+

Web applications

+
    +
  • Add: + 61223: Add the mbeans-descriptors.dtd file to the custom + MBean documentation so users have a reference to use when constructing + mbeans-descriptors.xml files for custom components. (markt) +
  • +
  • Fix: + Partial fix for 61886. Ensure that multiple threads do not + attempt to complete the AsyncContext if an I/O error occurs + in the stock ticker example Servlet. (markt) +
  • +
  • Fix: + 61886: Prevent ConcurrentModificationException + when running the asynchronous stock ticker in the examples web + application. (markt) +
  • +
  • Fix: + 61886: Prevent NullPointerException and other + errors if the stock ticker example is running when the examples web + application is stopped. (markt) +
  • +
  • Fix: + 61910: Clarify the meaning of the allowLinking + option in the documentation web application. (markt) +
  • +
  • Add: + Add OCSP configuration information to the SSL How-To. Patch provided by + Marek Czernek. (markt) +
  • +
  • Fix: + 62006: Document the new JvmOptions9 command line + parameter for tomcat8.exe. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 61312: Prevent NullPointerExceptionn when using + the statement cache of connection that has been closed. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update the internal fork of Commons Pool 2 to 2.4.3. (markt) +
  • +
  • Update: + Update the internal fork of Commons DBCP 2 to 8a71764 (2017-10-18) to + pick up some bug fixes and enhancements. (markt) +
  • +
  • Update: + Update the internal fork of Commons FileUpload to 6c00d57 (2017-11-23) + to pick up some code clean-up. (markt) +
  • +
  • Update: + Update the internal fork of Commons Codec to r1817136 to pick up some + code clean-up. (markt) +
  • +
  • Fix: + The native source bundles (for Commons Daemon and Tomcat Native) are no + longer copied to the bin directory for the deploy target. They are now + only copied to the bin directory for the release target. (markt) +
  • +
+
+

2017-12-12 Tomcat 8.0.48 (violetagg)

+

Catalina

+
    +
  • Add: + When running under Java 9 or later, and the + urlCacheProtection option of the + JreMemoryLeakPreventionListener is enabled, use the API + added in Java 9 to only disable the caching for JAR URL connections. + (markt) +
  • +
  • Fix: + 61597: Extend the StandardJarScanner to scan + JARs on the module path when running on Java 9 and class path scanning + is enabled. (markt) +
  • +
  • Fix: + Fix the JMX descriptor for Wrapper.findInitParameter(). + (rjung) +
  • +
  • Fix: + 61601: Add support for multi-release JARs in JAR scanning and + web application class loading. (markt) +
  • +
  • Add: + Provide the SessionInitializerFilter that can be used to + ensure that an HTTP session exists when initiating a WebSocket + connection. Patch provided by isapir. (markt) +
  • +
  • Fix: + Avoid a possible NullPointerException when timing out + AsyncContext instances during shut down. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 61568: Avoid a potential SecurityException when + using the NIO2 connector and a new thread is added to the pool. (markt) +
  • +
  • Fix: + 61736: Improve performance of NIO connector when clients + leave large time gaps between network packets. Patch provided by Zilong + Song. (markt) +
  • +
  • Fix: + 61773: Fix a connection counting bug in the NIO2 connector + that meant connections using the non-blocking I/O features of the + Servlet API (which includes the WebSocket implementation on Tomcat + 8.0.x) were not removed from the current connection count. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 61816: Invalid expressions in attribute values or template + text should trigger a translation (compile time) error, not a run time + error. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 61604: Add support for authentication in the websocket + client. Patch submitted by J Fernandez. (remm) +
  • +
+
+

Web applications

+
    +
  • Fix: + Enable Javadoc to be built with Java 9. (markt) +
  • +
  • Fix: + 61603: Add XML filtering for the status servlet output where + needed. (remm) +
  • +
  • Fix: + Correct the description of how the CGI servlet maps a request to a + script in the CGI How-To. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Fix incorrect behavior that attempts to resend channel messages more + than the actual setting value of maxRetryAttempts. + (kfujino) +
  • +
  • Fix: + Ensure that the remaining Sender can send channel messages by avoiding + unintended ChannelException caused by comparing the number + of failed members and the number of remaining Senders. (kfujino) +
  • +
  • Fix: + Ensure that remaining SelectionKeys that were not handled by throwing a + ChannelException during SelectionKey processing are + handled. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + Improve the fix for 61439 and exclude the JPA, JAX-WS and EJB + annotations completely from the Tomcat distributions. (markt) +
  • +
  • Fix: + Improve handling of endorsed directories. The endorsed directory + mechanism will only be used if the JAVA_ENDORSED_DIRS + system property is explicitly set or if + $CATALINA_HOME/endorsed exists. When running on Java 9, any + such attempted use of the endorsed directory mechanism will trigger an + error and Tomcat will fail to start. (rjung) +
  • +
  • Code: + Refactoring in preparation for Java 9. Refactor to avoid using some + methods that will be deprecated in Java 9 onwards. (markt) +
  • +
  • Add: + 51496: When using the Windows installer, check if the + requested service name already exists and, if it does, prompt the user + to select an alternative service name. Patch provided by Ralph + Plawetzki. (markt) +
  • +
  • Fix: + Add necessary Java 9 configuration options to the startup scripts to + prevent warnings being generated on web application stop. (markt) +
  • +
  • Fix: + 61590: Enable service.bat to recognise when + JAVA_HOME is configured for a Java 9 JDK. (markt) +
  • +
  • Fix: + 61598: Update the Windows installer to search the new (as of + Java 9) registry locations when looking for a JRE. (markt) +
  • +
  • Add: + Add generation of a SHA-512 hash for release artifacts to the build + script. (markt) +
  • +
  • Fix: + 61658: Update MIME mappings for fonts to use + font/* as per RFC8081. (markt) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.16 to + pick up the latest Windows binaries built with APR 1.6.3 and OpenSSL + 1.0.2m. (markt) +
  • +
  • Update: + Update the NSIS Installer used to build the Windows installer to version + 3.02.1. (kkolinko) +
  • +
  • Update: + Update the Windows installer to use "The Apache Software Foundation" as + the Publisher when Tomcat is displayed in the list of installed + applications in Microsoft Windows. (kkolinko) +
  • +
  • Fix: + 61803: Remove outdated SSL information from the Security + documentation. (remm) +
  • +
+
+

2017-10-03 Tomcat 8.0.47 (violetagg)

+

Catalina

+
    +
  • Fix: + 60963: Add ExtractingRoot, a new + WebResourceRoot implementation that extracts JARs to the + work directory for improved performance when deploying packed WAR files. + (markt) +
  • +
  • Fix: + 61554: Exclude test files in unusual encodings and markdown + files intended for display in GitHub from RAT analysis. Patch provided + by Chris Thistlethwaite. (markt) +
  • +
  • Add: + 61189: Add the ability to set environment variables for + individual CGI scripts. Based on a patch by jm009. (markt) +
  • +
  • Fix: + 61210: When running under a SecurityManager, do not print a + warning about not being able to read a logging configuration file when + that file does not exist. (markt) +
  • +
  • Add: + 61280: Add RFC 7617 support to the + BasicAuthenticator. Note that the default configuration + does not change the existing behaviour. (markt) +
  • +
  • Fix: + 61424: Avoid a possible StackOverflowError when + running under a SecurityManager and using + Subject.doAs(). (markt) +
  • +
  • Add: + 61489: When using the CGI servlet, make the generation of + command line arguments from the query string (as per section 4.4 of RFC + 3875) optional. The feature is enabled by default for consistency with + previous releases. Based on a patch by jm009. (markt) +
  • +
  • Fix: + 61503: This corrects a potential regression in the fix for + 60940 with an alternative solution that adds the + JarEntry objects normally skipped by a + JarInputStream only if those entries exist. (markt) +
  • +
  • Fix: + 61542: Fix CVE-2017-12617 and prevent JSPs from being + uploaded via a specially crafted request when HTTP PUT was enabled. + (markt) +
  • +
  • Fix: + Use the correct path when loading the JVM logging.properties + file for Java 9. (rjung) +
  • +
+
+

Coyote

+
    +
  • Fix: + Fix possible race condition when setting IO listeners on an upgraded + connection. (remm) +
  • +
  • Fix: + 48655: Enable Tomcat to shutdown cleanly when using sendfile, + the APR/native connector and a multi-part download is in progress. + (markt) +
  • +
  • Fix: + 58244: Handle the case when OpenSSL resumes a TLS session + using a ticket and the full client certificate chain is not available. + In this case the client certificate without the chain will be presented + to the application. (markt) +
  • +
  • Fix: + Fix random SocketTimeoutExceptions when reading the request + InputStream. Based on a patch by Peter Major. (markt) +
  • +
  • Fix: + 60900: Avoid a NullPointerException in the APR + Poller if a connection is closed at the same time as new data arrives on + that connection. (markt) +
  • +
  • Add: + Add an option to reject requests that contain HTTP headers with invalid + (non-token) header names with a 400 response. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 61491: When using the permessage-deflate + extension, correctly handle the sending of empty messages after + non-empty messages to avoid the IllegalArgumentException. + (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Show connector cipher list in the manager web application in the + correct cipher order. (rjung) +
  • +
+
+

Tribes

+
    +
  • Fix: + To avoid unexpected session timeout notification from backup session, + update the access time when receiving the map member notification + message. (kfujino) +
  • +
  • Fix: + Add member info to the log message when the failure detection check + fails in TcpFailureDetector. (kfujino) +
  • +
  • Fix: + Avoid Ping timeout until the added map member by receiving + MSG_START message is completely started. (kfujino) +
  • +
  • Fix: + When sending a channel message, make sure that the Sender has connected. + (kfujino) +
  • +
  • Fix: + Correct the backup node selection logic that node 0 is returned twice + consecutively. (kfujino) +
  • +
  • Fix: + Fix race condition of responseMap in + RpcChannel. (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 61391: Ensure that failed queries are logged if the + SlowQueryReport interceptor is configured to do so and the + connection has been abandoned. Patch provided by Craig Webb. (markt) +
  • +
  • Fix: + 61425: Ensure that transaction of idle connection has + terminated when the testWhileIdle is set to + true and defaultAutoCommit is set to + false. Patch provided by WangZheng. (kfujino) +
  • +
  • Fix: + 61545: Correctly handle invocations of methods defined in the + PooledConnection interface when using pooled XA + connections. Patch provided by Nils Winkler. (markt) +
  • +
+
+

Other

+
    +
  • Fix: + 61439: Remove the Java Annotation API classes from + tomcat-embed-core.jar and package them in a separate JAR in the + embedded distribution to provide end users with greater flexibility to + handle potential conflicts with the JRE and/or other JARs. (markt) +
  • +
  • Fix: + 61441: Improve the detection of JAVA_HOME by the + daemon.sh script when running on a platform where Java has + been installed from an RPM. (rjung) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.14 to + pick up the latest Windows binaries built with APR 1.6.2 and OpenSSL + 1.0.2l. (markt) +
  • +
  • Fix: + Update fix for 59904 so that values less than zero are accepted + instead of throwing a NegativeArraySizeException. (remm) +
  • +
  • Fix: + 61563: Correct typos in Spanish translation. Patch provided by + Gonzalo Vásquez. (csutherl) +
  • +
  • Update: + 61599: Update to Commons Daemon 1.1.0 for improved Java 9 + support. (markt) +
  • +
+
+

2017-08-18 Tomcat 8.0.46 (violetagg)

+

Catalina

+
    +
  • Fix: + Additional permission for deleting files is granted to JULI as it is + required by FileHandler when running under a Security Manager. The + thread that cleans the log files is marked as daemon thread. + (violetagg) +
  • +
  • Fix: + 61229: Correct a regression in 8.0.44 that broke WebDAV + handling for resources with names that included a & + character. (markt) +
  • +
  • Fix: + 61232: When log rotation is disabled only one separator will + be used when generating the log file name. For example if the prefix is + catalina. and the suffix is .log then the log + file name will be catalina.log instead of + catalina..log. Patch provided by Katya Stoycheva. + (violetagg) +
  • +
  • Fix: + Performance improvements for service loader look-ups (and look-ups of + other class loader resources) when the web application is deployed in a + packed WAR file. (markt) +
  • +
  • Fix: + 61253: Add warn message when Digester.updateAttributes + throws an exception instead of ignoring it. (csutherl) +
  • +
  • Fix: + 61313: Make the read timeout configurable in the + JNDIRealm and ensure that a read timeout will result in an + attempt to fail over to the alternateURL. Based on patches by Peter + Maloney and Felix Schumacher. (markt) +
  • +
  • Add: + 61366: Add a new attribute, localDataSource, to + the JDBCStore that allows the Store to be configured to use + a DataSource defined by the web application rather than the default of + using a globally defined DataSource. Patch provided by Jonathan + Horowitz. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 61086: Ensure to explicitly signal an empty request body for + HTTP 205 responses. Additional fix to r1795278. Based on a patch + provided by Alexandr Saperov. (violetagg) +
  • +
  • Fix: + 61322: Correct two regressions caused by the fix for + 60319 when using BIO with an external Executor. Firstly, use + the maxThreads setting from the Executor as the default for + maxConnections if none is specified. Secondly, use + maxThreads from the Executor when calculating the point at + which to disable keep-alive. (markt) +
  • +
  • Fix: + Prevent exceptions being thrown during normal shutdown of NIO + connections. This enables TLS connections to close cleanly. (markt) +
  • +
+
+

Jasper

+
    +
  • Add: + 53031: Add support for the fork option when + compiling JSPs with the Jasper Ant task and javac. (markt) +
  • +
+
+

WebSocket

+
    +
  • Add: + 57767: Add support to the WebSocket client for following + redirects when attempting to establish a WebSocket connection. Patch + provided by J Fernandez. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Remove references to the Loader attribute + searchExternalFirst from the documentation since the + attribute is no longer supported. (markt) +
  • +
  • Fix: + Correct the documentation for how StandardRoot is + configured. (markt) +
  • +
+
+

Other

+
    +
  • Add: + 52791: Add the ability to set the defaults used by the + Windows installer from a configuration file. Patch provided by Sandra + Madden. (markt) +
  • +
+
+

2017-07-01 Tomcat 8.0.45 (violetagg)

+

Catalina

+
    +
  • Fix: + 61101: CORS filter should set Vary header in response. + Submitted by Rick Riemer. (remm) +
  • +
  • Add: + 61105: Add a new JULI FileHandler configuration for + specifying the maximum number of days to keep the log files. + (violetagg) +
  • +
  • Fix: + 61125: Ensure that WarURLConnection returns the + correct value for calls to getLastModified() as this is + required for the correct detection of JSP modifications when the JSP is + packaged in a WAR file. (markt) +
  • +
  • Fix: + Improve the SSLValve so it is able to handle client + certificate headers from Nginx. Based on a patch by Lucas Ventura Carro. + (markt) +
  • +
  • Fix: + 61154: Allow the Manager and Host Manager web applications to + start by default when running under a security manager. This was + accomplished by adding a custom permission, + org.apache.catalina.security.DeployXmlPermission, that + permits an application to use a META-INF/context.xml file + and then granting that permission to the Manager and Host Manager. + (markt) +
  • +
  • Fix: + 61173: Polish the javadoc for + o.a.catalina.startup.Tomcat. Patch provided by + peterhansson_se. (violetagg) +
  • +
  • Add: + A new configuration property crawlerIps is added to the + o.a.catalina.valves.CrawlerSessionManagerValve. Using this + property one can specify a regular expression that will be used to + identify crawlers based on their IP address. Based on a patch provided + by Tetradeus. (violetagg) +
  • +
  • Fix: + 61180: Log a warning message rather than an information + message if it takes more than 100ms to initialised a + SecureRandom instance for a web application to use to + generate session identifiers. Patch provided by Piotr Chlebda. (markt) +
  • +
  • Fix: + 61185: When an asynchronous request is dispatched via + AsyncContext.dispatch() ensure that + getRequestURI() for the dispatched request matches that of + the original request. (markt) +
  • +
  • Fix: + 61201: Ensure that the SCRIPT_NAME environment + variable for CGI executables is populated in a consistent way regardless + of how the CGI servlet is mapped to a request. (markt) +
  • +
  • Fix: + 61215: Correctly define addConnectorPort and + invalidAuthenticationWhenDeny in the + mbean-descriptors.xml file for the + org.apache.catalina.valves package so that the attributes + are accessible via JMX. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 61086: Explicitly signal an empty request body for HTTP 205 + responses. (markt) +
  • +
  • Fix: + Revert a change introduced in the fix for bug 60718 that + changed the status code recorded in the access log when the client + dropped the connection from 200 to 500. (markt) +
  • +
  • Fix: + Make asynchronous error handling more robust. In particular ensure that + onError() is called for any registered + AsyncListeners after an I/O error on a non-container + thread. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 44787: Improve error message when JSP compiler configuration + options are not valid. (markt) +
  • +
  • Fix: + 61137: j.s.jsp.tagext.TagLibraryInfo#uri and + j.s.jsp.tagext.TagLibraryInfo#prefix fields should not be + final. Patch provided by Katya Todorova. (violetagg) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Correct the log message when a MessageHandler for + PongMessage does not implement + MessageHandler.Whole. (rjung) +
  • +
  • Fix: + Improve thread-safety of Futures used to report the result + of sending WebSocket messages. (markt) +
  • +
  • Fix: + 61183: Correct a regression in the previous fix for + 58624 that could trigger a deadlock depending on the locking + strategy employed by the client code. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Better document the meaning of the trimSpaces option for Jasper. (markt) +
  • +
  • Fix: + 61150: Configure the Manager and Host-Manager web + applications to permit serialization and deserialization of + CRSFPreventionFilter related session objects to avoid warning messages + and/or stack traces on web application stop and/or start when running + under a security manager. (markt) +
  • +
+
+

Other

+
    +
  • Add: + 45832: Add HTTP DIGEST authentication support to the Catalina + Ant tasks used to communicate with the Manager application. (markt) +
  • +
  • Fix: + 45879: Add the RELEASE-NOTES file to the root of + the installation created by the Tomcat installer for Windows to make it + easier for users to identify the installed Tomcat version. (markt) +
  • +
  • Fix: + 61055: Clarify the code comments in the rewrite valve to make + clear that there are no plans to provide proxy support for this valve + since Tomcat does not have proxy capbilities. (markt) +
  • +
  • Fix: + 61076: Document the altDDName attribute for the + Context element. (markt) +
  • +
  • Fix: + Correct typo in Jar Scan Filter Configuration Reference. + Issue reported via comments.apache.org. (violetagg) +
  • +
  • Fix: + 61145: Add missing @Documented annotation to + annotations in the annotations API. Patch provided by Katya Todorova. + (markt) +
  • +
  • Fix: + 61146: Add missing lookup() method to + @EJB annotation in the annotations API. Patch provided by + Katya Todorova. (markt) +
  • +
  • Fix: + Correct typo in Context Container Configuration Reference. + Patch provided by Katya Todorova. (violetagg) +
  • +
+
+

2017-05-16 Tomcat 8.0.44 (violetagg)

+

General

+
    +
  • Add: + Allow to exclude JUnit test classes using the build property + test.exclude and document the property in + BUILDING.txt. (rjung) +
  • +
+
+

Catalina

+
    +
  • Fix: + 60940: Improve the handling of the META-INF/ and + META-INF/MANIFEST.MF entries for Jar files located in + /WEB-INF/lib when running a web application from a packed + WAR file. (markt) +
  • +
  • Fix: + Pre-load the ExceptionUtils class. Since the class is used + extensively in error handling, it is prudent to pre-load it to avoid any + failure to load this class masking the true problem during error + handling. (markt) +
  • +
  • Fix: + Review those places where Tomcat re-encodes a URI or URI component and + ensure that that correct encoding (path differs from query string) is + applied and that the encoding is applied consistently. (markt) +
  • +
  • Fix: + Use a more reliable mechanism for the DefaultServlet when + determining if the current request is for custom error page or not. + (markt) +
  • +
  • Fix: + Ensure that when the Default or WebDAV servlets process an error + dispatch that the error resource is processed via the + doGet() method irrespective of the method used for the + original request that triggered the error. (markt) +
  • +
  • Fix: + If a static custom error page is specified that does not exist or cannot + be read, ensure that the intended error status is returned rather than a + 404 or 403. (markt) +
  • +
  • Fix: + When the WebDAV servlet is configured and an error dispatch is made to a + custom error page located below WEB-INF, ensure that the + target error page is displayed rather than a 404 response. (markt) +
  • +
  • Add: + 61047: Add MIME mapping for woff2 fonts in the default + web.xml. Patch provided by Justin Williamson. (violetagg) +
  • +
  • Fix: + Correct the logic that selects the encoding to use to decode the query + string in the SSIServletExternalResolver so that the + useBodyEncodingForURI attribute of the + Connector is correctly taken into account. (markt) +
  • +
  • Fix: + 61072: Respect the documentation statements that allow + using the platform default secure random for session id generation. + (remm) +
  • +
  • Fix: + Correct the javadoc for + o.a.c.connector.CoyoteAdapter#parseSessionCookiesId. + Patch provided by John Andrew (XUZHOUWANG) via Github. (violetagg) +
  • +
+
+

Jasper

+
    +
  • Fix: + 60925: Improve the handling of access to properties defined + by interfaces when a BeanELResolver is used under a + SecurityManager. (markt) +
  • +
  • Update: + 61057: Update to Eclipse JDT Compiler 4.6.3. (violetagg) +
  • +
  • Fix: + 61065: Ensure that once the class is resolved by + javax.el.ImportHandler#resolveClass it will be cached with + the proper name. (violetagg) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 61003: Ensure the flags for reading/writing in + o.a.t.websocket.AsyncChannelWrapperSecure are correctly + reset even if some exceptions occurred during processing. (markt/violetagg) +
  • +
+
+

Web applications

+
    +
  • Add: + Document test.threads option in BUILDING.txt. + (kkolinko, rjung) +
  • +
  • Add: + Add documents for maxIdleTime attribute to Channel Receiver + docs. (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Code: + Refactor the creating a constructor for a proxy class to reduce + duplicate code. (kfujino) +
  • +
  • Fix: + In StatementFacade, the method call on the statements that + have been closed throw SQLException rather than + NullPointerException. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + Correct comments about Java 8 in Jre8Compat. + Patch provided by fibbers via Github. (violetagg) +
  • +
  • Fix: + 60932: Correctly escape single quotes when used in i18n + messages. Based on a patch by Michael Osipov. (markt) +
  • +
  • Fix: + Update the custom Ant task that integrates with the Symantec code + signing service to use the now mandatory 2-factor authentication. + (markt) +
  • +
+
+

2017-04-02 Tomcat 8.0.43 (violetagg)

+

Catalina

+
    +
  • Add: + 54618: Add support to the + HttpHeaderSecurityFilter for the HSTS preload parameter. + (markt) +
  • +
  • Fix: + 60876: Ensure that Set-Cookie headers generated + by the Rfc6265CookieProcessor are aligned with the + specification. Patch provided by Jim Griswold. (markt) +
  • +
  • Fix: + 60911: Ensure NPE will not be thrown when looking for SSL + session ID. Based on a patch by Didier Gutacker. (violetagg) +
  • +
+
+

Coyote

+
    +
  • Fix: + When using the NIO2 connector, ensure a WebSocket close frame is + processed before the end of stream is processed to ensure that the end + of stream is processed correctly. (markt) +
  • +
  • Fix: + 60852: Correctly spell compressible when used in + configuration attributes and internal code. Based on a patch by Michael + Osipov. (markt) +
  • +
  • Fix: + Improve sendfile handling when requests are pipelined. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Improve the error handling for simple tags to ensure that the tag is + released and destroyed once used. (remm, violetagg) +
  • +
  • Fix: + 60844: Correctly handle the error when fewer parameter values + than required by the method are used to invoke an EL method expression. + Patch provided by Daniel Gray. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 60764: Implement equals() and + hashCode() in the StatementFacade in order to + enable these methods to be called on the closed statements if any + statement proxy is set. This behavior can be changed with + useStatementFacade attribute. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + Refactor the build script and the NSIS installer script so that either + NSIS 2.x or NSIS 3.x can be used to build the installer. This is + primarily to re-enable building the installer on the Linux based CI + system where the combination of NSIS 3.x and wine leads to failed + installer builds. (markt) +
  • +
+
+

2017-03-14 Tomcat 8.0.42 (markt)

+

Catalina

+
    +
  • Update: + 60596: Improve performance of DefaultServlet when sendfile + feature is disabled on connector. (kkolinko) +
  • +
  • Fix: + Reduce the contention in the default InstanceManager + implementation when multiple threads are managing objects and need to + reference the annotation cache. (markt) +
  • +
  • Add: + Extend the JreMemoryLeakPreventionListener to provide + protection against ForkJoinPool.commonPool() related memory + leaks. (markt) +
  • +
  • Code: + 60674: Remove final marker from + CorsFilter to enable sub-classing. (markt) +
  • +
  • Fix: + 60683: Security manager failure causing NPEs when doing IO + on some JVMs. (csutherl) +
  • +
  • Fix: + 60688: Update the internal fork of Apache Commons BCEL to + r1782855 to add early access Java 9 support to the annotation scanning + code. (markt) +
  • +
  • Fix: + When HTTP TRACE requests are disabled on the Connector, ensure that the + HTTP OPTIONS response from the WebDAV servlet does not include + TRACE in the returned Allow header. (markt) +
  • +
  • Fix: + 60718: Improve error handling for asynchronous processing and + correct a number of cases where the requestDestroyed() + event was not being fired and an entry wasn't being made in the access + logs. (markt) +
  • +
  • Fix: + 60722: Take account of the + dispatchersUseEncodedPaths setting on the current + Context when generating paths for dispatches triggered + by AsyncContext.dispatch(). (markt) +
  • +
  • Fix: + 60728: Make the separator Tomcat uses in the Tomcat specific + war:file:... URL protocol customizable via a system + property. The separator is equivalent to the use of the ! + character in jar:file:... URLs. The default separator of + * remains unchanged. (markt) +
  • +
  • Fix: + 60798: Correct a bug in the handling of JARs in unpacked WARs + that meant multiple attempts to read the same entry from a JAR in + succession would fail for the second and subsequent attempts. (markt) +
  • +
  • Fix: + 60808: Ensure that the Map returned by + ServletRequest.getParameterMap() is fully immutable. Based + on a patch provided by woosan. (markt) +
  • +
  • Fix: + 60824: Correctly cache the Subject in the + session - if there is a session - when running under a + SecurityManager. Patch provided by Jan Engehausen. (markt) +
  • +
  • Fix: + Ensure request and response facades are used when firing application + listeners. (markt/remm) +
  • +
+
+

Coyote

+
    +
  • Fix: + Ensure that executor thread pools used with connectors pre-start the + configured minimum number of idle threads. (markt) +
  • +
  • Add: + 60594: Allow some invalid characters that were recently + restricted to be processed in requests by using the system property + tomcat.util.http.parser.HttpParser.requestTargetAllow. + (csutherl) +
  • +
  • Fix: + Modify the cookie header generated by the + Rfc6265CookieProcessor so it always sends an + Expires attribute as well as a Max-Age + attribute to avoid problems with Microsoft browsers that do not support + the Max-Age attribute. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Follow up to the fix for 58178. When creating the + ELContext for a tag file, ensure that any registered + ELContextListeners are fired. (markt) +
  • +
  • Fix: + Refactor code generated for JSPs to reduce the size of the code required + for tags. (markt) +
  • +
  • Update: + Update to the Eclipse JDT Compiler 4.6.1. (markt) +
  • +
+
+

Cluster

+
    +
  • Add: + Make the accessTimeout configurable in + ClusterSingleSignOn. The accessTimeout is used + as a timeout period for PING in replication map. (kfujino) +
  • +
  • Fix: + 60806: To avoid ClassNotFoundException, make + sure that the web application class loader is passed to + ReplicatedContext. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 60617: Correctly create a CONNECT request when + establishing a WebSocket connection via a proxy. Patch provided by + Svetlin Zarev. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Ensure that NoRpcChannelReply messages are not received on + RpcCallback. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.12 to + pick up the latest Windows binaries built with OpenSSL 1.0.2k. (violetagg) +
  • +
  • Add: + 60784: Update all unit tests that test the HTTP status line + to check for the required space after the status code. Patch provided by + Michael Osipov. (markt) +
  • +
  • Update: + Update the NSIS Installer used to build the Windows installer to version + 3.01. (markt) +
  • +
+
+

2017-01-24 Tomcat 8.0.41 (violetagg)

+

Cluster

+
    +
  • Add: + Make the accessTimeout configurable in + BackupManager. The accessTimeout is used as a + timeout period for PING in replication map. (kfujino) +
  • +
+
+

Web applications

+
    +
  • Fix: + Ensure the ASF logo image is displayed in host-manager. (violetagg) +
  • +
+
+

not released Tomcat 8.0.40 (violetagg)

+

Catalina

+
    +
  • Add: + 53602: Add HTTP status code 451 (RFC 7725) to the list of + HTTP status codes recognised by Tomcat. (markt) +
  • +
  • Fix: + 60446: Handle the case where the stored user credential uses + a different key length than the length currently configured for the + CredentialHandler. Based on a patch by Niklas Holm. (markt) +
  • +
  • Fix: + 60351: Delay creating META-INF/war-tracker file + until after the WAR has been expanded to address the case where the + Tomcat process terminates during the expansion. (markt) +
  • +
  • Fix: + Correctly handle the configClass attribute of a Host when + embedding Tomcat. (markt) +
  • +
  • Fix: + 60379: Dispose of the GSS credential once it is no longer + required. Patch provided by Michael Osipov. (markt) +
  • +
  • Fix: + 60380: Ensure that a call to + HttpServletRequest#logout() triggers a call to + TomcatPrincipal#logout(). Based on a patch by Michael + Osipov. (markt) +
  • +
  • Fix: + 60387: Correct the javadoc for + o.a.catalina.AccessLog.setRequestAttributesEnabled. + The default value is different for the different implementations. + (violetagg) +
  • +
  • Code: + 60393: Use consistent parameter naming in implementations of + Realm#authenticate(GSSContext, boolean). (markt) +
  • +
  • Fix: + 60395: Log when an Authenticator passes an + incomplete GSSContext to a Realm since it indicates a bug + in the Authenticator. Patch provided by Michael Osipov. + (markt) +
  • +
  • Fix: + Correctly generate URLs for resources located inside JARs that are + themselves located inside a packed WAR file. (markt) +
  • +
  • Fix: + 60410: Ensure that multiple calls to + JarInputStreamWrapper#close() do not incorrectly trigger + the closure of the underlying JAR or WAR file. (markt) +
  • +
  • Fix: + 60411: Implement support in the RewriteValve for + symbolic names to specify the redirect code to use when returning a + redirect response to the user agent. Patch provided by Michael Osipov. + (markt) +
  • +
  • Fix: + 60413: In the RewriteValve write empty capture + groups as the empty string rather than as "null" + when generating the re-written URL. Based on a patch by Michael Osipov. + (markt) +
  • +
  • Update: + Update the warnings that reference required options for running on Java + 9 to use the latest syntax for those options. (markt) +
  • +
  • Fix: + 60513: Fix thread safety issue with RMI cleanup code. (remm) +
  • +
+
+

Coyote

+
    +
  • Fix: + Ensure that the endpoint is able to unlock the acceptor thread during + shutdown if the endpoint is configured to listen to any local address + of a specific type such as 0.0.0.0 or ::. + (markt) +
  • +
  • Fix: + Prevent read time out when the file is deleted while serving the + response. The issue was observed only with APR Connector and + sendfile enabled. (violetagg) +
  • +
  • Fix: + Improve the logic that selects an address to use to unlock the Acceptor + to take account of platforms what do not listen on all local addresses + when configured with an address of 0.0.0.0 or + ::. (markt) +
  • +
  • Fix: + 60409: When unable to complete sendfile request, ensure the + Processor will be added to the cache only once. (markt/violetagg) +
  • +
+
+

Jasper

+
    +
  • Fix: + 60431: Improve handling of varargs in UEL expressions. Based + on a patch by Ben Wolfe. (markt) +
  • +
  • Fix: + 60497: Restore previous tag reuse behavior following the use + of try/finally. (remm) +
  • +
  • Fix: + Improve the error handling for simple tags to ensure that the tag is + released and destroyed once used. (remm) +
  • +
  • Fix: + 60497: Follow up fix using a better variable name for the + tag reuse flag. (remm) +
  • +
  • Fix: + Revert use of try/finally for simple tags. (remm) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct a typo in Host Configuration Reference. + Issue reported via comments.apache.org. (violetagg) +
  • +
  • Fix: + 60344: Add a note to BUILDING.txt regarding using the source + bundle with the correct line endings. (markt) +
  • +
  • Fix: + 60412: Add information on the comment syntax for the + RewriteValve configuration. (markt) +
  • +
  • Fix: + 60467: remove problematic characters from XML documentation. + Based upon a patch by Michael Osipov. (schultz) +
  • +
  • Add: + In the documentation web application, be explicit that clustering + requires a secure network for all of the cluster network traffic. + (markt) +
  • +
  • Update: + Update the ASF logos to the new versions. +
  • +
  • Fix: + 60468: Correct the format of the sample ISO-8601 date used + to report the build date for the documentation. Patch provided by + Michael Osipov. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Reduce the warning logs for a message received from a different domain + in order to avoid excessive log outputs. (kfujino) +
  • +
  • Add: + Add log message that PING message has received beyond the timeout + period. (kfujino) +
  • +
  • Fix: + When a PING message that beyond the time-out period has been received, + make sure that valid member is added to the map membership. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 60437: Avoid possible handshake overflows in the websocket + client. (remm) +
  • +
+
+

jdbc-pool

+
    +
  • Add: + 58816: Implement the statistics of jdbc-pool. The stats infos + are borrowedCount, returnedCount, + createdCount, releasedCount, + reconnectedCount, releasedIdleCount and + removeAbandonedCount. (kfujino) +
  • +
  • Fix: + 60194: If validationQuery is not specified, + connection validation is done by calling the isValid() + method. (kfujino) +
  • +
  • Fix: + 60398: Fix testcase of TestSlowQueryReport. + (kfujino) +
  • +
  • Add: + Enable reset the statistics without restarting the pool. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + 60366: Change catalina.bat to use directly + LOGGING_MANAGER and LOGGING_CONFIG variables + in order to configure logging, instead of modifying + JAVA_OPTS. Patch provided by Petter Isberg. (violetagg) +
  • +
  • Add: + New property is added test.verbose in order to control + whether the output of the tests is displayed on the console or not. + Patch provided by Emmanuel Bourg. (violetagg) +
  • +
  • Update: + Update the ASF logos used in the Apache Tomcat installer for Windows to + use the new versions. +
  • +
  • Fix: + Spelling corrections provided by Josh Soref. (violetagg) +
  • +
+
+

2016-11-14 Tomcat 8.0.39 (violetagg)

+

Catalina

+
    +
  • Fix: + When creating a new Connector via JMX, ensure that both HTTP/1.1 and + AJP/1.3 connectors can be created. (markt) +
  • +
  • Fix: + Include the Context name in the log message when an item cannot be + added to the cache. (markt) +
  • +
  • Fix: + Exclude JAR files in /WEB-INF/lib from the static resource + cache. (markt) +
  • +
  • Fix: + When calling getResourceAsStream() on a directory, ensure + that null is returned. (markt) +
  • +
  • Fix: + 60161: Allow creating subcategories of the container logger, + and use it for the rewrite valve. (remm) +
  • +
  • Fix: + Correctly test for control characters when reading the provided shutdown + password. (markt) +
  • +
  • Fix: + When configuring the JMX remote listener, specify the allowed types for + the credentials. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Correct the HTTP header parser so that DEL is not treated as a valid + token character. (markt) +
  • +
  • Fix: + 60319: When using an Executor, disconnect it from the + Connector attributes maxThreads, + minSpareThreads and threadPriority to enable + the configuration settings to be consistently reported. These Connector + attributes will be reported as -1 when an Executor is in + use. The values used by the executor may be set and obtained via the + Executor. (markt) +
  • +
  • Fix: + If an I/O error occurs during async processing on a non-container + thread, ensure that the onError() event is triggered. + (markt) +
  • +
  • Fix: + Improve detection of I/O errors during async processing on non-container + threads and trigger async error handling when they are detected. (markt) +
  • +
  • Add: + Add additional checks for valid characters to the HTTP request line + parsing so invalid request lines are rejected sooner. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct a typo in HTTP Connector How-To. + Issue reported via comments.apache.org. (violetagg) +
  • +
  • Fix: + Fix default value of validationInterval attribute in + jdbc-pool. (kfujino) +
  • +
  • Fix: + Correct a typo in CGI How-To. + Issue reported via comments.apache.org. (violetagg) +
  • +
+
+

Tribes

+
    +
  • Fix: + When the proxy node sends a backup retrieve message, ensure that using + the channelSendOptions that has been set rather than the + default channelSendOptions. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update the ECJ compiler to version 4.5.1. (markt) +
  • +
  • Fix: + Remove classes from tomcat-util-scan.jar that are duplicates of those in + tomcat-util.jar. (markt) +
  • +
  • Add: + Update the NSIS Installer used to build the Windows installer to version + 3.0. (markt) +
  • +
+
+

2016-10-10 Tomcat 8.0.38 (markt)

+

Catalina

+
    +
  • Add: + 59961: Add an option to the StandardJarScanner + to control whether or not JAR Manifests are scanned for additional + class path entries. (markt) +
  • +
  • Fix: + 60013: Refactor the previous fix to align the behaviour of + the Rewrite Valve with mod_rewrite. As part of this, provide an + implementation for the B and NE flags and + improve the handling for the QSA flag. Includes multiple + test cases by Santhana Preethiand a patch by Tiago Oliveira. (markt) +
  • +
  • Fix: + 60087: Refactor the web resources handling to use the Tomcat + specific war:file:... URL protocol to refer to WAR files + and their contents rather than the standard jar:file:... + form since some components of the JRE, such as JAR verification, give + unexpected results when the standard form is used. A side-effect of the + refactoring is that when using packed WARs, it is now possible to + reference a WAR and/or specific JARs within a WAR in the security policy + file used when running under a SecurityManager. (markt) +
  • +
  • Fix: + 60116: Fix a problem with the rewrite valve that caused back + references evaluated in conditions to be forced to lower case when using + the NC flag. (markt) +
  • +
  • Fix: + Ensure Digester.useContextClassLoader is considered in + case the class loader is used. (violetagg) +
  • +
  • Fix: + 60117: Ensure that the name of LogLevel is + localized when using OneLineFormatter. Patch provided by + Tatsuya Bessho. (kfujino) +
  • +
  • Fix: + 60146: Improve performance for resource retrieval by making + calls to WebResource.getInputStream() trigger caching if the resource is + small enough. Patch provided by mohitchugh. (markt) +
  • +
  • Add: + 60151: Improve the exception error messages when a + ResourceLink fails to specify the type, specifies an + unknown type or specifies the wrong type. (markt) +
  • +
  • Fix: + 60167: Ignore empty lines in /etc/passwd files + when using the PasswdUserDatabase. (markt) +
  • +
  • Fix: + 60170: Exclude the compressed test file + index.html.br from RAT analysis. Patch provided by Gavin + McDonald. (markt) +
  • +
  • Fix: + When starting web resources, ensure that class resources are only + started once. (markt) +
  • +
  • Fix: + Improve the access checks for linked global resources to handle the case + where the current class loader is a child of the web application class + loader. (markt) +
  • +
  • Fix: + 60199: Log a warning if deserialization issues prevent a + session attribute from being loaded. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Correctly handle a call to AsyncContext.complete() from a + non-container thread when non-blocking I/O is being used. (markt) +
  • +
  • Add: + Refactor the code that implements the requirement that a call to + complete() or dispatch() made from a + non-container thread before the container initiated thread that called + startAsync() completes must be delayed until the container + initiated thread has completed. Rather than implementing this by + blocking the non-container thread, extend the internal state machine to + track this. This removes the possibility that blocking the non-container + thread could trigger a deadlock. (markt) +
  • +
  • Fix: + 60123: Avoid potential threading issues that could cause + excessively large vales to be returned for the processing time of + a current request. (markt) +
  • +
  • Fix: + 60174: Log instances of HeadersTooLargeException + during request processing. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 60101: Remove preloading of the class that was deleted. + (violetagg) +
  • +
+
+

Web applications

+
    +
  • Add: + Expand the documentation for the nested elements within a + Resources element to clarify the behaviour of different + configuration options with respect to the order in which resources are + searched. (markt) +
  • +
  • Add: + Add an example of using the classesToInitialize attribute + of the JreMemoryLeakPreventionListener to the documentation + web application. Based on a patch by Cris Berneburg. (markt) +
  • +
  • Fix: + 60192: Correct a typo in the status output of the Manager + application. Patch provided by Radhakrishna Pemmasani. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Notify jmx when returning the connection that has been marked suspect. + (kfujino) +
  • +
  • Fix: + Ensure that the POOL_EMPTY notification has been added to + the jmx notification types. (kfujino) +
  • +
  • Fix: + 60099: Ensure that use all method arguments as a cache key + when using StatementCache. (kfujino) +
  • +
  • Fix: + 60139: Correct Javadocs for + PoolConfiguration.getValidationInterval and + setValidationInterval. Reported by Phillip Webb. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + Update the download location for Objenesis. (violetagg) +
  • +
  • Fix: + 60164: Replace log4j-core*.jar with + log4j-web*.jar since it is log4j-web*.jar that + contains the ServletContainerInitializer. (markt) +
  • +
  • Add: + Add documentation to the bin/catalina.bat script to remind users that + environment variables don't affect the configuration of Tomcat when + run as a Windows Service. Based upon a documentation patch by + James H.H. Lampert. (schultz) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.10 to + pick up the latest Windows binaries built with OpenSSL 1.0.2j. (markt) +
  • +
+
+

2016-09-05 Tomcat 8.0.37 (markt)

+

Catalina

+
    +
  • Fix: + 57705: Add debug logging for requests denied by the remote + host and remote address valves and filters. Based on a patch by Graham + Leggett. (markt) +
  • +
  • Add: + 59399: Add a new option to the Realm implementations that + ship with Tomcat that allows the HTTP status code used for HTTP -> HTTPS + redirects to be controlled per Realm. (markt) +
  • +
  • Update: + Change the default of the + sessionCookiePathUsesTrailingSlash attribute of the + Context element to false since the problems + caused when a Servlet is mapped to /* are more significant + than the security risk of not enabling this option by default. (markt) +
  • +
  • Fix: + Do not attempt to start web resources during a web application's + initialisation phase since the web application is not fully configured + at that point and the web resources may not be correctly configured. + (markt) +
  • +
  • Fix: + 59708: Modify the LockOutRealm logic. Valid authentication + attempts during the lock out period will no longer reset the lock out + timer to zero. (markt) +
  • +
  • Fix: + Improve error handling around user code prior to calling + InstanceManager.destroy() to ensure that the method is + executed. (markt) +
  • +
  • Fix: + 59813: Ensure that circular relations of the Class-Path + attribute from JAR manifests will be processed correctly. (violetagg) +
  • +
  • Fix: + Ensure that reading the singleThreadModel attribute of a + StandardWrapper via JMX does not trigger initialisation of + the associated servlet. With some frameworks this can trigger an + unexpected initialisation thread and if initialisation is not thread-safe + the initialisation can then fail. (markt) +
  • +
  • Fix: + Compatibility with rewrite from httpd for non existing headers. + (jfclere) +
  • +
  • Fix: + By default, treat paths used to obtain a request dispatcher as encoded. + This behaviour can be changed per web application via the + dispatchersUseEncodedPaths attribute of the Context. + (markt) +
  • +
  • Fix: + 59839: Apply roleSearchAsUser to all nested searches + in JNDIRealm. (fschumacher) +
  • +
  • Fix: + 59859: Fix resource leak in WebDAV servlet. Based on patch by + Coty Sutherland. (fschumacher) +
  • +
  • Add: + Provide a mechanism that enables the container to check if a component + (typically a web application) has been granted a given permission when + running under a SecurityManager without the current execution stack + having to have passed through the component. Use this new mechanism to + extend SecurityManager protection to the system property replacement + feature of the digester. (markt) +
  • +
  • Add: + When retrieving an object via a ResourceLink, ensure that + the object obtained is of the expected type. (markt) +
  • +
  • Fix: + 59824: Mark the RewriteValve as supporting async + processing by default. (markt) +
  • +
  • Fix: + 59862: Allow nested jar files scanning to be filtered with + the system property + tomcat.util.scan.StandardJarScanFilter.jarsToSkip. Patch + is provided by Terence Bandoian. (violetagg) +
  • +
  • Fix: + 59866: When scanning WEB-INF/classes for + annotations, don't scan the contents of + WEB-INF/classes/META-INF (if present) since classes will + never be loaded from that location. (markt) +
  • +
  • Fix: + 59888: Correctly handle tabs and spaces in quoted version one + cookies when using the Rfc6265CookieProcessor. (markt) +
  • +
  • Fix: + 59912: Fix an edge case in input stream handling where an + IOException could be thrown when reading a POST body. + (markt) +
  • +
  • Fix: + 59960: Fix Javadoc so it builds with Java 8. Patch by Coty + Sutherland. (markt) +
  • +
  • Fix: + 59966: Do not start the web application if the error page + configuration in web.xml is invalid. (markt) +
  • +
  • Fix: + Switch the CGI servlet to the standard logging mechanism and remove + support for the debug attribute. (markt) +
  • +
  • Fix: + Changes to the allowLinking attribute of a + StandardRoot instance now invalidate the cache if caching + is enabled. (markt) +
  • +
  • Add: + Add a new initialisation parameter, envHttpHeaders, to + the CGI Servlet to mitigate httpoxy + (CVE-2016-5388) by default and to provide a mechanism that can be + used to mitigate any future, similar issues. (markt) +
  • +
  • Add: + When adding and removing ResourceLinks dynamically, ensure + that the global resource is only visible via the + ResourceLinkFactory when it is meant to be. (markt) +
  • +
  • Fix: + 60008: When processing CORs requests, treat any origin with a + URI scheme of file as a valid origin. (markt) +
  • +
  • Fix: + Improve handling of exceptions during a Lifecycle events triggered by a + state transition. The exception is now caught and the component is now + placed into the FAILED state. (markt) +
  • +
  • Fix: + 60013: Fix encoding issues when using the RewriteValve with + UTF-8 query strings or UTF-8 redirect URLs. (markt) +
  • +
  • Fix: + 60022: Improve handling when a WAR file and/or the associated + exploded directory are symlinked into the appBase. (markt) +
  • +
  • Fix: + Fix a file descriptor leak when reading the global web.xml. (markt) +
  • +
  • Fix: + Consistently decode URL patterns provided via web.xml using the encoding + of the web.xml file where specified or UTF-8 where no explicit encoding + is specified. (markt) +
  • +
  • Fix: + Make timing attacks against the Realm implementations harder. (schultz) +
  • +
+
+

Coyote

+
    +
  • Fix: + Improve error handling around user code prior to calling + InstanceManager.destroy() to ensure that the method is + executed. (markt) +
  • +
  • Fix: + Extend synchronization for NIO2 writes to avoid + ConcurrentModificationException observed during testing. + (markt) +
  • +
  • Fix: + 59904: Add a limit (default 200) for the number of cookies + allowed per request. Based on a patch by gehui. (markt) +
  • +
  • Fix: + 59925: Correct regression in r1628368 and ensure that HTTP + separators are handled as configured in the + LegacyCookieProcessor. Patch provided by Kyohei Nakamura. + (markt) +
  • +
  • Fix: + OpenSSL now disables 3DES by default so reflect this when using OpenSSL + syntax to select ciphers. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Improve error handling around user code prior to calling + InstanceManager.destroy() to ensure that the method is + executed. (markt) +
  • +
  • Fix: + Improve the error handling for custom tags to ensure that the tag is + returned to the pool or released and destroyed once used. (markt) +
  • +
  • Fix: + 60032: Fix handling of method calls that use varargs within + EL value expressions. (markt) +
  • +
  • Fix: + Ignore engineOptionsClass and scratchdir when + running under a security manager. (markt) +
  • +
  • Fix: + Fixed StringIndexOutOfBoundsException. Based on a patch provided by + wuwen via Github. (violetagg) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Improve error handling around user code prior to calling + InstanceManager.destroy() to ensure that the method is + executed. (markt) +
  • +
  • Fix: + 59908: Ensure that a reason phrase is included in the close + message if a session is closed due to a timeout. (markt) +
  • +
+
+

Web Applications

+
    +
  • Fix: + Do not log an additional case of IOExceptions in the + error handler for the Drawboard WebSocket example when the root cause is + the client disconnecting since the logs add no value. (markt) +
  • +
  • Fix: + 59642: Mention the localDataSource in the + DataSourceRealm section of the Realm How-To. (markt) +
  • +
  • Fix: + Follow-up to the fix for 59399. Ensure that the new attribute + transportGuaranteeRedirectStatus is documented for all + Realms. Also document the NullRealm and + when it is automatically created for an Engine. (markt) +
  • +
  • Fix: + Fix the description of maxAge attribute in jdbc-pool doc. + This attribute works both when a connection is returned and when a + connection is borrowed. (kfujino) +
  • +
  • Fix: + 59774: Correct the prefix values in the + documented examples for configuring the AccessLogValve. + Patch provided by Mike Noordermeer. (markt) +
  • +
  • Fix: + 59868: Clarify the documentation for the Manager web + application to make clearer that the host name and IP address in the + server section are the primary host name and IP address. (markt) +
  • +
  • Fix: + MBeans Descriptors How-To is moved to + mbeans-descriptors-howto.html. Patch provided by Radoslav + Husar. (violetagg) +
  • +
  • Fix: + Update NIO Connector configuration documentation with an information + about socket.directSslBuffer. (violetagg) +
  • +
  • Fix: + 60034: Correct a typo in the Manager How-To page of the + documentation web application. (markt) +
  • +
+
+

Tribes

+
    +
  • Add: + Add log message when the ping has timed-out. (kfujino) +
  • +
  • Fix: + If the ping message has been received at the + AbstractReplicatedMap#leftOver method, ensure that notify + the member is alive than ignore it. (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Fix the duplicated connection release when connection verification + failed. (kfujino) +
  • +
  • Fix: + Ensure that do not remove the abandoned connection that has been already + released. (kfujino) +
  • +
  • Fix: + In order to avoid the unintended skip of PoolCleaner, + remove the check code of the execution interval in the task that has + been scheduled. (kfujino) +
  • +
  • Fix: + 59850: Ensure that the ResultSet is closed when + enabling the StatementCache interceptor. (kfujino) +
  • +
  • Fix: + 59923: Reduce the default value of + validationInterval in order to avoid the potential issue + that continues to return an invalid connection after database restart. + (kfujino) +
  • +
  • Fix: + Ensure that the ResultSet is returned as Proxy object when + enabling the StatementDecoratorInterceptor. (kfujino) +
  • +
  • Fix: + 60043: Ensure that the suspectTimeout works + without removing connection when the removeAbandoned is + disabled. (kfujino) +
  • +
  • Fix: + Add log message of when returning the connection that has been marked + suspect. (kfujino) +
  • +
  • Fix: + Correct Javadoc for ConnectionPool.suspect(). Based on a + patch by Yahya Cahyadi. (markt) +
  • +
+
+

Other

+
    +
  • Update: + 59276: Update optional Checkstyle library to 6.17. (kkolinko) +
  • +
  • Add: + Use the mirror network rather than the ASF master site to download the + current ASF dependencies. (markt) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.8 to + pick up the latest fixes and make 1.2.8 the minimum recommended version. + (markt) +
  • +
  • Fix: + 59899: Update Tomcat's copy of the Java Persistence + annotations to include the changes made in 2.1 / JavaEE 7. (markt) +
  • +
  • Fix: + Fixed typos in mbeans-descriptors.xml files. (violetagg) +
  • +
  • Update: + Update the internal fork of Commons BCEL to r1757132 to align with the + BCEL 6 release. (markt) +
  • +
  • Update: + Update the internal fork of Commons DBCP2 to r1757164 to pick up a + couple of bug fixes. (markt) +
  • +
  • Update: + Update the internal fork of Commons Codec to r1757174. Code formatting + changes only. (markt) +
  • +
  • Update: + Update the internal fork of Commons FileUpload to afdedc9. This pulls in + a fix to improve the performance with large multipart boundaries. + (markt) +
  • +
+
+

2016-06-13 Tomcat 8.0.36 (markt)

+

Catalina

+
    +
  • Fix: + RMI Target related memory leaks are avoidable which makes them an + application bug that needs to be fixed rather than a JRE bug to work + around. Therefore, start logging RMI Target related memory leaks on web + application stop. Add an option that controls if the check for these + leaks is made. Log a warning if running on Java 9 with this check + enabled but without the command line option it requires. (markt) +
  • +
  • Fix: + Ensure NPE will not be thrown during deployment when scanning jar files + without MANIFEST.MF file. (violetagg) +
  • +
  • Fix: + 59604: Correct the assumption made in the URL decoding that + the default platform encoding is always compatible with ISO-8859-1. This + assumption is not always valid, e.g. on z/OS. (markt) +
  • +
  • Fix: + 59608: Skip over any invalid Class-Path attribute + from JAR manifests. Log errors at debug level due to many bad libraries. + (remm) +
  • +
  • Fix: + Fix error message when failed to register MBean. (kfujino) +
  • +
+
+

Coyote

+
    +
  • Fix: + Ensure that requests with HTTP method names that are not tokens (as + required by RFC 7231) are rejected with a 400 response. (markt) +
  • +
  • Fix: + When an asynchronous request is processed by the AJP connector, ensure + that request processing has fully completed before starting the next + request. (markt) +
  • +
  • Fix: + If an async dispatch results in the completion of request processing, + ensure that any remaining request body is swallowed before starting the + processing of the next request else the remaining body may be read as the + start of the next request leading to a 400 response. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 59567: Fix NPE scanning webapps for TLDs when an exploded + JAR has an empty WEB-INF/classes/META-INF folder. (remm) +
  • +
  • Fix: + Fix a memory leak in the expression language implementation that caused + the class loader of the first web application to use expressions to be + pinned in memory. (markt) +
  • +
  • Fix: + 59640: NPEs with not found TLDs. (remm) +
  • +
  • Fix: + 59654: Improve error message when attempting to use a TLD + file from an invalid location. Patch provided by Huxing Zhang. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + 58891: Update the SSL how-to. Based on a suggestion by + Alexander Kjäll. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Fix a memory leak with the pool cleaner thread that retained a reference + to the web application class loader for the first web application to use + a connection pool. (markt) +
  • +
+
+

Other

+
    +
  • Update: + Update the internal fork of Commons DBCP 2 to r1743696 (2.1.1 plus + additional fixes). (markt) +
  • +
  • Update: + Update the internal fork of Commons Pool 2 to r1743697 (2.4.2 plus + additional fixes). (markt) +
  • +
  • Update: + Update the internal fork of Commons File Upload to r1743698 (1.3.1 plus + additional fixes). (markt) +
  • +
  • Update: + Update the option code coverage tool Cobertura to 2.1.1 so it is easier + to compare the change in lines of code between 8.0.x and 9.0.x. (markt) +
  • +
  • Fix: + 58626: Add support for a new environment variable + (USE_NOHUP) that causes nohup to be used when + starting Tomcat. It is disabled by default except on HP-UX where it is + enabled by default since it is required when starting Tomcat at boot on + HP-UX. (markt) +
  • +
+
+

2016-05-16 Tomcat 8.0.35 (markt)

+

Catalina

+
    +
  • Fix: + Ensure that annotated web components packed in web fragments will be + processed when unpackWARs is enabled. (violetagg) +
  • +
+
+

not released Tomcat 8.0.34 (markt)

+

Catalina

+
    +
  • Fix: + 59206: Ensure NPE will not be thrown by + o.a.tomcat.util.file.ConfigFileLoader when + catalina.base is not specified. (violetagg) +
  • +
  • Fix: + 59217: Remove duplication in the recycling of the path in + o.a.tomcat.util.http.ServerCookie. Patch is provided by + Kyohei Nakamura. (violetagg) +
  • +
  • Fix: + 59213: Async dispatches should be based off a wrapped + request. (remm) +
  • +
  • Fix: + Ensure that javax.servlet.ServletRequest and + javax.servlet.ServletResponse provided during + javax.servlet.AsyncListener registration are made + available via javax.servlet.AsyncEvent.getSuppliedRequest + and javax.servlet.AsyncEvent.getSuppliedResponse + (violetagg) +
  • +
  • Fix: + 59219: Ensure AsyncListener.onError() is called + if an Exception is thrown during async processing. (markt) +
  • +
  • Fix: + 59220: Ensure that AsyncListener.onComplete() is + called if the async request times out and the response is already + committed. (markt) +
  • +
  • Fix: + 59226: Process the Class-Path attribute from + JAR manifests for JARs on the class path excluding JARs packaged in + WEB-INF/lib. (markt) +
  • +
  • Fix: + 59255: Fix possible NPE in mapper. (kkolinko/remm) +
  • +
  • Fix: + 59256: slf4j-taglib*.jar should not be excluded + from the standard JAR scanning by default. (violetagg) +
  • +
  • Fix: + Clarify in the log message that specifying both urlPatterns and value + attributes in WebServlet and WebFilter annotations is not allowed. + (violetagg) +
  • +
  • Fix: + Ensure the exceptions caused by Valves will be available in the log + files so that they can be evaluated when + o.a.catalina.valves.ErrorReportValve.showReport is + disabled. Patch is provided by Svetlin Zarev. (violetagg) +
  • +
  • Fix: + Fix handling of Cluster Receiver in StoreConfig. The bind + and host attributes define as + TransientAttribute. (kfujino) +
  • +
  • Fix: + 59261: ServletRequest.getAsyncContext() now + throws an IllegalStateException as required by the Servlet + specification if the request is not in asynchronous mode when called. + (markt) +
  • +
  • Fix: + 59269: Correct the implementation of + PersistentManagerBase so that minIdleSwap + functions as designed and sessions are swapped out to keep the active + session count below maxActiveSessions. (markt) +
  • +
  • Fix: + 59247: Preload ResourceEntry as a workaround for security + manager issues on some JVMs. (kkolinko/remm) +
  • +
  • Fix: + Correctly configure the base path for a resources directory provided by + an expanded JAR file. Patch provided by hengyunabc. (markt) +
  • +
  • Fix: + Ensure that /WEB-INF/classes is never processed as a web + fragment. (markt) +
  • +
  • Fix: + 59310: Do not add a Content-Length: 0 header for + custom responses to HEAD requests that do not set a + Content-Length value. (markt) +
  • +
  • Add: + Make a web application's CredentialHandler available through a context + attribute. This allows a web application to use the same algorithm + for validating or generating new stored credentials from cleartext + ones. (schultz) +
  • +
  • Fix: + When normalizing paths, improve the handling when paths end with + /. or /.. and ensure that input and output are + consistent with respect to whether or not they end with /. + (markt) +
  • +
  • Fix: + 59317: Ensure that + HttpServletRequest.getRequestURI() returns an encoded URI + rather than a decoded URI after a dispatch. (markt) +
  • +
  • Fix: + Use the correct URL for the fragment when reporting errors processing + a web-fragment.xml file from a JAR located in an unpacked + WAR. (markt) +
  • +
  • Fix: + Ensure that JarScanner only uses the explicit call-back to + process WEB-INF/classes and only when configured to treat + the contents of WEB-INF/classes as a possible exploded JAR. + (markt) +
  • +
  • Code: + Remove the java2DDisposerProtection option from the + JreMemoryLeakPreventionListener. The leak is fixed in Java + 7 onwards and Tomcat 8 requires Java 7 so the option is unnecessary. + (markt) +
  • +
  • Fix: + Ensure that the value for the header X-Frame-Options is + constructed correctly according to the specification when + ALLOW-FROM option is used. (violetagg) +
  • +
  • Fix: + 59449: In ContainerBase, ensure that the process + to remove a child container is the reverse of the process to add one. + Patch provided by Huxing Zhang. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + When running on Java 7, exclude DHE ciphers from the default cipher list + for JSSE connectors since they use weak 768 bit DH keys and cannot be + configured to use more secure keys. (markt) +
  • +
  • Add: + Add a new environment variable JSSE_OPTS that is intended + to be used to pass JVM wide configuration to the JSSE implementation. + The default value is -Djdk.tls.ephemeralDHKeySize=2048 + which protects against weak Diffie-Hellman keys with Java 8. (markt) +
  • +
  • Update: + Exclude ciphers that use RSA keys from the default cipher list since + they do not support forward secrecy. (markt) +
  • +
  • Fix: + 58970: Fix a connection counting bug in the NIO connector + that meant some dropped connections were not removed from the current + connection count. (markt) +
  • +
  • Fix: + 59289: Do not recycle upgrade processors in unexpected close + situations. (remm) +
  • +
  • Fix: + 59295: Use Locale.toLanguageTag() to construct + the Content-Language HTTP header to ensure the locale is + correctly represented. Patch provided by zikfat. (markt) +
  • +
  • Fix: + 59451: Correct Javadoc for MessageBytes. Patch + provided by Kyohei Nakamura. (markt) +
  • +
  • Fix: + 59450: Correctly handle the case where the + LegacyCookieProcessor is configured with + allowHttpSepsInV0 set to false and + forwardSlashIsSeparator set to true. Patch + provided by Kyohei Nakamura. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + When scanning JARs for TLDs, correctly handle the (rare) case where a + JAR has been exploded into WEB-INF/classes and the web + application is deployed as a packed WAR. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Ensure that a client disconnection triggers the error handling for the + associated WebSocket end point. (markt) +
  • +
  • Add: + Make WebSocket client more robust when handling errors during the close + of a WebSocket session. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Update in the documentation the link to the maven repository where + Tomcat snapshot artifacts are deployed. (markt/violetagg) +
  • +
  • Fix: + Clarify in the documentation that calls to + ServletContext.log(String, Throwable) or + GenericServlet.log(String, Throwable) are logged at the + SEVERE level. (violetagg) +
  • +
  • Fix: + Correct a typo in SSL/TLS Configuration How-To. + Issue reported via comments.apache.org. (violetagg) +
  • +
+
+

Tribes

+
    +
  • Fix: + Avoid NPE when a proxy node failed to retrieve a backup entry. (kfujino) +
  • +
  • Add: + Add log of when received an unexpected messages. (kfujino) +
  • +
  • Add: + Add the flag indicating that member is a localMember. (kfujino) +
  • +
  • Fix: + Fix potential NPE that depends on the setting order of attributes of + static member when using the static cluster. (kfujino) +
  • +
  • Add: + Add get/set method for the channel that is related to + ChannelInterceptorBase. (kfujino) +
  • +
  • Fix: + As with the multicast cluster environment, in the static cluster + environment, the local member inherits properties from the cluster + receiver. (kfujino) +
  • +
  • Add: + Add get/set method for the channel that is related to each Channel + services. (kfujino) +
  • +
  • Add: + Add name to channel in order to identify channels. In tomcat cluster + environment, it is set the cluster name + "-Channel" as default value. + (kfujino) +
  • +
  • Add: + Add the channel name to the thread which is invoked by channel services + in order to identify the associated channel. (kfujino) +
  • +
  • Fix: + Ensure that clear the channel instance from channel services when + stopping channel. (kfujino) +
  • +
  • Add: + Implement map state in the replication map. (kfujino) +
  • +
  • Fix: + Ensure that the ping is not executed during the start/stop of the + replication map. (kfujino) +
  • +
  • Fix: + In ping processing in the replication map, send not the + INIT message but the newly introduced PING + message. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + 59211: Add hamcrest to Eclipse classpath. Patch is provided + by Huxing Zhang. (violetagg) +
  • +
  • Update: + 59280: Update the NSIS Installer used to build the + Windows Installers to version 2.51. (kkolinko) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.7 to + pick up the Windows binaries that are based on OpenSSL 1.0.2h and APR + 1.5.2. (markt) +
  • +
+
+

2016-03-24 Tomcat 8.0.33 (markt)

+

Catalina

+
    +
  • Fix: + Correct a regression in the fix for 58867. When configuring a + Context to use an external directory for the docBase, and + that directory happens to be located along side the original WAR, use + the directory as the docBase rather than expanding the + WAR into the appBase and using the newly created expanded + directory as the docBase. (markt) +
  • +
  • Add: + 58351: Make the server build date and server version number + accessible via JMX. Patch provided by Huxing Zhang. (markt) +
  • +
  • Add: + 58988: Special characters in the substitutions for the RewriteValve + can now be quoted with a backslash. (fschumacher) +
  • +
  • Fix: + 58999: Fix class and resource name filtering in WebappClassLoader. + It throws a StringIndexOutOfBoundsException if the name is exactly + "org" or "javax". (rjung) +
  • +
  • Code: + Remove unnecessary code. There is no support for context level cluster. + (kfujino) +
  • +
  • Add: + Make checking for var and map replacement in RewriteValve a bit stricter and + correct detection of colon in var replacement. (fschumacher) +
  • +
  • Fix: + Fix the type of InstanceManager attribute of mbean + definition of StandardContext. (kfujino) +
  • +
  • Fix: + Refactor the web application class loader to reduce the impact of JAR + scanning on the memory footprint of the web application. (markt) +
  • +
  • Fix: + Fix some resource leaks in the error handling for accessing files from + JARs and WARs. (markt) +
  • +
  • Fix: + Refactor the JAR and JAR-in-WAR resource handling to reduce the memory + footprint of the web application. (markt) +
  • +
  • Fix: + 57809: Deprecate the custom context attribute + org.apache.tomcat.util.scan.MergedWebXml which will be + removed in Tomcat 9. (markt) +
  • +
  • Fix: + 59001: Correctly handle the case when Tomcat is installed on + a path where one of the segments ends in an exclamation mark. (markt) +
  • +
  • Fix: + Expand the fix for 59001 to cover the special sequences used + in Tomcat's custom jar:war: URLs. (markt) +
  • +
  • Fix: + 59043: Avoid warning while expiring sessions associated with + a single sign on if HttpServletRequest.logout() is used. + (markt) +
  • +
  • Fix: + 59054: Ensure that using the + CrawlerSessionManagerValve in a distributed environment + does not trigger an error when the Valve registers itself in the + session. (markt) +
  • +
  • Fix: + Storeconfig handling of alternate cookie processors. (markt/remm) +
  • +
  • Fix: + Storeconfig handling for socket properties. (remm) +
  • +
  • Add: + Log a warning message if a user tries to configure the default session + timeout via the deprecated (and ignored) + Manager.setMaxInactiveInterval() method. (markt) +
  • +
  • Fix: + Fix incorrect parsing of the NE and NC flags in rewrite rules. (remm) +
  • +
  • Fix: + 59065: Correct the timing of the check for colons in paths + on non-Windows systems implemented in catalina.sh so it + works correctly with Cygwin. Patch provided by Ed Randall. (markt) +
  • +
  • Fix: + When a Host is configured with an appBase that does not exist, create + the appBase before trying to expand an external WAR file into it. + (markt) +
  • +
  • Fix: + 59115: When using the Servlet 3.0 file upload, the submitted + file name may be provided as a token or a quoted-string. If a + quoted-string, unquote the string before returning it to the user. + (markt) +
  • +
  • Fix: + 59123: Close NamingEnumeration objects used by + the JNDIRealm once they are no longer required. + (fschumacher/markt) +
  • +
  • Fix: + 59138: Correct a false positive warning for ThreadLocal + related memory leaks when the key class but not the value class has been + loaded by the web application class loader. (markt) +
  • +
  • Fix: + 59145: Don't log an invalid warning when a user logs out of + a session associated with SSO. (markt) +
  • +
  • Fix: + 59151: Fix a regression in the fix for 56917 that + added additional (and arguably unnecessary) validation to the provided + redirect location. (markt) +
  • +
  • Fix: + 59154: Fix a NullPointerException in the + JASSMemoryLoginModue resulting from the introduction of the + CredentialHandler to Realms. (schultz/markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 58646: Correct a problem with sendfile that resulted in a + Processor being added to the cache twice leading to broken responses. + (markt) +
  • +
  • Fix: + 59015: Fix potential cause of endless APR Poller loop during + shutdown if the Poller experiences an error during the shutdown process. + (markt) +
  • +
  • Fix: + Align cipher aliases for kECDHE and ECDHE with + the current OpenSSL implementation. (markt) +
  • +
  • Fix: + 59081: Retain the user defined cipher order when defining + ciphers using the OpenSSL format. (markt) +
  • +
  • Fix: + 59089: Correctly ignore HTTP headers that include non-token + characters in the header name. (markt) +
  • +
  • Add: + Add support for additional OpenSSL cipher aliases from OpenSSL master + when specifying ciphers using the OpenSSL syntax. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57583: Improve the performance of + javax.servlet.jsp.el.ScopedAttributeELResolver when + resolving attributes that do not exist. This improvement only works when + Jasper is used with with Tomcat's EL implementation. (markt) +
  • +
  • Update: + 58111: Update to the Eclipse JDT Compiler 4.5. (markt) +
  • +
  • Add: + Add Java 9 support for JSPs. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 59014: Ensure that a WebSocket close message can be sent + after a close message has been received. (markt) +
  • +
  • Fix: + Correctly handle compression of partial messages when the final message + fragment has a zero length payload. (markt) +
  • +
  • Fix: + 59119: Correct read logic for WebSocket client when using + secure connections. (markt) +
  • +
  • Fix: + 59134: Correct client connect logic for secure connections + made through a proxy. (markt) +
  • +
  • Fix: + 59189: Explicitly release the native memory held by the + Inflater and Deflater when using + PerMessageDeflate and the WebSocket session ends. Based on a patch by + Henrik Olsson. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct an error in the documentation of the expected behaviour for + automatic deployment. If a WAR is updated and an expanded directory is + present, the directory will always be deleted and recreated by expanding + the WAR if unpackWARs is true. (markt) +
  • +
  • Fix: + 58935: Remove incorrect references in the documentation to + using jar:file: URLs with the Manager application. (markt) +
  • +
  • Fix: + Correct the description of the + ServletRequest.getServerPort() in Proxy How-To. + Issue reported via comments.apache.org. (violetagg) +
  • +
  • Fix: + Fix a potential indefinite wait in the Comet Chat servlet in the + examples web application. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + If promoting a proxy node to a primary node when getting a session, + notify the change of the new primary node to the original backup node. + (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + 58283: Change the default download location for libraries + during the build process from /usr/share/java to + ${user.home}/temp. Patch provided by Ahmed Hosni. (markt) +
  • +
  • Fix: + 59031: When using the Windows uninstaller, do not remove the + contents of any directories that have been symlinked into the Tomcat + directory structure. (markt) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.5 to + pick up the Windows binaries that are based on OpenSSL 1.0.2g and APR + 1.5.1. (markt) +
  • +
  • Update: + Modify the default tomcat-users.xml file to make it harder + for users to configure the entries intended for use with the examples + web application for the Manager application. (markt) +
  • +
+
+

2016-02-08 Tomcat 8.0.32 (markt)

+

General

+
    +
  • Add: + Allow to configure multiple JUnit test class patterns with the build + property test.name and document the property in + BUILDING.txt. (rjung) +
  • +
  • Fix: + 58768: Log a warning if a redirect fails because of an + invalid location. (markt) +
  • +
+
+

Catalina

+
    +
  • Fix: + Fix class loader decision on the delegation for class loading and + resource lookup and make it faster too. (rjung) +
  • +
  • Fix: + 58946: Ensure that the request parameter map remains + immutable when processing via a RequestDispatcher. (markt) +
  • +
  • Fix: + 58827: Deprecate what is left of the JSR 77 implementation. + (markt) +
  • +
  • Fix: + 58905: Ensure that Tomcat.silence() silences the + correct logger and respects the current setting. (markt) +
  • +
+
+

Coyote

+
    +
  • Add: + New configuration option ajpFlush for the AJP connectors + to disable the sending of AJP flush packets. (rjung) +
  • +
+
+

Cluster

+
    +
  • Fix: + Correct a regression in the session attribute filtering that prevented + clustering from starting in the default configuration. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Fix a timing issue on session close that could result in an exception + being thrown for an incomplete message even through the message was + completed. (markt) +
  • +
+
+

not released Tomcat 8.0.31 (markt)

+

Catalina

+
    +
  • Fix: + Correct implementation of + validateClientProvidedNewSessionId so client provided + session IDs may be rejected if validation is enabled. (markt) +
  • +
  • Fix: + Add path parameter handling to + HttpServletRequest.getContextPath(). This is a follow-up to + the fix for 57215. (markt) +
  • +
  • Fix: + 58692: Make StandardJarScanner more robust. Log + a warning if a class path entry cannot be scanned rather than triggering + the failure of the web application. Includes a test case written by + Derek Abdine. (markt) +
  • +
  • Fix: + 58701: Reset the instanceInitialized field in + StandardWrapper when unloading a Servlet so that a new + instance may be correctly initialized. (markt) +
  • +
  • Fix: + 58702: Ensure an access log entry is generated if the client + aborts the connection. (markt) +
  • +
  • Fix: + Fixed various issues reported by Findbugs. (violetagg) +
  • +
  • Fix: + 58735: Add support for the X-XSS-Protection + header to the HttpHeaderSecurityFilter. Patch provided by + Jacopo Cappellato. (markt) +
  • +
  • Fix: + 58751: Correctly handle the case where an + AsyncListener dispatches to a Servlet on an asynchronous + timeout and the Servlet uses sendError() to trigger an + error page. Includes a test case based on code provided by Andy + Wilkinson.(markt) +
  • +
  • Fix: + 58765: Change default for + mapperContextRootRedirectEnabled to true since + this is required for correct session management because of the default + for sessionCookiePathUsesTrailingSlash. (markt) +
  • +
  • Fix: + Add the StatusManagerServlet to the list of Servlets that + can only be loaded by privileged applications. (markt) +
  • +
  • Fix: + Simplify code and fix messages in + org.apache.catalina.core.DefaultInstanceManager class. + (kkolinko) +
  • +
  • Code: + Deprecate InstanceListener, InstanceEvent and InstanceSupport prior to + removal in 9.0.x. (markt) +
  • +
  • Fix: + Ensure that the proper file encoding if specified will be used when + a readme file is served by DefaultServlet. (violetagg) +
  • +
  • Fix: + Fix declaration of localPort attribute of Connector MBean: + it is read-only. (kkolinko) +
  • +
  • Fix: + 58766: Make skipping non-class files during annotation + scanning faster by checking the file name first. Improve debug logging. + (kkolinko) +
  • +
  • Fix: + 58809: Correctly recycle cookies when mapping requests for + parallel deployment. As a side-effect of this fix, the system property + org.apache.tomcat.util.http.ServerCookie.PRESERVE_COOKIE_HEADER + is no longer used. From this release, Tomcat will always preserve the + cookie header. (markt) +
  • +
  • Fix: + 58836: Correctly merge query string parameters when + processing a forwarded request where the target includes a query string + that contains a parameter with no value. (markt/kkolinko) +
  • +
  • Fix: + Make sure that shared Digester is reset in an unlikely error case + in HostConfig.deployWAR(). (kkolinko) +
  • +
  • Fix: + 58867: Improve checking on Host start for WAR files that have + been modified while Tomcat has stopped and re-expand them if + unpackWARs is true. (markt) +
  • +
  • Fix: + Fix a potential JDBC resource leak in DataSourceRealm. (schultz) +
  • +
  • Fix: + 58900: Correctly undeploy symlinked resources and prevent an + infinite cycle of deploy / undeploy. (markt) +
  • +
  • Fix: + Protect initialization of ResourceLinkFactory when + running with a SecurityManager. (kkolinko) +
  • +
  • Add: + Extend the feature available in the cluster session manager + implementations that enables session attribute replication to be + filtered based on attribute name to all session manager implementations. + Note that configuration attribute name has changed from + sessionAttributeFilter to + sessionAttributeNameFilter. Apply the filter on load as + well as unload to ensure that configuration changes made while the web + application is stopped are applied to any persisted data. (markt) +
  • +
  • Add: + Extend the session attribute filtering options to include filtering + based on the implementation class of the value and optional + WARN level logging if an attribute is filtered. These + options are available for all of the Manager implementations that ship + with Tomcat. When a SecurityManager is used filtering will + be enabled by default. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Fix handling of missing messages in + org.apache.el.util.MessageFactory. (violetagg) +
  • +
+
+

Cluster

+
    +
  • Fix: + In order to avoid that the heartbeat thread and the background thread to + run Channel.heartbeat simultaneously, if + heartbeatBackgroundEnabled of SimpleTcpCluster + set to true, ensure that the heartbeat thread does not + start. (kfujino) +
  • +
  • Code: + Simplify the code of JvmRouteBinderValve.startInternal(). + Avoid potential NPE when JvmRouteBinderValve is configured + directly at Engine element. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 57489: Ensure onClose() is called when a + WebSocket connection is closed even if the sending of the close message + fails. Includes test cases by Barry Coughlan. (markt) +
  • +
+
+

Web Applications

+
    +
  • Add: + Add a description of the default value of + heartbeatSleeptime attribute and optionCheck + attribute in the cluster channel docs. (kfujino) +
  • +
  • Fix: + Correct some typos in the JNDI resources How-To. (markt) +
  • +
  • Fix: + Don't create sessions unnecessarily in the Manager application. (markt) +
  • +
  • Fix: + Don't create sessions unnecessarily in the Host Manager application. + (markt) +
  • +
  • Fix: + 58723: Clarify documentation and error messages for the text + interface of the manager to make clear that version must be used with + path when referencing contexts deployed using parallel deployment. + (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Fix potential NPE in AbstractReplicatedMap.breakdown(). + (kfujino) +
  • +
  • Fix: + Add support for the startup notification of local members in the static + cluster. (kfujino) +
  • +
  • Fix: + Ignore the unnecessary member remove operation from different domain. + (kfujino) +
  • +
  • Fix: + Add support for the shutdown notification of local members in the static + cluster. (kfujino) +
  • +
  • Fix: + Ensure that asynchronous session replication thread is a daemon thread. + (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Remove native code (Windows Service Wrapper, APR/native connector) + support for Windows Itanium. (markt) +
  • +
  • Update: + Update the packaged version of the Tomcat Native Library to 1.2.4 to + pick up the Windows binaries that are based on OpenSSL 1.0.2e and APR + 1.5.1. (markt) +
  • +
  • Update: + Update the NSIS Installer used to build the Windows Installers to + version 2.50. (markt/kkolinko) +
  • +
  • Update: + Update optional Checkstyle library to 6.14.1. (kkolinko) +
  • +
+
+

2015-12-06 Tomcat 8.0.30 (markt)

+

Catalina

+
    +
  • Fix: + 34319: Only load those keys in + StoreBase.processExpire from JDBCStore, that are old + enough, to be expired. Based on a patch by Tom Anderson. (fschumacher) +
  • +
  • Add: + 56917: As per RFC7231 (HTTP/1.1), allow HTTP/1.1 and later + redirects to use relative URIs. This is controlled by a new attribute + useRelativeRedirects on the Context and + defaults to true. (markt) +
  • +
  • Fix: + 58629: Allow an embedded Tomcat instance to start when the + Service has no Engine configured. (markt) +
  • +
  • Fix: + 58635: Enable break points to be set within agent code when + running Tomcat with a Java agent. Based on a patch by Huxing Zhang. + (markt) +
  • +
  • Fix: + 58660: Correct a regression in 8.0.29 caused by the change + that moved the redirection for context roots from the Mapper to the + Default Servlet. (markt) +
  • +
  • Fix: + Fixed potential NPE in HostConfig while deploying an + application. Issue reported by coverity scan. (violetagg) +
  • +
  • Fix: + 58655: Fix an IllegalStateException when + calling HttpServletResponse.sendRedirect() with the + RemoteIpFilter. This was caused by trying to correctly + generate the absolute URI for the redirect. With the fix for + 56917, redirects may now be relative making the + sendRedirect() implementation for the + RemoteIpFilter much simpler. This also addresses issues + where the redirect may not have behaved as expected when redirecting + from http to https to from https to http. (markt) +
  • +
  • Fix: + 58657: Exceptions in a Servlet 3.1 ReadListener + or WriteListener do not need to be immediately fatal to the + connection. Allow an error response to be written. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Improve upgrade context classloader handling by using Context.bind and + unbind. (remm) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57136#c25: Change default value of + quoteAttributeEL setting in Jasper to be true + for better compatibility with other implementations and older versions + of Tomcat (8.0.26/7.0.64 and earlier). Add command line option + -no-quoteAttributeEL in JspC. (kkolinko) +
  • +
+
+

Cluster

+
    +
  • Fix: + Fix potential integer overflow in DeltaSession. + Reported by coverity scan. (fschumacher) +
  • +
+
+

WebSocket

+
    +
  • Add: + 55006: The WebSocket client now honors the + java.net.java.net.ProxySelector configuration (using the + HTTP type) when establishing WebSocket connections to servers. Based on + a patch by Niki Dokovski. (markt) +
  • +
  • Fix: + 58624: Correct a thread safety issue that meant that blocking + message writes could block indefinitely if the WebSocket connection was + closed while a message write was in progress. (markt) +
  • +
+
+

Web Applications

+
    +
  • Fix: + 58631: Correct the continuation character use in the Windows + Service How-To page of the documentation web application. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Ensure that the static member is registered to the add suspect list even + if the static member that is registered to the remove suspect list has + disappeared. (kfujino) +
  • +
  • Fix: + Correct the warning log of when the member that is not registered in the + membership is detected. (kfujino) +
  • +
  • Fix: + When using a static cluster, add the members that have been cached in + the membership service to the map members list in order to ensure that + the map member is a static member. (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Correct evaluation of system property + org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader. + It was basically ignored before. Reported by coverity scan. + (fschumacher) +
  • +
  • Fix: + Fix potential integer overflow in ConnectionPool and + PooledConnection. Reported by coverity scan. (fschumacher) +
  • +
+
+

Other

+
    +
  • Update: + Update optional Checkstyle library to 6.13. (kkolinko) +
  • +
+
+

2015-11-24 Tomcat 8.0.29 (markt)

+

General

+
    +
  • Update: + 58596: Clarify the description in RUNNING.txt of how + environment variables are used. (markt) +
  • +
+
+

Catalina

+
    +
  • Add: + Extend the fix for 57136 to provide a JSP Servlet + initialisation parameter per web application that controls whether or + not EL in JSP attributes is processed as if it uses JSP attribute + quoting. By default, EL does not use JSP attribute quoting. (markt) +
  • +
  • Fix: + 57799: InputStream.available() was causing an IO operation + to occur even in blocking mode, which caused problems with NIO2. + (remm) +
  • +
  • Add: + Extend the fix for 58228 to include + ServletContext.getRealPath(). (markt) +
  • +
  • Add: + 58486: Protect against two further possible memory leaks + associated with XML parsing. (markt) +
  • +
  • Fix: + 58490: Fixed NPE thrown when scanning for + javax.servlet.ServletContainerInitializer in case the web + application is not extracted. (violetagg) +
  • +
  • Code: + 58497: Make AbstractHttp11Processor easy to + extend. (markt) +
  • +
  • Fix: + 58508: Escape role names when generating associated MBeans in + case the role name contains characters not permitted in an MBean name. + (markt) +
  • +
  • Fix: + 58518: Correct a regression in the fix for 56777 + that added support for URIs in config file locations. File paths on + Windows could previously be specified with \ or + / as the separator. 56777 broke that. (markt) +
  • +
  • Fix: + 58519: Fix ISE thrown by web application classloader in some + error conditions due to trying to call initCause() on a + ClassNotFoundException which is not permitted. (markt) +
  • +
  • Fix: + 58534: Removed repeated conditional tests in + o.a.tomcat.websocket.pojo.PojoMethodMapping and + o.a.tomcat.util.net.AprEndpoint + Patch provided by Anthony Whitford. (violetagg) +
  • +
  • Fix: + 58535: Use Collections.reverseOrder + when a reverse ordering is needed. (violetagg) +
  • +
  • Fix: + 58537, 58546: Some of the inner classes in + o.a.catalina.valves.ExtendedAccessLogValve + and o.a.tomcat.util.net.SecureNio2Channel + are made static. + Patch provided by Anthony Whitford. (violetagg) +
  • +
  • Fix: + 58540: Removed unused code from + o.a.catalina.connector.Request. + Patch provided by Anthony Whitford. (violetagg) +
  • +
  • Fix: + 58541, 58544: It is more efficient to call + Integer.toString(int) instead of + Integer.valueOf(int).toString() when only a string + representation of a primitive is needed. Based on a patch provided by + Anthony Whitford. (violetagg) +
  • +
  • Fix: + 58541, 58547: It is more efficient to call + valueOf(...) instead of Number constructor. Based on a + patch provided by Anthony Whitford. (violetagg) +
  • +
  • Fix: + 58545: In some use cases it is more efficient to use + Map.entrySet() instead of Map.keySet() + Based on a patch provided by Anthony Whitford. (violetagg) +
  • +
  • Fix: + Ensure that ServletRequest.getContentLengthLong is used + instead of ServletRequest.getContentLength for servlets and + valves provided by Tomcat. The API is available since Servlet + specification 3.1. (violetagg) +
  • +
  • Add: + Add a new RestCsrfPreventionFilter that provides basic CSRF protection + for REST APIs. (violetagg) +
  • +
  • Fix: + 58578: Avoid NPE accessing cookies during access logging + for request that had no context mapping. (remm) +
  • +
  • Fix: + Avoid UnsupportedOperationException when releasing an user-provided + URLStreamHandlerFactory. Patch provided by Cristian Talau. (violetagg) +
  • +
  • Fix: + 58581: If a custom error page fails, fall back to the + standard error page rather than throwing an NPE. Based on a patch by + Huxing Zhang. (markt) +
  • +
  • Fix: + 58582: Combined realm should perform background processing + on its sub-realms. Based upon a patch provided by Aidan. (schultz) +
  • +
  • Fix: + Handle the unlikely case where different versions of a web application + are deployed with different session settings. (markt) +
  • +
  • Add: + Add a new Context option, enabled by default, that enables an additional + check that a client provided session ID is in use in at least one other + web application before allowing it to be used as the ID for a new + session in the current web application. (markt) +
  • +
  • Add: + Add support for DIGEST authentication to the JNDIRealm. Based on a patch + by Alexis Hassler. (markt) +
  • +
  • Fix: + 58603: Ensure that + HttpServletRequest.getRequestURL() returns the correct + value when using the RemoteIpFilter. (markt) +
  • +
  • Fix: + Ensure that in an embedded Tomcat the logging configuration is + not lost during garbage collection. (violetagg) +
  • +
  • Add: + Move the functionality that provides redirects for context roots and + directories where a trailing / is added from the Mapper to + the DefaultServlet. This enables such requests to be + processed by any configured Valves and Filters before the redirect is + made. This behaviour is configurable via the + mapperContextRootRedirectEnabled and + mapperDirectoryRedirectEnabled attributes of the Context + which may be used to restore the previous behaviour. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Cancel pending blocking IO operation following a timeout in the NIO2 + connector. (remm) +
  • +
  • Fix: + Add instance manager support for upgrade handlers, and set context + class loader. (remm) +
  • +
  • Update: + Synchronize OpenSSL to JSSE cipher mapping to recent OpenSSL changes. In + particular, TLSv1.0 is now an alias for those ciphers that + require TLSv1 and will not work with SSLv3. TLSv1 remains + an alias for SSLv3. (markt) +
  • +
+
+

Jasper

+
    +
  • Add: + Deprecate the STRICT_QUOTE_ESCAPING system property and + replace it with an initialisation parameter for the JSP Servlet. This + enables per web application control of this configuration setting. + (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Optimize the session lock range in DeltaManager.requestCompleted. + (kfujino) +
  • +
  • Fix: + Enable an explicit configuration of local member in the static cluster + membership. (kfujino) +
  • +
+
+

Tribes

+
    +
  • Code: + Distinguish the handling of the shutdown payload and member verification + clearly. When handling shutdown payload, verification completion message + is not required. (kfujino) +
  • +
  • Fix: + When starting the StaticMembershipInterceptor, + StaticMembershipInterceptor checks the required + Interceptors. If the required Interceptor does not exist, it issues + warning logs. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Use instance manager for server endpoint instances. (remm) +
  • +
+
+

Web applications

+
    +
  • Add: + Make it clear in the documentation for the CGI servlet that the debug + page is not considered secure and should not be used in production. + (markt) +
  • +
  • Fix: + The domain attribute of StaticMember is not + required but optional. (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 58489: Correct QueryStatsComparator to hold up the + general contract for Comparator. (fschumacher) +
  • +
  • Fix: + When creating a QueryStats object, ensure that + maxQueries is checked. If maxQueries is a + value less than or equal to 0, QueryStats are never + created. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update optional Checkstyle library to 6.12.1. (kkolinko) +
  • +
  • Add: + Add support for creating a FindBugs report when building Tomcat. It + is disabled by default. (violetagg) +
  • +
+
+

2015-10-12 Tomcat 8.0.28 (markt)

+

Catalina

+
    +
  • Add: + Add support for the custom classpath protocol in URLs. It + an be used anywhere Tomcat accepts a URL for a configuration parameter. + (markt) +
  • +
  • Fix: + 56777: Allow file based configuration resources (user + database, certificate revocation lists, keystores and trust stores) to + be configured using URLs as well as files. (markt) +
  • +
  • Fix: + Perform null-checking on input and stored credentials in all Realms + before passing credentials off to CredentialHandlers for matching. + (schultz) +
  • +
+
+

Coyote

+
    +
  • Update: + Add the new ciphers from RFC6655 and RFC7251 to the OpenSSL to JSSE + cipher mapping. (markt) +
  • +
  • Update: + Remove DES, RC2 and RC4 from DEFAULT for the OpenSSL to JSSE cipher + mapping to align with the OpenSSL development branch. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Improve the error message when JSP parser encounters an error parsing an + attribute value. (markt) +
  • +
+
+

Web applications

+
    +
  • Update: + 58474: Provide a reference to the differences between + CATALINA_HOME and CATALINA_BASE in the sample + application that is part of the documentation web application. (markt) +
  • +
+
+

Extras

+
    +
  • Fix: + Ensure JULI adapters does not include the LogFactoryImpl class. Patch + provided by Benjamin Gandon. (markt) +
  • +
+
+

2015-10-01 Tomcat 8.0.27 (markt)

+

Catalina

+
    +
  • Fix: + 58187: Correct a regression in the fix for 57765 + that meant that deployment of web applications deployed via the Manager + application was delayed until the next execution of the automatic + deployment background process. (markt) +
  • +
  • Fix: + 58284: Correctly implement session serialization so + non-serializable attributes are skipped with a warning. Patch provided + by Andrew Shore. (markt) +
  • +
  • Fix: + 58313: Fix concurrent access of encoders map when clearing + encoders prior to switch to async. (markt) +
  • +
  • Fix: + 58320: Fix concurrent access of request attributes which is + possible during asynchronous processing. (markt) +
  • +
  • Fix: + 58352: Always trigger a thread dump if Tomcat fails to stop + gracefully from catalina.sh even if using + -force. Patch provided by Alexandre Garnier. (markt) +
  • +
  • Fix: + 58368: Fix a rare data race in the code that obtains the + ApplicationFilterFactory instance. (markt) +
  • +
  • Fix: + 58369: Fix a rare data race in the code that obtains the + CookieProcessor for a StandardContext instance. (markt) +
  • +
  • Fix: + Ensure the JAASRealm uses the configured CredentialHandler. (markt) +
  • +
  • Fix: + 58372: Fix rare data races closed and suspended flags that + could be triggered by async and/or comet processing. (markt) +
  • +
  • Fix: + 58373: Fix rare data race with the application event + listeners for StandardContext. (markt) +
  • +
  • Fix: + 58374: Fix a rare data race in the AsyncContext + implementation for access to the internal Tomcat request object to which + it holds a reference. (markt) +
  • +
  • Fix: + 58380: Fix two rare data races in the standard session + implementation on the flag that tracks if the session is new and on the + field that tracks the maximum inactive period. (markt) +
  • +
  • Fix: + 58385: Fix a rare data race in the internal flag Tomcat uses + to keep track of whether or not a request is being used for Comet + processing. (markt) +
  • +
  • Fix: + 58394: Fix a rare data race in Mapper when adding or removing + a host. (markt) +
  • +
  • Fix: + 58398: Fix a rare data race in LifecycleSupport. + (markt) +
  • +
  • Fix: + 58412: Ensure that the AsyncFileHandler has the + source class and method name available for logging. (fschumacher) +
  • +
  • Fix: + 58416: Correctly detect when a forced stop fails to stop + Tomcat because the Tomcat process is waiting on some system call or is + uninterruptible. (markt) +
  • +
  • Fix: + 58436: Fix some rare data races in JULI's + ClassLoaderLogManager during shutdown. (markt) +
  • +
  • Fix: + 58845: Fix off-by one error in calculation of valid + characters in a cookie domain. Patch provided by Thorsten Ehlers. + (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Correct some edge cases in RequestUtil.normalize(). (markt) +
  • +
  • Fix: + 58275: The IBM JREs accept cipher suite names starting with + TLS_ or SSL_ but when listing the supported + cipher suites only the SSL_ version is reported. This can + break Tomcat's check that at least one requested cipher suite is + supported. Tomcat now includes a work-around so either form of the + cipher suite name can be used when running on an IBM JRE. (markt) +
  • +
  • Fix: + 58357: For reasons not currently understood when the + APR/native connector is used with OpenSSL reads can return an error code + when there is no apparent error. This was work-around for HTTP upgrade + connections by treating this as EAGAIN. The same fix has + now been applied to the standard HTTP connector. (markt) +
  • +
  • Code: + Minor clean-up in NIO2 SSL handshake code to address some theoretical + concurrency issues. (markt) +
  • +
  • Fix: + 58367: Fix a rare data race in the code that obtains the + reason phrase for a given HTTP response code. (markt) +
  • +
  • Fix: + 58370: Fix a rare data race in the connector shutdown code. + (markt) +
  • +
  • Fix: + 58371: Fix a rare data race when accessing request URI in + String form when switching from non-async to async due to early + triggering of the gathering of request statistics. (markt) +
  • +
  • Fix: + 58375: Fix a rare data race on the internal flag Tomcat uses + to mark a response as committed. (markt) +
  • +
  • Fix: + 58377: Fix a rare data race on the internal flag Tomcat uses + to mark a request as using HTTP keep-alive when switching to + asynchronous processing. (markt) +
  • +
  • Fix: + 58379: Fix a rare data race on the internal reference Tomcat + retains to the socket when switching to asynchronous processing. (markt) +
  • +
  • Fix: + 58387: Fix a rare data race when closing Comet connections. + (markt) +
  • +
  • Fix: + 58388: Fix a data race when determining if Comet processing + is occurring on a container or non-container thread. (markt) +
  • +
  • Fix: + 58389: Fix a rare data race while shutting down the thread + pools on Connector stop. (markt) +
  • +
  • Code: + Clean up use of error flag on socket wrapper prompted by + 58390. (markt) +
  • +
  • Code: + Remove some unnecessary code from the NIO Poller and fix + 58396 as a side-effect. (markt) +
  • +
  • Fix: + 57799: Remove useless sendfile check for NIO SSL. (remm) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57136: Correct a regression in the previous fix for this + issue. \${ should only be an escape for ${ + within an EL expression. Within a JSP page \$ should be an + escape for $. The EL specification applies when parsing the + expression delimited by ${ and }. Parsing of + the delimiting ${ and } is the responsibility + of the JSP specification. (markt) +
  • +
  • Fix: + 58296: Fix a memory leak in the JSP unloading feature that + meant that using a value other than -1 for + maxLoadedJsps triggered a memory leak once the limit was + reached. (markt) +
  • +
  • Fix: + 58327: Cache the expression string for value expression + literals since it is frequently used and may be expensive to evaluate. + Patch provided by Andreas Kohn. (markt) +
  • +
  • Fix: + 58340: Improve error reporting for tag files packaged in + JARs. (markt) +
  • +
  • Fix: + 58424: When parsing TLD files, allow whitespace around + boolean configuration values. (schultz) +
  • +
  • Fix: + Fix a possible resource leak reported by coverity scan. (fschumacher) +
  • +
  • Fix: + 58427: Enforce the JSP specification defined limitations of + which elements are allowed in an implicit.tld file. (markt) +
  • +
  • Fix: + 58444: Ensure that JSPs work with any custom base class that + meets the requirements defined in the JSP specification without + requiring that base class to implement Tomcat specific code. (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Fix a default clusterListeners in SimpleTcpCluster. The + optimal default value is different for each session manager. + ClusterSessionListener is never used in + BackupManager. (kfujino) +
  • +
  • Fix: + Correct log messages in case of using BackupManager. + (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 58342: Fix a copy and paste error that meant MessageHandler + removal could fail for binary and pong MessageHandlers. Patch provided + by DJ. (markt) +
  • +
  • Fix: + Data races detected by RV-Predict, mostly caused by completion handlers + running in separate threads. (markt) +
  • +
  • Fix: + 58414: Correctly handle sending zero length messages when + using per message deflate. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct documentation for cluster-howto. (kfujino) +
  • +
  • Fix: + Add missing documentation for property alwaysAddExpires for + the LegacyCookieProcessor. (markt) +
  • +
+
+

Tribes

+
    +
  • Add: + Add support for configurations of ChannelListener and + MembershipListener in server.xml. (kfujino) +
  • +
  • Fix: + Correct log messages in case of using ReplicatedMap. + (kfujino) +
  • +
  • Fix: + 58381: Fix a rare data race in the NioReceiver. + (markt) +
  • +
  • Fix: + 58382: Fix multiple rare data races in the default membership + implementation. (markt) +
  • +
  • Fix: + 58383: Fix a data race in SenderState. (markt) +
  • +
  • Fix: + 58386: Fix a data race in ObjectReader. (markt) +
  • +
  • Fix: + 58391: Fix multiple data races in + NonBlockingCoordinator, most of which were associated with + ensuring that log messages contained the correct information. (markt) +
  • +
  • Fix: + 58392: Fix a data race in + DomainFilterInterceptor. (markt) +
  • +
  • Fix: + 58393: Fix a data race on the listener in + McastService. (markt) +
  • +
  • Fix: + 58395: Fix multiple data races in MemberImpl + that were likely to cause issues if certain properties were updated + concurrently (such updates are unlikely in normal usage). (markt) +
  • +
  • Code: + Remove some unnecessary code from PooledParallelSender and + fix 58397. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Make sure the pool has been properly configured when attributes that + related to the pool size are changed via JMX. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + Ensure logging works for all tests in a class rather than just the first + one executed. (markt) +
  • +
  • Add: + 58344: Add build properties to enable tests to be executed + against alternative binaries. Based on a patch by Petr Sumbera. (markt) +
  • +
+
+

2015-08-21 Tomcat 8.0.26 (markt)

+

Web applications

+
    +
  • Add: + 58255: Document the Semaphore valve. Patch provided by + Kyohei Nakamura. (markt) +
  • +
+
+

not released Tomcat 8.0.25 (markt)

+

Catalina

+
    +
  • Fix: + Make the WAR manifest file available for WebResource instances from an + unpacked WAR in the same way the manifest is available if the WAR is not + unpacked. (markt) +
  • +
  • Fix: + Ensure that only /WEB-INF/classes/ and + /WEB-INF/lib/ are excluded from the web resource caching. + (Resources loaded from these locations are cached by the web application + class loader.) (markt) +
  • +
  • Add: + 57741: Enable the CGI servlet to use the standard error page + mechanism. Note that if the CGI servlet's debug init parameter is + set to 10 or higher then the standard error page mechanism will be + bypassed and a debug response generated by the CGI servlet will be + returned instead. (markt) +
  • +
  • Fix: + 58031: Make the (first) reason parameter parsing failed + available as a request attribute and then use it to provide a better + status code via the FailedRequstFilter (if configured). (markt) +
  • +
  • Fix: + 58086: Correct a regression in the fix for 58086 that + incorrectly handled WAR URLs. (violetagg) +
  • +
  • Fix: + 58096: Classes loaded from /WEB-INF/classes/ + should use that directory as their code base. (markt) +
  • +
  • Fix: + Fix possible resource leaks by closing streams properly. + Issues reported by Coverity Scan. (violetagg) +
  • +
  • Fix: + 58116: Fix regression in the fix for 57281 that + broke Comet support when running under a security manager. Based on a + patch provided by Johno Crawford. (markt) +
  • +
  • Fix: + 58125: Avoid a possible ClassCircularityError + when running under a security manager. (markt) +
  • +
  • Fix: + 58179: Fix a thread safety issues that could mean concurrent + threads setting the same attribute on a ServletContext + could both see null as the old value. (markt) +
  • +
  • Fix: + Allow web archives bigger than 2G to be deployed using ANT tasks. + (violetagg) +
  • +
  • Fix: + 58192: Correct a regression in the previous fix for + 58023. Ensure that classes are associated with their manifest + even if the class file is first read (and cached) without the manifest. + (markt) +
  • +
  • Fix: + Fix thread safety issue in the AsyncContext implementation + that meant a sequence of start();dispatch(); calls using + non-container threads could result in a previous dispatch interfering + with a subsequent start. (markt) +
  • +
  • Fix: + 58228: Make behaviour of + ServletContext.getResource() and + ServletContext.getResourceAsStream() consistent with each + other and the expected behaviour of the GET_RESOURCE_REQUIRE_SLASH + system property. (markt) +
  • +
  • Fix: + 58230: Fix input stream corruption if non-blocking I/O is + used and the first read is made immediately after the switch to async + mode rather than in response to onDataAvaiable() and that + read does not read all the available data. (markt) +
  • +
  • Fix: + Ensure that log4javascript*.jar was not excluded from the + standard JAR scanning by default. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 57943: Prevent the same socket being added to the cache + twice. Patch based on analysis by Ian Luo / Sun Qi. (markt) +
  • +
  • Fix: + Add text/javascript,application/javascript to the default + list of compressable MIME types. (violetagg) +
  • +
  • Fix: + 58103: When pipelining requests, and the previous request was + an async request, ensure that the socket is removed from the waiting + requests so that the async timeout thread doesn't process it during the + next request. (markt) +
  • +
  • Fix: + 58151: Correctly handle EOF in the AJP APR/native connector + to prevent the connector entering a loop and generate excessive CPU + load. (markt) +
  • +
  • Fix: + In the AJP and HTTP NIO connectors, ensure that the socket timeout is + correctly set before adding the socket back to the poller for read. + (markt) +
  • +
  • Fix: + 58157: Ensure that the handling of async timeouts does not + result in an unnecessary dispatch to a container thread that could + result in the current socket being added to the Poller multiple times + with multiple attempts to process the same event for the same socket. + (markt) +
  • +
  • Fix: + Correct a couple of edge cases in RequestUtil.normalize(). + (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 58110: Like scriptlet sections, declaration sections of JSP + pages have a one-to-one mapping of lines to the generated .java file. + Use this information to provide more accurate error messages if a + compilation error occurs in a declaration section. (markt) +
  • +
  • Fix: + 58119: When tags are compiled they must be placed in the + org/apache/jsp/tag/web directory. Correct a regression in the fix for + 52725. (violetagg) +
  • +
  • Fix: + Fix a resource leak in JspC identified by Eclipse. (markt) +
  • +
  • Fix: + 58178: Expressions in a tag file should use the tag + file's PageContext rather than that of the containing + page. (markt) +
  • +
  • Fix: + Following on from the fix for 58178, expressions in a tag + file should use the tag file's imports rather than those of the + containing page. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 58166: Allow applications to send close codes in the range + 3000-4999 inclusive. (markt) +
  • +
  • Fix: + 58232: Avoid possible NPE when adding endpoints + programmatically to the + javax.websocket.server.ServerContainer. + Based on a patch provided by bastian.(violetagg) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct the incorrect document of QueryTimeoutInterceptor. + The setting value is not in milliseconds but in seconds. (kfujino) +
  • +
  • Fix: + 58112: Update the documentation for using the Catalina tasks + in an Apache Ant build file. (markt) +
  • +
  • Fix: + Improve the Javadoc for some of the APR socket read functions that have + inconsistent behaviour for return values. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 58042: The default value of logFailed attribute + of SlowQueryReport is changed to false so that + the failed queries are not logged by default. (kfujino) +
  • +
  • Fix: + Fix potential NPE in QueryTimeoutInterceptor. (kfujino) +
  • +
  • Fix: + Add support for stopping the pool cleaner via JMX. (kfujino) +
  • +
  • Fix: + The fairness attribute and + ignoreExceptionOnPreLoad attribute do not allow a change + via JMX. (kfujino) +
  • +
  • Fix: + If the timeBetweenEvictionRunsMillis attribute is changed + via jmx, it should restart the pool cleaner because this attribute + affects the execution interval of the pool cleaner. (kfujino) +
  • +
  • Fix: + Eliminate the dependence on maxActive of busy queues and + idle queue in order to enable the expansion of the pool size via JMX. + (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update optional Checkstyle library to 6.8.1. (kkolinko) +
  • +
  • Fix: + Update sample Eclipse IDE configuration to exclude test/webapp* and + similar paths from compiler sourcepath. (kkolinko) +
  • +
  • Update: + Update package renamed Apache Commons Pool to Commons Pool 2.4.2. + (markt) +
  • +
  • Update: + Update package renamed Apache Commons DBCP to Commons DBCP 2.1.1. + (markt) +
  • +
  • Add: + Support the use of the threads attribute on Ant's + junit task. Note that using this with a value of greater than one will + disable Cobertura code coverage. (markt) +
  • +
+
+

2015-07-06 Tomcat 8.0.24 (markt)

+

Catalina

+
    +
  • Fix: + 57938: Correctly handle empty form fields when a form is + submitted as multipart/form-data, the + maxPostSize attribute of the Connector has been set to a + negative value and the Context has been configured with a value of + true for allowCasualMultipartParsing. The + meaning of the value zero for the maxPostSize has also been + changed to mean a limit of zero rather than no limit to align it with + maxSavePostSize and to be more intuitive. (markt) +
  • +
  • Fix: + 57977: Correctly bind and unbind the web application class + loader during execution of the PersistentValve. (markt) +
  • +
  • Fix: + Remove some unnecessary code from the web application class loader and + deprecate the now unused validate() method since the + requirements of SRV.10.7.2 are met using cleaner code in + loadClass(String, boolean) and filter(). + (markt) +
  • +
  • Fix: + Correct a bug that prevented the web application class loader's + filter() from working correctly. It only returned + true for classes in sub-packages of the listed packages, + but not classes located in the packages themselves. (markt) +
  • +
  • Fix: + Add the WebSocket API classes to the list of classes that the web + application class loader will always delegate to its parent for loading + first. (markt) +
  • +
  • Fix: + 58015: Ensure that whenever the web application class loader + checks to see if it should delegate first, it also checks the result + of the filter() method which may indicate that it should + always delegate first for the current class/resource regardless of the + value of the delegate configuration option. (markt) +
  • +
  • Fix: + 58023: Fix potentially excessive memory usage due to + unnecessary caching of JAR manifests in the web application class + loader. (markt) +
  • +
  • Fix: + 57700: Ensure that Container event + ADD_CHILD_EVENT will be sent in all cases. (violetagg) +
  • +
  • Fix: + 58086: Ensure that WAR URLs are handled properly when using + ANT for web application deployment. Based on a patch provided by Lukasz + Jader. (violetagg) +
  • +
  • Fix: + Fix CredentialHandler element handling in storeconfig. (remm) +
  • +
+
+

Coyote

+
    +
  • Fix: + 57265: Further fix to address a potential threading issue + when sendfile is used in conjunction with TLS. (markt) +
  • +
  • Fix: + 57936: Improve robustness of the acceptor thread count + parameter for NIO2, since it must be set to 1. Submitted by + Oliver Kant. (remm) +
  • +
  • Add: + 57943: Added a work-around to catch + ConcurrentModificationExceptions during Poller timeout + processing that were causing the Poller thread to stop. The root cause + of these exceptions is currently unknown. (markt) +
  • +
  • Fix: + 57944: Ensure that if non-blocking I/O listeners are set on + a non-container thread that the expected listener events are still + triggered. (markt) +
  • +
  • Fix: + Fix possible very long (1000 seconds) timeout with APR/native connector. + (markt) +
  • +
  • Add: + Support "-" separator in the SSLProtocol configuration of the + APR/native connector for protocol exclusion. (rjung) +
  • +
  • Fix: + 58004: Fix AJP buffering output data even in blocking mode. + (remm) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 57969: Provide path parameters to POJO via per session + javax.websocket.server.ServerEndpointConfig as they vary + between different requests. (violetagg) +
  • +
  • Fix: + 57974: Session.getOpenSessions should return all sessions + associated with a given endpoint instance, rather than all sessions + from the endpoint class. (remm) +
  • +
+
+

Web applications

+
    +
  • Fix: + 57282: Update request processing sequence diagrams. Updated + diagrams provided by Stephen Chen. (markt) +
  • +
  • Fix: + 57971: Correct the documentation for the cluster + configuration setting recoverySleepTime. (markt) +
  • +
  • Add: + 57758: Add document of testOnConnect attribute + in jdbc-pool doc. (kfujino) +
  • +
  • Add: + Add description of validatorClassName attribute to testXXXX + attributes in jdbc-pool docs. (kfujino) +
  • +
+
+

Tribes

+
    +
  • Code: + Use StringManager to provide i18n support in the + org.apache.catalina.tribes packages. (kfujino) +
  • +
  • Fix: + Do not set the nodes that failed to replication to the backup nodes. + Ensure that the nodes that the data has been successfully replicated are + set to the backup node. (kfujino) +
  • +
  • Fix: + When failed to replication, rather than all member is handled as a + failed member, exclude the failure members from backup members. + (kfujino) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + Refactoring of the removeOldest method in + SlowQueryReport to behave as expected. (kfujino) +
  • +
  • Fix: + 57783: Fix NullPointerException in + SlowQueryReport. To avoid this NPE, Refactor + SlowQueryReport#removeOldest and handle the abandoned + connection properly. (kfujino) +
  • +
  • Fix: + 58042: In SlowQueryReportJmx, the + LogSlow and logFailed attributes that + inherited from SlowQueryReport are used as a condition of + whether JMX notifications are sent. (kfujino) +
  • +
  • Fix: + Ensure that specified Boolean attribute values of + SlowQueryReport reflect correctly. The LogSlow + and the logFailed are not system property, these are + attributes of SlowQueryReport. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update package renamed Apache Commons BCEL to r1682271 to pick up some + some code clean up. (markt) +
  • +
  • Update: + Update package renamed Apache Commons DBCP to r1682314 to pick up the + DBCP 2.1 release and additional fixes since then. (markt) +
  • +
  • Update: + Update package renamed Apache Commons Pool to the 2.4 release. (markt) +
  • +
  • Update: + Update package renamed Apache Commons File upload to r1682322 to pick up + the post 1.3.1 fixes. (markt) +
  • +
  • Update: + Update package renamed Apache Commons Codec to r1682326. No functional + changes. Javadoc only. (markt) +
  • +
  • Update: + Update optional Checkstyle library to 6.7. (kkolinko) +
  • +
+
+

2015-05-22 Tomcat 8.0.23 (markt)

+

Catalina

+
    +
  • Add: + 54618: Add a new HttpHeaderSecurityFilter that + adds the Strict-Transport-Security, + X-Frame-Options and X-Content-Type-Options + HTTP headers to the response. (markt) +
  • +
  • Fix: + 57875: Add javax.websocket.* to the classes for + which the web application class loader always delegates first. (markt) +
  • +
  • Fix: + 57871: Ensure that setting the + allowHttpSepsInV0 property of a + LegacyCookieProcessor to false only prevents HTTP + separators from being used without quotes. (markt) +
  • +
  • Fix: + Add a workaround for issues with SPNEGO authentication when running on + Java 8 update 40 and later. The workaround should be safe for earlier + Java versions but it can be disabled with the + applyJava8u40Fix attribute of the SPNEGO authenticator if + necessary. (markt) +
  • +
  • Fix: + 57926: Restore the original X-Forwarded-By and + X-Forwarded-For headers after processing by the + RemoteIPValve . (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Follow up to previous fix that removed the behavior difference between + NIO and NIO2 for SSL, which caused corruption with NIO2. + (remm) +
  • +
  • Fix: + 57931: Ensure that TLS connections with the NIO or NIO2 HTTP + connectors that experience issues during the handshake (e.g. missing or + invalid client certificate) are closed cleanly and that the client + receives the correct error code rather than simply closing the + connection. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56438: Add debug logging to TLD discovery that logs positive + and negative results for JARs, resource paths and directories. Patch + provided by VIN. (markt) +
  • +
  • Fix: + 57802: Correct the default implementation of + convertToType() provided by + javax.el.ELResolver. (markt) +
  • +
  • Fix: + 57887: Fix compilation of recursive tag files packaged in a + JAR. (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Make sure that stream is closed after using it in + DeltaSession.applyDiff(). (kfujino) +
  • +
  • Code: + Use StringManager to provide i18n support in the + org.apache.catalina.ha packages. (kfujino) +
  • +
  • Code: + Add the context name to log messages when replication context failed to + start. (kfujino) +
  • +
+
+

Web applications

+
    +
  • Fix: + 57875: Update the web application class loader documentation + to reflect the more relaxed approach to SRV.10.7.2 in Tomcat 8 onwards. + (markt) +
  • +
  • Fix: + 57896: Document system property + org.apache.tomcat.util.http.ServerCookie.PRESERVE_COOKIE_HEADER + that was introduced in Tomcat 8.0.0. (kkolinko) +
  • +
+
+

Tribes

+
    +
  • Fix: + Ensure that the state transfer flag is updated to true only when the map + states have been transferred correctly from existing map members. + (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update optional Checkstyle library to 6.6. (kkolinko) +
  • +
+
+

2015-05-05 Tomcat 8.0.22 (markt)

+

Catalina

+
    +
  • Fix: + 57736: Change the format of the Tomcat specific URLs for + resources inside JARs that are in turn packed in a WAR. The + ^/ sequence has been replaced by */ so that + the resulting URLs are compliant with RFC 2396 and do not trigger + exceptions when converted to URIs. The old format will continue to be + accepted. (markt) +
  • +
  • Fix: + 57752: Exclude non-cached resources from the Cache statistics + for resource lookups. Patch provided by Adam Mlodzinski. (markt) +
  • +
  • Add: + Allow logging of the remote port in the access log using the format + pattern %{remote}p. (rjung) +
  • +
  • Fix: + 57556: Refine the previous fix for this issue so that the + real path returned only has a trailing separator if the requested path + ended with /. (markt) +
  • +
  • Fix: + 57765: When checking last modified times as part of the + automatic deployment process, account for the fact that + File.lastModified() has a resolution of one second to + ensure that if a file has been modified within the last second, the + latest version of the file is always used. Note that a side-effect of + this change is that files with modification times in the future are + treated as if they are unmodified. (markt) +
  • +
  • Fix: + Align redeploy resource modification checking with reload modification + checking so that now, in both cases, a change in modification time + rather than an increase in modification time is used to determine if the + resource has changed. (markt) +
  • +
  • Fix: + Cleanup o.a.tomcat.util.digester.Digester from debug + messages that do not give any valuable information. Patch provided + by Polina Genova. (violetagg) +
  • +
  • Fix: + 57772: When reloading a web application and a directory + representing an expanded WAR needs to be deleted, delete the directory + after the web application has been stopped rather than before to avoid + potential ClassNotFoundExceptions. (markt) +
  • +
  • Fix: + Fix wrong logger name of + org.apache.catalina.webresources.StandardRoot. (kfujino) +
  • +
  • Fix: + 57801: Improve the error message in the start script in case + the PID read from the PID file is already owned by a process. (rjung) +
  • +
  • Fix: + 57841: Improve error logging during web application start. + (markt) +
  • +
  • Fix: + 57856: Ensure that any scheme/port changes implemented by the + RemoteIpFilter also affect + HttpServletResponse.sendRedirect(). (markt) +
  • +
  • Fix: + 57863: Fix the RewriteMap support in RewriteValve that did + not use the correct key value to look up entries. Based on a patch + provided by Tatsuya Bessho. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 57779: When an I/O error occurs on a non-container thread + only dispatch to a container thread to handle the error if using Servlet + 3+ asynchronous processing. This avoids potential deadlocks if an + application is performing I/O on a non-container thread without using + the Servlet 3+ asynchronous API. (markt) +
  • +
  • Code: + Remove the experimental support for SPDY. No current user agent supports + the version of SPDY that the experiment targeted. Note: HTTP/2 support + is under development for Tomcat 9 and may be back-ported to Tomcat 8 + once complete. (markt) +
  • +
  • Fix: + Possible incomplete writes with SSL NIO2. (remm) +
  • +
  • Fix: + Incorrect reads with SSL NIO2 caused by a bad strategy for handling IO + differences between NIO and NIO2 that don't seem to be justified. + (remm) +
  • +
  • Fix: + After some errors, the pending flags could remain set when using SSL + NIO2. (remm) +
  • +
  • Fix: + 57833: When using JKS based keystores for NIO or NIO2, ensure + that the key alias is always converted to lower case since that is what + JKS key stores expect. Based on a patch by Santosh Giri Govind M. + (markt) +
  • +
  • Fix: + 57837: Add text/css to the default list of + compressable MIME types. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57845: Ensure that, if the same JSP is accessed directly and + via a <jsp-file> declaration in web.xml, updates to + the JSP are visible (subject to the normal rules on re-compilation) + regardless of how the JSP is accessed. (markt) +
  • +
  • Fix: + 57855: Explicitly handle the case where a + MethodExpression is invoked with null or the wrong number + of parameters. Rather than failing with an + ArrayIndexOutOfBoundsException or a + NullPointerException throw an + IllegalArgumentException with a useful error message. + (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Avoid unnecessary call of DeltaRequest.addSessionListener() + in non-primary nodes. (kfujino) +
  • +
  • Add: + Add new attribute that send all actions for session across Tomcat + cluster nodes. (kfujino) +
  • +
  • Fix: + Remove unused pathname attribute in mbean definition of + BackupManager. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 57761: Ensure that the opening HTTP request is correctly + formatted when the WebSocket client connects to a server root. (remm) +
  • +
  • Fix: + 57762: Ensure that the WebSocket client correctly detects + when the connection to the server is dropped. (markt) +
  • +
  • Fix: + 57776: Revert the 8.0.21 fix for the + permessage-deflate implementation and incorrect op-codes + since the fix was unnecessary (the bug only affected trunk) and the fix + broke rather than fixed permessage-deflate if an + uncompressed message was converted into more than one compressed + message. (markt) +
  • +
  • Fix: + Fix log name typo in WsRemoteEndpointImplServer class, + caused by a copy-paste. (markt/kkolinko) +
  • +
  • Fix: + 57788: Avoid NPE when looking up a class hierarchy without + finding anything. (remm) +
  • +
+
+

Web applications

+
    +
  • Add: + 57759: Add information to the keyAlias documentation to make + it clear that the order keys are read from the keystore is + implementation dependent. (markt) +
  • +
  • Fix: + 57864: Update the documentation web application to make it + clearer that hex values are not valid for cluster send options. Based on + a patch by Kyohei Nakamura. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Fix a concurrency issue when a backup message that has all session data + and a backup message that has diff data are processing at the same time. + This fix ensures that MapOwner is set to + ReplicatedMapEntry. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + Add missing pom for tomcat-storeconfig. (remm) +
  • +
  • Update: + Update optional Checkstyle library to 6.5. (kkolinko) +
  • +
  • Fix: + 57707: Improve error message when trying to run a release + build on a non-Windows platform and Wine is not available. (markt) +
  • +
+
+

2015-03-26 Tomcat 8.0.21 (markt)

+

Catalina

+
    +
  • Add: + 49785: Enable StartTLS connections for JNDIRealm. + (fschumacher) +
  • +
  • Fix: + When docBase refers internal war and unpackWARs is set to false, avoid + registration of the invalid redeploy resource that has been added ".war" + extension in duplicate. (kfujino) +
  • +
  • Fix: + If WAR exists, it is not necessary to trigger a reload when adding a + Directory. (kfujino) +
  • +
  • Fix: + 55988: Add support for Java 8 JSSE server-preferred TLS + cipher suite ordering. This feature requires Java 8 + and is controlled by useServerCipherSuitesOrder + attribute on an HTTP connector. + Based upon a patch provided by Ognjen Blagojevic. (schultz) +
  • +
  • Fix: + 56608: When deploying an external WAR, add watched resources + in the expanded directory based on whether the expanded directory is + expected to exist rather than if it does exist. (markt) +
  • +
  • Fix: + When triggering a reload due to a modified watched resource, ensure + that multiple changed watched resources only trigger one reload rather + than a series of reloads. (markt) +
  • +
  • Fix: + 57601: Ensure that HEAD requests return the correct content + length (i.e. the same as for a GET) when the requested resource includes + a resource served by the Default servlet. (jboynes/markt) +
  • +
  • Fix: + 57602: Ensure that HEAD requests return the correct content + length (i.e. the same as for a GET) when the requested resource includes + a resource served by a servlet that extends HttpServlet. + (markt) +
  • +
  • Fix: + 57621: When an async request completes, ensure that any + remaining request body data is swallowed. (markt) +
  • +
  • Fix: + 57637: Do not create unnecessary sessions when using + PersistentValve. (jboynes/fschumacher) +
  • +
  • Fix: + 57645: Correct a regression in the fix for + 57190 that incorrectly required the path passed to + ServletContext.getContext(String) to be an exact match to a + path to an existing context. (markt) +
  • +
  • Fix: + Make sure that unpackWAR attribute of Context + is handled correctly in HostConfig. (kfujino) +
  • +
  • Fix: + When deploying a WAR file that contains a context.xml file and + unpackWARs is false ignore any context.xml + file that may exist in an expanded directory associated with the WAR. + (markt) +
  • +
  • Fix: + 57675: Correctly quote strings when using the extended + access log. (markt) +
  • +
  • Add: + Enable Tomcat to detect when a WAR file has been changed while Tomcat is + not running. Tomcat does this by adding a META-INF/war-tracking file to + the expanded directory and setting the last modified time of this file + to the last modified time of the WAR. If Tomcat detects a modified WAR + via this mechanism the web application will be redeployed (i.e. the + expanded directory will be removed and the modified WAR expanded in its + place). (markt) +
  • +
  • Fix: + 57704: Fix potential NPEs during web application start/stop + when org.apache.tomcat.InstanceManager is not initialized. + (violetagg) +
  • +
  • Add: + Use the simplified digest output for digest.bat|sh when generating + digests with no salt and a single iteration to make it easier to use + with DIGEST authentication. (markt) +
  • +
  • Fix: + Add support for LAST_ACCESS_AT_START system property to + SingleSignOn. (kfujino) +
  • +
  • Code: + Refactor Authenticator implementations to reduce code duplication. + (markt) +
  • +
  • Fix: + 57724: Handle the case in the CORS filter where a user agent + includes an origin header for a non-CORS request. (markt) +
  • +
  • Fix: + When searching for SCIs + o.a.catalina.Context.getParentClassLoader will be used + instead of java.lang.ClassLoader.getParent. Thus one can + provide the correct parent class loader when running embedded Tomcat in + other environments such as OSGi. (violetagg) +
  • +
  • Fix: + 57743: Fix a locked file / resource leak issue when a JAR is + accessed just before or during web application undeploy. Patch provided + by Pavel Avgustinov. (markt) +
  • +
+
+

Coyote

+
    +
  • Add: + 57540: Make TLS/SSL protocol available in a new request + attribute + (org.apache.tomcat.util.net.secure_protocol_version). + (Note that AJP connectors will require mod_jk 1.2.41 or later, + or an as-yet-unknown version of mod_proxy_ajp, or configure the proxy + to send the AJP_SSL_PROTOCOL request attribute to Tomcat. Please see + the bug comments for details.) + Based upon a patch provided by Ralf Hauser. (schultz) +
  • +
  • Fix: + Fix a cipher ordering issue when using the OpenSSL syntax for JSSE + cipher configuration to ensure that ephemeral ECDH with AES is preferred + to ephemeral ECDH with anything else. (markt) +
  • +
  • Fix: + 57570: Make the processing of trailer headers with chunked + input optional and disabled by default. (markt) +
  • +
  • Fix: + 57592: Correctly handle the case where an + AsyncContext is used for non-blocking I/O and is completed + during a write operation. (markt) +
  • +
  • Fix: + 57638: Avoid an IllegalArgumentException when an AJP request + body chunk larger than the socket read buffer is being read. This + typically requires a larger than default AJP packetSize. (markt) +
  • +
  • Fix: + 57674: Avoid a BufferOverflowException when an AJP response + body chunk larger than the socket write buffer is being written. This + typically requires a larger than default AJP packetSize. (markt) +
  • +
  • Update: + Align the OpenSSL syntax cipher configuration with the OpenSSL 1.0.2 + branch. (markt) +
  • +
  • Fix: + Numerous fixes to the APR/native connector to improve robustness. + (markt) +
  • +
  • Fix: + Stop caching and re-using SocketWrapper instances. With the introduction + of upgrade and non-blocking I/O, I/O can occur on non-container threads. + This makes it nearly impossible to track whether a SocketWrapper is + still being referenced or not, making re-use a risky proposition. + (markt) +
  • +
  • Code: + Refactor Connector authentication (only used by AJP) into a separate + method. (markt) +
  • +
  • Add: + 57708: Implement a new feature for AJP connectors - Tomcat + Authorization. If the new tomcatAuthorization attribute is set to + true (it is disabled by default) Tomcat will take an + authenticated user name from the AJP protocol and use the appropriate + Realm for the request to authorize (i.e. add roles) to that user. + (markt) +
  • +
  • Fix: + Fix an issue that meant that any pipe-lined data read by Tomcat before + an asynchronous request completed was lost during the completion of the + asynchronous request. This mean that the pipe-lined request(s) would be + lost and/or corrupted. (markt) +
  • +
  • Update: + Update the minimum recommended version of the Tomcat Native library (if + used) to 1.1.33. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57135: Package imports via + javax.el.ImportHandler should only import public, concrete + classes. (markt) +
  • +
  • Fix: + 57583: Cache 'Not Found' results in + javax.el.ImportHandler.resolveClass() to save repeated + attempts to load classes that are known not to exist to improve + performance. (markt) +
  • +
  • Fix: + 57626: Correct a regression introduced in the 8.0.16 fix for + ensuring Jars were closed after use, that broke recompilation of + modified JSPs that depended on a tag file packaged in a Jar. (markt) +
  • +
  • Fix: + 57627: Correctly determine last modified times for + dependencies when a tag file packaged in a JAR depends on a tag file + packaged in a second JAR. (markt) +
  • +
  • Fix: + 57647: Ensure INFO message is logged when scanning jars for + TLDs if the scan does not find a TLD in any jar. Previously a message + would only be logged if a TLD was not found in all scanned jars. (jboynes) +
  • +
  • Update: + 57662: Update all references to the ECJ compiler to version + 4.4.2. (violetagg) +
  • +
+
+

Cluster

+
    +
  • Fix: + Remove unnecessary method that always returns true. The domain filtering + works on DomainFilterInterceptor. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Correct a bug in the permessage-deflate implementation that + meant that the incorrect op-codes were used if an uncompressed message + was converted into more than one compressed message. (markt) +
  • +
  • Add: + 57676: List conflicting WebSocket endpoint classes when + there is a path conflict. Based upon a patch proposed by yangkun. + (schultz) +
  • +
+
+

Web applications

+
    +
  • Fix: + 56058: Add links to the AccessLogValve documentation for + configuring reverse proxies and/or Tomcat to ensure that the desired + information is used entered in the access log when Tomcat is running + behind a reverse proxy. (markt) +
  • +
  • Fix: + 57587: Update the JNDI Datasource HOWTO for DBCP2. Patch + provided by Phil Steitz. (markt) +
  • +
  • Fix: + Remove incorrect note from context configuration page in the + documentation web application that stated WAR files located outside the + appBase were never unpacked. (markt) +
  • +
  • Update: + 57644: Update examples to use Apache Standard Taglib 1.2.5. + (jboynes) +
  • +
  • Fix: + 57683: Ensure that if a client aborts their connection to the + stock ticker example (the only way a client can disconnect), the example + continues to work for existing and new clients. (markt) +
  • +
  • Fix: + Make it clear that when using digested passwords with DIGEST + authentication that no salt and only a single iteration must be used + when generating the digest. (markt) +
  • +
+
+

Extras

+
    +
  • Fix: + 57377: Remove the restriction that prevented the use of SSL + when specifying a bind address with the JMXRemoteLifecycleListener. Also + enable SSL to be configured for the registry as well as the server. + (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + When a map member has been added to ReplicatedMap, make + sure to add it to backup nodes list of all other members. (kfujino) +
  • +
  • Fix: + Make sure that refuse the messages from a different domain in + DomainFilterInterceptor. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + Update optional Checkstyle library to 6.4.1. (kkolinko) +
  • +
  • Fix: + 57703: Update the http-method definition for + web applications using a Servlet 2.5 descriptor as per Servlet 2.5 MR 6. + (markt) +
  • +
  • Update: + Update to Tomcat Native Library version 1.1.33 to pick up the Windows + binaries that are based on OpenSSL 1.0.1m and APR 1.5.1. (markt) +
  • +
+
+

2015-02-20 Tomcat 8.0.20 (markt)

+

Coyote

+
    +
  • Fix: + Fix a concurrency issue that meant that a change in socket timeout (e.g. + when switching to asynchronous I/O) did not always take effect + immediately. (markt) +
  • +
+
+

not released Tomcat 8.0.19 (markt)

+

Catalina

+
    +
  • Fix: + Clarify threaded usage of variables by removing volatile marker + in NonceInfo. Issue reported by Coverity Scan. (fschumacher) +
  • +
  • Fix: + 57180: Further fixes to support the use of arbitrary HTTP + methods with the CORS filter. (markt) +
  • +
  • Fix: + 57472: Fix performance regression in resources implementation + when signed JARs are used in a web application. (markt) +
  • +
  • Add: + Warn about problematic setting of appBase. (fschumacher) +
  • +
  • Fix: + Fix exception while authentication in JDBCRealm. (fschumacher) +
  • +
  • Fix: + 57534: CORS Filter should only look at media type component of + Content-Type request header. (markt) +
  • +
  • Fix: + 57556: Align getRealPath() behaviour with that + of earlier versions and include a trailing separator if the real path + refers to a directory. (markt) +
  • +
  • Fix: + Ensure that Servlet 3.0 async requests where startAsync() + is called in one container thread and dispatch() is called + in a different container thread complete correctly. (markt) +
  • +
  • Fix: + Ensure that user name checking in the optional SecurityListener is + case-insensitive (as documented) and than the case-insensitive + comparison is performed using the system default Locale. (markt) +
  • +
  • Add: + 57021: Improve logging in AprLifecycleListener and + jni.Library when Tomcat-Native DLL fails to load. Based on a patch by + Pravallika Peddi. (markt/kkolinko) +
  • +
+
+

Coyote

+
    +
  • Fix: + Fix several bugs that could cause multiple registrations for write + events for a single socket when using Servlet 3.0 async. Typically, the + side effects of these multiple registrations would be exceptions + appearing in the logs. (markt) +
  • +
  • Fix: + 57432: Align SSL_OP_NO_TLSv1_1 and + SSL_OP_NO_TLSv1_2 constant values with OpenSSL (they had + been swapped). (markt) +
  • +
  • Fix: + 57509: Improve length check when writing HTTP/1.1 + response headers: reserve space for 4 extra bytes. (kkolinko) +
  • +
  • Fix: + 57544: Fix potential infinite loop when preparing a kept + alive HTTP connection for the next request. (markt) +
  • +
  • Fix: + 57546: Ensure that a dropped network connection does not + leave references to the UpgradeProcessor associated with the connection + in memory. (markt) +
  • +
  • Fix: + When applying the maxSwallowSize limit to a connection read + that many bytes first before closing the connection to give the client a + chance to read the response. (markt) +
  • +
  • Fix: + Prevent an async timeout being processed multiple times for the same + socket when running on slow and/or heavily loaded systems. (markt) +
  • +
  • Fix: + 57581: Change statistics byte counter in coyote Request + object to be long to allow values above 2Gb. (kkolinko) +
  • +
  • Update: + Use the data that supports cipher definition using OpenSSL syntax to + improve the quality of values provided for the + javax.servlet.request.key_size request attribute. (markt) +
  • +
  • Fix: + Fix a concurrency issue in the APR Poller that meant it was possible + under low load for a socket queued to be added to the Poller not to be + added for 10 seconds. (markt) +
  • +
+
+

Jasper

+
    +
  • Update: + 57123: Update all references to the ECJ compiler to version + 4.4.1. With thanks to Ralph Schaer for uploading the 4.4.1 JAR to Maven + Central. (markt) +
  • +
  • Add: + 57564: Make JspC amenable to subclassing. Patch provided by + Jan Bartel. (markt) +
  • +
  • Fix: + Simplify code in ProtectedFunctionMapper class of + Jasper runtime. (kkolinko) +
  • +
  • Fix: + 57574: Do not check existence of a Java package in + javax.el.ImportHandler.importPackage(). (kkolinko) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 57490: Make it possible to use Tomcat's WebSocket client + within a web application when running under a SecurityManager. Based on + a patch by Mikael Sterner. (markt) +
  • +
  • Add: + Add some debug logging to the WebSocket session to track session + creation and session closure. (markt) +
  • +
+
+

Web applications

+
    +
  • Update: + Clarify documentation for useBodyEncodingForURI + attribute of a connector. (kkolinko) +
  • +
  • Fix: + Fix possible resource leaks by closing streams properly. Issues + reported by Coverity Scan. (fschumacher) +
  • +
  • Fix: + 57503: Make clear that the JULI integration for log4j only + works with log4j 1.2.x. (markt) +
  • +
  • Fix: + 57496: Remove hard-coded URL in JSP SVG example. (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + Fix a possible deadlock when receiver thread invokes + mapMemberAdded() while ping thread invokes + memberAlive(). (kfujino) +
  • +
+
+

Other

+
    +
  • Add: + Enhance bean factory used for JNDI resources. New attribute + forceString allows to support non-standard + string argument property setters. (rjung) +
  • +
  • Fix: + Assign newly created stream to field instead of leaking it uselessly. + Issue reported by Coverity Scan. (fschumacher) +
  • +
  • Update: + Update optional Checkstyle library to 6.3. (kkolinko) +
  • +
  • Fix: + Guard the digester from MbeansDescriptorsDigesterSource with its own + lock object. (fschumacher) +
  • +
  • Fix: + Refactor the unit tests and add some new test properties to make it + easier to exclude performance tests and relax timing tests. This is + primarily for the ASF CI system where these tests frequently fail. + (markt) +
  • +
  • Fix: + 57558: Add missing JAR in Ant task definition required by + the validate task. (markt) +
  • +
  • Add: + List names of Testsuites that have failed or skipped tests when + running the tests with Ant. (kkolinko) +
  • +
+
+

2015-01-26 Tomcat 8.0.18 (markt)

+

Catalina

+
    +
  • Fix: + 57178: The CORS filter now treats null as a + valid origin that matches *. Patch provided by Gregor + Zurowski. (markt) +
  • +
  • Fix: + 57425: Don't add attributes with null value or name to the + replicated context. (fschumacher) +
  • +
  • Add: + 57431: Enable usage of custom class for context creation when + using embedded tomcat. (fschumacher) +
  • +
  • Fix: + 57446: Ensure that ServletContextListeners that + have limited access to ServletContext methods are called + with the same ServletContext instance for both + contextInitialized() and contextDestroyed(). + (markt) +
  • +
  • Fix: + 57455: Explicitly block the use of the double-quote character + when configuring the common, server and shared class loaders since + double-quote is used to quote values that contain commas. (markt) +
  • +
  • Fix: + 57461: When an instance of + org.apache.catalina.startup.VersionLoggerListener logs the + result of System.getProperty("java.home") don't report it + in a manner that makes it look like the JAVA_HOME + environment variable. (markt) +
  • +
  • Fix: + 57476: Ensure the responses written as part of a forward are + fully written. This fixes a regression in 8.0.15 caused by the fix for + 57252. (markt) +
  • +
  • Fix: + While closing streams for given resources ensure that if an exception + happens it will be handled properly. Issue is reported by Coverity Scan. + (violetagg) +
  • +
  • Fix: + 57481: Fix IllegalStateException at the end of + the request when using non-blocking reads with the HTTP BIO connector. + (markt) +
  • +
  • Fix: + Change Response to use UEncoder instances with shared safeChars. + (fschumacher) +
  • +
  • Fix: + Ensure that when static resources are served from JARs, only static + resources are served. (markt) +
  • +
  • Add: + Allow VersionLoggerListener to log all system properties. + This feature is off by default. (kkolinko) +
  • +
+
+

Jasper

+
    +
  • Fix: + Ensure that classes imported via the page directive are made available + to the EL environment via the ImportHandler. Issue is reported by + Coverity Scan. (violetagg) +
  • +
  • Fix: + 57441: Do not trigger an error when using functions defined + by lambdas or imported via an ImportHandler in an EL expression in a + JSP. (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Fix mbean descriptor of ClusterSingleSignOn. (kfujino) +
  • +
  • Fix: + 57473: Add sanity check to FarmWebDeployer's WarWatcher to + detect suspected incorrect permissions on the watch directory. (schultz) +
  • +
+
+

Tribes

+
    +
  • Fix: + Clarify the handling of Copy message and Copy nodes. (kfujino) +
  • +
  • Fix: + Copy node does not need to send the entry data. It is enough to send + only the node information of the entry. (kfujino) +
  • +
  • Fix: + ReplicatedMap should send the Copy message when replicating. (kfujino) +
  • +
  • Fix: + Fix behavior of ReplicatedMap when member has disappeared. If map entry + is primary, rebuild the backup members. If primary node of map entry has + disappeared, backup node is promoted to primary. (kfujino) +
  • +
+
+

2015-01-16 Tomcat 8.0.17 (markt)

+

Catalina

+
    +
  • Fix: + Correct a regression in the previous fix for 57252 that broke + request listeners for non-async requests that triggered an error that + was handled by the ErrorReportingValve. (markt/violetagg) +
  • +
+
+

Coyote

+
    +
  • Fix: + Add flushing to send ack in the NIO2 connector. (remm) +
  • +
+
+

not released Tomcat 8.0.16 (markt)

+

Catalina

+
    +
  • Fix: + 57172: Provide a better error message if something attempts to + access a resource through a web application class loader that has been + stopped. (markt/kkolinko) +
  • +
  • Fix: + 57173: Revert the fix for 56953 that broke + annotation scanning in some cases. (markt) +
  • +
  • Fix: + 57180: Do not limit the CORS filter to only accepting + requests that use an HTTP method defined in RFC 7231. (markt) +
  • +
  • Fix: + 57190: Fix ServletContext.getContext(String) + when parallel deployment is used so that the correct ServletContext is + returned. (markt) +
  • +
  • Fix: + 57208: Prevent NPE in JNDI Realm when no results are found + in a directory context for a user with specified user name. Based on + a patch provided by Jason McIntosh. (violetagg) +
  • +
  • Add: + 57209: Add a new attribute, userSearchAsUser to the JNDI + Realm. (markt) +
  • +
  • Fix: + 57215: Ensure that the result of calling + HttpServletRequest.getContextPath() is neither decoded nor + normalized as required by the Servlet specification. (markt) +
  • +
  • Fix: + 57216: Improve handling of invalid context paths. A context + path should either be an empty string or start with a + '/' and do not end with a + '/'. Invalid context path are automatically + corrected and a warning is logged. The null and + "/" values are now correctly changed to + "". (markt/kkolinko) +
  • +
  • Fix: + Update storeconfig with the CredentialHandler element. (remm) +
  • +
  • Fix: + Correct message that is logged when load-on-startup servlet fails + to load. It was logging a wrong name. (kkolinko) +
  • +
  • Fix: + 57239: Correct several message typos. Includes patch by + vladk. (kkolinko) +
  • +
  • Fix: + Fix closing of Jars during annotation scanning. (schultz/kkolinko) +
  • +
  • Fix: + Fix a concurrency issue in async processing. Ensure that a non-container + thread can not change the async state until the container thread has + completed. (markt) +
  • +
  • Fix: + 57252: Provide application configured error pages with a + chance to handle an async error before the built-in error reporting. + (markt) +
  • +
  • Fix: + 57281: Enable non-public Filter and Servlet classes to be + configured programmatically via the Servlet 3.0 API and then used + without error when running under a SecurityManager. (markt) +
  • +
  • Fix: + 57308: Remove unnecessary calls to + System.getProperty() where more suitable API calls are + available. (markt) +
  • +
  • Add: + Add unit tests for RemoteAddrValve and RemoteHostValve. (rjung) +
  • +
  • Add: + Allow to configure RemoteAddrValve and RemoteHostValve to + adopt behavior depending on the connector port. Implemented + by optionally adding the connector port to the string compared + with the patterns allow and deny. Configured + using addConnectorPort attribute on valve. (rjung) +
  • +
  • Add: + Optionally trigger authentication instead of denial in + RemoteAddrValve and RemoteHostValve. This only works in + combination with preemptiveAuthentication + on the application context. Configured using + invalidAuthenticationWhenDeny attribute on valve. (rjung) +
  • +
  • Fix: + Remove the obsolete jndi protocol usage from the scanning + process performed by StandardJarScanner. (violetagg) +
  • +
  • Fix: + Prevent file descriptors leak and ensure that files are closed after + retrieving the last modification time. (violetagg) +
  • +
  • Update: + Make o.a.catalina.webresources.StandardRoot easier for + extending. (violetagg) +
  • +
  • Fix: + 57326: Enable AsyncListener implementations to + re-register themselves during AsyncListener.onStartAsync. + (markt) +
  • +
  • Fix: + 57331: Allow ExpiresFilter to use "year" as synonym for + "years" in its configuration. (kkolinko) +
  • +
  • Fix: + Ensure that if the RewriteValve rewrites a request that subsequent calls + to HttpServletRequest.getRequestURI() return the undecoded + URI. (markt) +
  • +
  • Fix: + Ensure that if the RewriteValve rewrites a request to a non-normalized + URI that the URI is normalized before the URI is mapped to ensure that + the correct mapping is applied. (markt) +
  • +
  • Fix: + Prevent NPEs being logged during post-processing for requests that have + been re-written by the RewriteValve. (markt) +
  • +
  • Fix: + Various StoreConfig improvements including removing a dependency on the + StandardServer implementation, improve consistency of + behaviour when MBean is not registered and improve error messages when + accessed via the Manager application. (markt) +
  • +
  • Update: + Improve SnoopServlet in unit tests. (rjung) +
  • +
  • Add: + Add RequestDescriptor class to unit tests. + Adjust TestRewriteValve to use RequestDescriptor. (rjung) +
  • +
  • Update: + Add more AJP unit tests. (rjung) +
  • +
  • Fix: + 57363: Log to stderr if LogManager is unable to read + configuration files rather than swallowing the exception silently. + (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Allow HTTP upgrade process to complete without data corruption when + additional content is sent along with the upgrade header. (remm) +
  • +
  • Fix: + 57187: Regression handling the special * URL. (remm) +
  • +
  • Fix: + 57234: Make SSL protocol filtering to remove insecure + protocols case insensitive. (markt) +
  • +
  • Fix: + 57265: Fix some potential concurrency issues with sendFile + and the NIO connector. (markt) +
  • +
  • Fix: + 57324: If the client uses Expect: 100-continue + and Tomcat responds with a non-2xx response code, Tomcat also closes the + connection. If Tomcat knows the connection is going to be closed when + committing the response, Tomcat will now also send the + Connection: close response header. (markt) +
  • +
  • Fix: + 57340: When using Comet, ensure that Socket and SocketWrapper + are only returned to their respective caches once on socket close (it is + possible for multiple threads to call close concurrently). (markt) +
  • +
  • Fix: + 57347: AJP response contains wrong status reason phrase + (rjung) +
  • +
  • Add: + 57391: Allow TLS Session Tickets to be disabled when using + the APR/native HTTP connector. Patch provided by Josiah Purtlebaugh. + (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57142: As per the clarification from the JSP specification + maintenance lead, classes and packages imported via the page directive + must be made available to the EL environment via the ImportHandler. + (markt) +
  • +
  • Fix: + 57247: Correct the default Java source and target versions in + the JspC usage message to 1.7 for Java 7. (markt) +
  • +
  • Fix: + 57309: Ensure that the current EL Resolver is given an + opportunity to perform type coercion before applying the default EL + coercion rules. (markt) +
  • +
  • Fix: + Improve the calculation of the resource's last-modified, performed by + JspCompilationContext, in a way to support URLs with protocol different + than jar:file. (violetagg) +
  • +
  • Fix: + CVE-2014-7810: + Do not use a privileged code block when evaluating EL expressions + when running under a security manager, which allowed to bypass code + restrictions. (markt) +
  • +
  • Fix: + Fix an issue with BeanELResolver when running under a security + manager. Some classes may not be accessible but may have accessible + interfaces. (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + In order to enable define in Cluster element, + ClusterSingleSignOn implements ClusterValve. + (kfujino) +
  • +
  • Fix: + 57338: Improve the ability of the + ClusterSingleSignOn valve to handle nodes being added and + removed from the Cluster at run time. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Correct multiple issues with the flushing of batched messages that could + lead to duplicate and/or corrupt messages. (markt) +
  • +
  • Fix: + Correctly implement headers case insensitivity. (markt/remm) +
  • +
  • Fix: + Allow optional use of user extensions. (remm) +
  • +
  • Fix: + Allow using partial binary message handlers. (remm) +
  • +
  • Fix: + Limit ping/pong message size. (remm) +
  • +
  • Fix: + Allow configuration of the time interval for the periodic event. (remm) +
  • +
  • Fix: + More accurate annotations processing. (remm) +
  • +
  • Fix: + Allow optional default for origin header in the client. (remm) +
  • +
+
+

Web applications

+
    +
  • Fix: + Update documentation for CGI servlet. Recommend to copy the servlet + declaration into web application instead of enabling it globally. + Correct documentation for cgiPathPrefix. (kkolinko) +
  • +
  • Update: + Improve HTML version of build instructions and align with + BUILDING.txt. (kkolinko) +
  • +
  • Update: + Improve Tomcat Manager documentation. Rearrange, add section on + HTML GUI, document /expire command and Server Status page. (kkolinko) +
  • +
  • Update: + 57238: Update information on SSL/TLS on Security and SSL + documentation pages. Patch by Glen Peterson. (kkolinko) +
  • +
  • Fix: + 57245: Correct the reference to allowLinking in + the security configuration guide since that attribute has moved from the + Context element to the nested Resources element. (markt) +
  • +
  • Fix: + Fix ambiguity of section links on Valves configuration reference page. + (kkolinko) +
  • +
  • Fix: + 57261: Fix vminfo and threaddump Manager commands to start + their output with an "OK" line. Document them. Based on a patch by + Oleg Trokhov. (kkolinko) +
  • +
  • Fix: + 57267: Document the StoreConfigLifecycleListener + and the /save command for the Manager application. (markt) +
  • +
  • Fix: + 57323: Correct display of outdated sessions in sessions + count listing in Manager application. (kkolinko) +
  • +
  • Add: + Add document of ClusterSingleSignOn. (kfujino) +
  • +
+
+

Other

+
    +
  • Update: + When downloading required libraries at build time, use random name + for temporary file and automatically create destination directory + (base.path). (kkolinko) +
  • +
  • Update: + Update optional Checkstyle library to 6.2. (kkolinko) +
  • +
  • Update: + Simplify setproxy task in build.xml. + Taskdef there is not needed since Ant 1.8.2. (kkolinko) +
  • +
  • Fix: + Update "ide-eclipse" target in build.xml to create Eclipse + project that uses Java 7 compliance settings instead of workspace-wide + defaults. (kkolinko) +
  • +
  • Fix: + Update the package renamed copy of Apache Commons Pool 2 to the 2.3 + release to pick up various fixes since the 2.2 release including one for + a possible infinite loop. (markt) +
  • +
  • Fix: + 57285: Restore the manifest entry that marks the Windows + uninstaller application as requiring elevated privileges. (markt) +
  • +
  • Add: + 57344: Provide sha1 checksum files for Tomcat downloads. + Correct filename patterns for apache-tomcat-*-embed.tar.gz archive + to exclude an *.asc file. (kkolinko) +
  • +
+
+

2014-11-07 Tomcat 8.0.15 (markt)

+

Catalina

+
    +
  • Add: + 43548: Add an XML schema for the tomcat-users.xml file. + (markt) +
  • +
  • Add: + 43682: Add support for referring to the current context, host + and service name in per Context logging.properties files by using the + properties ${classloader.webappName}, + ${classloader.hostName} and + ${classloader.serviceName}. (markt) +
  • +
  • Add: + 47919: Extend the information logged when Tomcat starts to + optionally log the values of command line arguments (enabled by + default) and environment variables (disabled by default). Note that + the values added to CATALINA_OPTS and JAVA_OPTS environment variables + will be logged, as they are used to build up the command line. (markt) +
  • +
  • Add: + 49939: Expose the method that clears the static resource + cache for a web application via JMX. (markt) +
  • +
  • Fix: + 55951: Allow cookies to use UTF-8 encoded values in HTTP + headers. This requires the use of the RFC6265 + CookieProcessor. (markt) +
  • +
  • Fix: + 55984: Using the allow separators in version 0 cookies option + with the legacy cookie processor should only apply to version 0 cookies. + Version 1 cookies with values that contain separators should not be + affected and should continue to be quoted. (markt) +
  • +
  • Add: + 56393: Add support for RFC6265 cookie parsing and generation. + This is currently disabled by default and may be enabled via the + CookieProcessor element of a Context. + (markt) +
  • +
  • Add: + 56394: Introduce new configuration element CookieProcessor in + Context to allow context-specific configuration of cookie processing + options. Attributes of Context element that were added in Tomcat 8.0.13 + to allow configuration of a new experimental RFC6265 based cookie parser + (useRfc6265 and cookieEncoding) are + replaced by this new configuration element. (markt) +
  • +
  • Fix: + Improve the previous fix for 56401. Avoid logging version + information in the constructor since it then gets logged at undesirable + times such as when using StoreConfig. (markt) +
  • +
  • Fix: + 56403: Add pluggable password derivation support to the + Realms via the new CredentialHandler interface. + (markt/schultz) +
  • +
  • Fix: + 57016: When using the PersistentValve do not + remove sessions from the store when persisting them. (markt) +
  • +
  • Add: + Deprecate the use of system properties to control cookie parsing and + replace them with attributes on the new CookieProcessor + that may be configured on a per context basis. (markt) +
  • +
  • Fix: + Correct an edge case and allow a cookie if the value starts with an + equals character and the CookieProcessor is not configured + to allow equals characters in cookie values but is configured to allow + name only cookies. (markt) +
  • +
  • Fix: + 57022: Ensure SPNEGO authentication continues to work with + the JNDI Realm using delegated credentials with recent Oracle JREs. + (markt) +
  • +
  • Fix: + 57027: Add additional validation for stored credentials used + by Realms when the credential is stored using hex encoding. (markt) +
  • +
  • Fix: + 57038: Add a WebResource.getCodeBase() method, + implement for all WebResource implementations and then use + it in the web application class loader to set the correct code base for + resources loaded from JARs and WARs. (markt) +
  • +
  • Fix: + Correct a couple of NPEs in the JNDI Realm that could be triggered with + when not specifying a roleBase and enabling roleSearchAsUser. (markt) +
  • +
  • Fix: + Correctly handle relative values for the docBase attribute of a Context. + (markt) +
  • +
  • Fix: + Ensure that log messages generated by the web application class loader + correctly identify the associated Context when multiple versions of a + Context with the same path are present. (markt) +
  • +
  • Fix: + Remove the unnecessary registration of context.xml as a redeploy + resource. The context.xml having an external docBase has already been + registered as a redeploy resource at first. (kfujino) +
  • +
  • Fix: + 57089: Ensure that configuration of a session ID generator is + not lost when a web application is reloaded. (markt) +
  • +
  • Fix: + 57105: When parsing web.xml do not limit the buffer element + of the jsp-property-group element to integer values as the allowed + values are <number>kb or none. (markt) +
  • +
  • Update: + Update the minimum required version of the Tomcat Native library (if + used) to 1.1.32. (markt) +
  • +
  • Fix: + Update storeconfig with newly introduced elements: SessionIdGenerator, + CookieProcessor, JarScanner and JarScanFilter. (remm) +
  • +
  • Fix: + Throw a NullPointerException if a null string is passed to + the write(String,int,int) method of the + PrintWriter obtained from the ServletResponse. + (markt) +
  • +
  • Fix: + Cookie rewrite flag abbreviation should be CO rather than C. (remm) +
  • +
  • Fix: + 57153: When the StandardJarScanner is configured to scan the + full class path, ensure that class path entries added directly to the + web application class loader are scanned. (markt) +
  • +
  • Fix: + AsyncContext should remain usable until fireOnComplete is called. (remm) +
  • +
  • Fix: + AsyncContext createListener should wrap any instantiation exception + using a ServletException. (remm) +
  • +
  • Fix: + 57155: Allow a web application to be configured that does not + have a docBase on the file system. This is primarily intended for use + when embedding. (markt) +
  • +
  • Fix: + Propagate header ordering from fileupload to the part implementation. + (remm) +
  • +
+
+

Coyote

+
    +
  • Add: + 53952: Add support for TLSv1.1 and TLSv1.2 for APR connector. + Based upon a patch by Marcel Å ebek. This feature requires + Tomcat Native library 1.1.32 or later. (schultz/jfclere) +
  • +
  • Code: + Cache the Encoder instances used to convert Strings to byte + arrays in the Connectors (e.g. when writing HTTP headers) to improve + throughput. (markt) +
  • +
  • Add: + Disable SSLv3 by default for JSSE based HTTPS connectors (BIO, NIO and + NIO2). The change also ensures that SSLv2 is disabled for these + connectors although SSLv2 should already be disabled by default by the + JRE. (markt) +
  • +
  • Add: + Disable SSLv3 by default for the APR/native HTTPS connector. (markt) +
  • +
  • Fix: + Do not increase remaining counter at end of stream in + IdentityInputFilter. (kkolinko) +
  • +
  • Fix: + Trigger an error if an invalid attempt is made to use non-blocking IO. + (markt) +
  • +
  • Fix: + 57157: Allow calls to + AsyncContext.start(Runnable) during non-blocking IO reads + and writes. (markt) +
  • +
  • Fix: + Async state MUST_COMPLETE should still be started. (remm) +
  • +
+
+

Jasper

+
    +
  • Fix: + 57099: Ensure that semi-colons are not permitted in JSP + import page directives. (markt) +
  • +
  • Fix: + 57113: Fix broken package imports in Expression Language when + more than one package was imported and the desired class was not in the + last package imported. (markt) +
  • +
  • Fix: + 57132: Fix import conflicts reporting in Expression Language. + (kkolinko) +
  • +
  • Fix: + When coercing an object to a given type, only attempt coercion to an + array if both the object type and the target type are an array type. + (violetagg/markt) +
  • +
  • Fix: + Improve handling of invalid input to + javax.el.ImportHandler.resolveClass(). (markt) +
  • +
  • Fix: + Allow the same class to be added to an instance of + javax.el.ImportHandler more than once without triggering + an error. The second and subsequent calls for the same class will be + ignored. (markt) +
  • +
  • Fix: + 57136: Ensure only \${ and \#{ are + treated as escapes for ${ and #{ rather than + \$ and \# being treated as escapes for + $ and # when processing literal expressions in + expression language. (markt) +
  • +
  • Fix: + When coercing an object to an array type in Expression Language, handle + the case where the source object is an array of primitives. + (markt/kkolinko) +
  • +
  • Fix: + Do not throw an exception on missing JSP file servlet initialization. + (remm) +
  • +
  • Fix: + 57148: When coercing an object to a given type and a + PropertyEditor has been registered for the type correctly + coerce the empty string to null if the + PropertyEditor throws an exception. (kkolinko/markt) +
  • +
  • Fix: + 57153: Correctly scan for TLDs located in directories that + represent expanded JARs files that have been added to the web application + class loader's class path. (markt) +
  • +
  • Fix: + 57141: Enable EL in JSPs to refer to static fields of + imported classes including the standard java.lang.* + imports. (markt) +
  • +
+
+

Cluster

+
    +
  • Fix: + Add support for the SessionIdGenerator to cluster manager + template. (kfujino) +
  • +
  • Fix: + Avoid possible integer overflows reported by Coverity Scan. (fschumacher) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 57054: Correctly handle the case in the WebSocket client + when the HTTP response to the upgrade request can not be read in a + single pass; either because the buffer is too small or the server sent + the response in multiple packets. (markt) +
  • +
  • Add: + Extend support for the permessage-deflate extension to the + client implementation. (markt) +
  • +
  • Fix: + Fix client subprotocol handling. (remm) +
  • +
  • Fix: + Add null checks for arguments in remote endpoint. (remm/kkolinko) +
  • +
  • Fix: + 57091: Work around the behaviour of the Oracle JRE when + creating new threads in an applet environment that breaks the WebSocket + client implementation. Patch provided by Niklas Hallqvist. (markt) +
  • +
  • Fix: + 57118: Ensure that that an EncodeException is + thrown by RemoteEndpoint.Basic.sendObject(Object) rather + than an IOException when no suitable Encoder + is configured for the given Object. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct a couple of broken links in the Javadoc. (markt) +
  • +
  • Fix: + Correct documentation for ServerCookie.ALLOW_NAME_ONLY + system property. (kkolinko) +
  • +
  • Fix: + 57049: Clarified that jvmRoute can be set in + <Engine>'s jvmRoute or in a system + property. (schultz) +
  • +
  • Fix: + Correct version of Java WebSocket mentioned in documentation + (s/1.0/1.1/). (markt/kkolinko) +
  • +
  • Update: + Suppress timestamp comments in Javadoc. (kkolinko) +
  • +
  • Fix: + 57147: Various corrections to the JDBC Store section of the + session manager configuration page of the documentation web application. + (markt) +
  • +
+
+

Tribes

+
    +
  • Fix: + 45282: Improve shutdown of NIO receiver so that sockets are + closed cleanly. (fhanik/markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 57005: Fix javadoc errors when building with Java 8. Patch + provided by Pierre Viret. (markt) +
  • +
  • Fix: + 57079: Use Tomcat version number for jdbc-pool module when + building and shipping the module as part of Tomcat. (markt) +
  • +
  • Fix: + Fix broken overview page in javadoc generated via "javadoc" task in + jdbc-pool build.xml file. (kkolinko) +
  • +
+
+

Other

+
    +
  • Fix: + 56079: The uninstaller packaged with the Apache Tomcat + Windows installer is now digitally signed. (markt) +
  • +
  • Fix: + Fix timestamps in Tomcat build and jdbc-pool to use 24-hour format + instead of 12-hour one and use UTC timezone. (markt/kkolinko) +
  • +
  • Fix: + Update the package renamed copy of Apache Commons DBCP 2 to revision + 1631450 to pick up additional fixes since the 2.0.1 release including + Javadoc corrections to fix errors when compiling with Java 8. (markt) +
  • +
  • Update: + 56596: Update to Tomcat Native Library version 1.1.32 to + pick up the Windows binaries that are based on OpenSSL 1.0.1j and APR + 1.5.1. (markt) +
  • +
  • Code: + In Tomcat tests: log name of the current test method at start time. + (kkolinko) +
  • +
+
+

2014-09-29 Tomcat 8.0.14 (markt)

+

Other

+
    +
  • Fix: + 56079: The Apache Tomcat Windows installer, the Apache Tomcat + Windows service and the Apache Tomcat Windows service monitor + application are now digitally signed. (markt) +
  • +
+
+

not released Tomcat 8.0.13 (markt)

+

Catalina

+
    +
  • Fix: + 55917: Allow bytes in the range 0x80 to 0xFF to appear in + cookie values if the cookie is a V1 (RFC2109) cookie and the value is + correctly quoted. The new RFC6265 based cookie parser must be enabled to + correctly handle these cookies. (markt) +
  • +
  • Fix: + 55918: Do not permit control characters to appear in quoted + V1 (RFC2109) cookie values. The new RFC6265 based cookie parser must be + enabled to correctly handle these cookies. (markt) +
  • +
  • Fix: + 55921: Correctly handle (ignore the cookie) unescaped JSON in + a cookie value. The new RFC6265 based cookie parser must be enabled to + correctly handle these cookies. (markt) +
  • +
  • Add: + 56401: Log version information when Tomcat starts. + (markt/kkolinko) +
  • +
  • Add: + 56530: Add a web application class loader implementation that + supports the parallel loading of web application classes. (markt) +
  • +
  • Fix: + 56900: Fix some potential resource leaks when reading + property files reported by Coverity Scan. Based on patches provided by + Felix Schumacher. (markt) +
  • +
  • Fix: + 56902: Fix a potential resource leak in the Default Servlet + reported by Coverity Scan. Based on a patch provided by Felix + Schumacher. (markt) +
  • +
  • Fix: + 56903: Correct the return value for + StandardContext.getResourceOnlyServlets() so that multiple + names are separated by commas. Identified by Coverity Scan and fixed + based on a patch by Felix Schumacher. (markt) +
  • +
  • Add: + Add an additional implementation of a RFC6265 based cookie parser along + with new Context options to select and configure it. This parser is + currently considered experimental and is not used by default. (markt) +
  • +
  • Fix: + Fixed the multipart elements merge operation performed during web + application deployment. Identified by Coverity Scan. (violetagg) +
  • +
  • Fix: + Correct the information written by + ExtendedAccessLogValve when a format token x-O(XXX) is + used so that multiple values for a header XXX are separated by commas. + Identified by Coverity Scan. (violetagg) +
  • +
  • Fix: + Fix a potential resource leak when reading MANIFEST.MF file for + extension dependencies reported by Coverity Scan. (violetagg) +
  • +
  • Fix: + Fix some potential resource leaks when reading properties, files and + other resources. Reported by Coverity Scan. (violetagg) +
  • +
  • Fix: + Correct the previous fix for 56825 that enabled pre-emptive + authentication to work with the SSL authenticator. (markt) +
  • +
  • Code: + Refactor to reduce code duplication identified by Simian. (markt) +
  • +
  • Fix: + When using parallel deployment and undeployOldVersions + feature is enabled on a Host, correctly undeploy context of old + version. Make sure that Tomcat does not undeploy older Context if + current context is not running. (kfujino) +
  • +
  • Fix: + Fix a rare threading issue when locking resources via WebDAV. + (markt) +
  • +
  • Fix: + Fix a rare threading issue when using HTTP digest authentication. + (markt) +
  • +
  • Fix: + When deploying war, add XML file in the config base to the redeploy + resources if war does not have META-INF/context.xml or + deployXML is false. If XML file is created in the config + base, redeploy will occur. (kfujino) +
  • +
  • Code: + Various changes to reduce unnecessary code in Tomcat's copy of + Apache Commons BCEL to reduce the time taken for annotation scanning + when web applications start. Includes contributions from kkolinko and + hzhang9. (markt) +
  • +
  • Fix: + 56938: Ensure web applications that have mixed case context + paths and are deployed as directories are correctly removed on undeploy + when running on a case sensitive file system. (markt) +
  • +
  • Add: + 57004: Add stuckThreadCount property to + StuckThreadDetectionValve's JMX bean. Patch provided by + JiÅ™í Pejchal. (schultz) +
  • +
  • Fix: + 57011: Ensure that the request and response are correctly + recycled when processing errors during async processing. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 56910: Prevent the invalid value of -1 being + used for maxConnections with APR connectors. (markt) +
  • +
  • Fix: + Ensure that AJP connectors enable the KeepAliveTimeout. + (kfujino) +
  • +
  • Fix: + Reduce duplicated code. All AJP connectors use common method to + configuration of processor. (kfujino) +
  • +
+
+

Jasper

+
    +
  • Fix: + 43001: Enable the JspC Ant task to set the JspC option + mappedFile. (markt) +
  • +
  • Fix: + Ensure that the implementation of + javax.servlet.jsp.PageContext.include(String) + and + javax.servlet.jsp.PageContext.include(String, boolean) + will throw IOException when an I/O error occur during + the operation. (violetagg) +
  • +
  • Fix: + 56908: Fix some potential resource leaks when reading + jar files. Reported by Coverity Scan. Patch provided by Felix + Schumacher. (violetagg) +
  • +
  • Fix: + Fix a potential resource leak in JDTCompiler when checking whether + a resource is a package. Reported by Coverity Scan. (fschumacher) +
  • +
  • Fix: + 56991: Deprecate the use of a request attribute to pass a + <jsp-file> declaration to Jasper and prevent an infinite loop + if this technique is used in conjunction with an include. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 56905: Make destruction on web application stop of thread + group used for WebSocket connections more robust. (kkolinko/markt) +
  • +
  • Fix: + 56907: Ensure that client IO threads are stopped if a secure + WebSocket client connection fails. (markt) +
  • +
  • Fix: + 56982: Return the actual negotiated extensions rather than an + empty list for Session.getNegotiatedExtensions(). (markt) +
  • +
  • Update: + Update the WebSocket implementation to support the Java WebSocket + specification version 1.1. (markt) +
  • +
+
+

Web applications

+
    +
  • Add: + Add JarScanner to the nested components listed for a + Context. (markt) +
  • +
  • Update: + Update the Windows authentication documentation after some additional + testing to answer the remaining questions. (markt) +
  • +
+
+

Other

+
    +
  • Fix: + 56895: Correctly compose JAVA_OPTS in + catalina.bat so that escape sequences are preserved. Patch + by Lucas Theisen. (markt) +
  • +
  • Update: + 56988: Allow to use relative path in base.path + setting when building Tomcat. (kkolinko) +
  • +
  • Fix: + 56990: Ensure that the ide-eclipse build target + downloads all the libraries required by the default Eclipse + configuration files. (markt) +
  • +
  • Fix: + Update the package renamed copy of Apache Commons DBCP 2 to revision + 1626988 to pick up the fixes since the 2.0.1 release including support + for custom eviction policies. (markt) +
  • +
  • Fix: + Update the package renamed copy of Apache Commons Pool 2 to revision + 1627271 to pick up the fixes since the 2.2 release including some memory + leak fixes and support for application provided eviction policies. + (markt) +
  • +
+
+

2014-09-03 Tomcat 8.0.12 (markt)

+

Catalina

+
    +
  • Add: + Make the session id generator extensible by adding a + SessionIdGenerator interface, an abstract + base class and a standard implementation. (rjung) +
  • +
  • Fix: + 56882: Fix regression in processing of includes and forwards + when Context have been reloaded. Tomcat was responding with HTTP Status + 503 (Servlet xxx is currently unavailable). (kkolinko) +
  • +
+
+

Coyote

+
    +
  • Fix: + When building a list of JSSE ciphers from an OpenSSL cipher definition, + ignore unknown criteria rather than throwing a + NullPointerException. (markt) +
  • +
  • Add: + Add support for the EECDH alias when using the OpenSSL cipher syntax to + define JSSE ciphers. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Correct a logic error in the JasperElResolver. There was no + functional impact but the code was less efficient as a result of the + error. Based on a patch by martinschaef. (markt) +
  • +
  • Fix: + 56568: Enable any HTTP method to be used to request a JSP + page that has the isErrorPage page directive set to + true. (markt) +
  • +
+
+

WebSocket

+
    +
  • Add: + Extend support for the permessage-deflate extension to + compression of outgoing messages on the server side. (markt) +
  • +
+
+

Other

+
    +
  • Add: + 56323: Include the *.bat files when installing + Tomcat via the Windows installer. (markt) +
  • +
+
+

2014-08-22 Tomcat 8.0.11 (markt)

+

Catalina

+
    +
  • Fix: + 56658: Fix regression that a context was inaccessible after + reload. (kkolinko) +
  • +
  • Fix: + 56710: Do not map requests to servlets when context is + being reloaded. (kkolinko) +
  • +
  • Fix: + 56712: Fix session idle time calculations in + PersistenceManager. (kkolinko) +
  • +
  • Fix: + 56717: Fix duplicate registration of + MapperListener during repeated starts of embedded Tomcat. + (kkolinko) +
  • +
  • Add: + 56724: Write an error message to Tomcat logs if container + background thread is aborted unexpectedly. (kkolinko) +
  • +
  • Fix: + When scanning class files (e.g. for annotations) and reading the number + of parameters in a MethodParameters structure only read a + single byte (rather than two bytes) as per the JVM specification. Patch + provided by Francesco Komauli. (markt) +
  • +
  • Fix: + Allow the JNDI Realm to start even if the directory is not available. + The directory not being available is not fatal once the Realm is started + and it need not be fatal when the Realm starts. Based on a patch by + Cédric Couralet. (markt) +
  • +
  • Fix: + 56736: Avoid an incorrect IllegalStateException + if the async timeout fires after a non-container thread has called + AsyncContext.dispatch() but before a container thread + starts processing the dispatch. (markt) +
  • +
  • Fix: + 56739: If an application handles an error on an application + thread during asynchronous processing by calling + HttpServletResponse.sendError(), then ensure that the + application is given an opportunity to report that error via an + appropriate application defined error page if one is configured. (markt) +
  • +
  • Fix: + 56784: Fix a couple of rare but theoretically possible + atomicity bugs. (markt) +
  • +
  • Fix: + 56785: Avoid NullPointerException if directory + exists on the class path that is not readable by the Tomcat user. + (markt) +
  • +
  • Fix: + 56796: Remove unnecessary sleep when stopping a web + application. (markt) +
  • +
  • Fix: + 56801: Improve performance of + org.apache.tomcat.util.file.Matcher which is to filter JARs + for scanning during web application start. Based on a patch by Sheldon + Shao. (markt) +
  • +
  • Fix: + 56815: When the gzip option is enabled for the + DefaultServlet ensure that a suitable Vary + header is returned for resources that might be returned directly in + compressed form. (markt) +
  • +
  • Fix: + Do not mark threads from the container thread pool as container threads + when being used to process AsyncContext.start(Runnable) so + processing is correctly transferred back to a genuine container thread + when necessary. (markt) +
  • +
  • Add: + Add simple caching for calls to StandardRoot.getResources() + in the new (for 8.0.x) resources implementation. (markt) +
  • +
  • Fix: + 56825: Enable pre-emptive authentication to work with the + SSL authenticator. Based on a patch by jlmonteiro. (markt) +
  • +
  • Fix: + 56840: Avoid NPE when the rewrite valve is mapped to + a context. (remm) +
  • +
  • Fix: + Correctly handle multiple accept-language headers rather + than just using the first header to determine the user's preferred + Locale. (markt) +
  • +
  • Fix: + 56848: Improve handling of accept-language + headers. (markt) +
  • +
  • Fix: + 56857: Fix thread safety issue when calling ServletContext + methods while running under a security manager. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Fix NIO2 sendfile state tracking and error handling to fix + various corruption issues. (remm) +
  • +
  • Fix: + Missing timeout for NIO2 sendfile writes. (remm) +
  • +
  • Fix: + Allow inline processing for NIO2 sendfile and optimize keepalive + behavior. (remm) +
  • +
  • Fix: + Fix excessive NIO2 sendfile direct memory use in some cases, sendfile + will now instead use the regular socket write buffer as configured. + (remm) +
  • +
  • Fix: + 56661: Fix getLocalAddr() for AJP connectors. + The complete fix is only available with a recent AJP forwarder like + the forthcoming mod_jk 1.2.41. (rjung) +
  • +
  • Fix: + Use default ciphers defined as + HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5 so + that no weak ciphers are enabled by default. (remm) +
  • +
  • Fix: + 56780: Enable Tomcat to start when using SSL with an IBM JRE + in strict SP800-131a mode. (markt) +
  • +
  • Fix: + 56810: Remove use of Java 8 specific API calls in unit tests + for OpenSSL to JSSE cipher conversion. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56709: Fix system property name in a log message. Submitted + by Robert Kish. (remm) +
  • +
  • Fix: + 56797: When matching a method in an EL expression, do not + treat bridge methods as duplicates of the method they bridge to. In this + case always call the target of the bridge method. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 56746: Allow secure WebSocket client threads to use the + current context class loader rather than explicitly setting it to the + class loader that loaded the WebSocket implementation. This allows + WebSocket client connections from within web applications to access, + amongst other things, the JNDI resources associated with the web + application. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Correct the label in the list of sessions by idle time for the bin that + represents the idle time immediately below the maximum permitted idle + time when using the expire command of the Manager application. (markt) +
  • +
+
+

jdbc-pool

+
    +
  • Fix: + 53088: More identifiable thread name. (fhanik) +
  • +
  • Fix: + 53200: Selective logging for slow versus failed queries. + (fhanik) +
  • +
  • Fix: + 53853: More flexible classloading. (fhanik) +
  • +
  • Fix: + 54225: Disallow empty init SQL. (fhanik) +
  • +
  • Fix: + 54227: Evaluate max age upon borrow. (fhanik) +
  • +
  • Fix: + 54235: Disallow nested pools exploitating using data source. + (fhanik) +
  • +
  • Fix: + 54395: Fix JDBC interceptor parsing bug. (fhanik) +
  • +
  • Fix: + 54537: Performance improvement in + StatementFinalizer. (fhanik) +
  • +
  • Fix: + 54978: Make sure proper connection validation always happens, + regardless of config. (fhanik) +
  • +
  • Fix: + 56318: Ability to trace statement creation in + StatementFinalizer. (fhanik) +
  • +
  • Fix: + 56789: getPool() returns the actual pool, always. (fhanik) +
  • +
+
+

Other

+
    +
  • Add: + 56788: Display the full version in the list of installed + applications when installed via the Windows installer package. Patch + provided by Alexandre Garnier. (markt) +
  • +
  • Add: + 56829: Add the ability for users to define their own values + for _RUNJAVA and _RUNJDB environment + variables. Be more strict with executable filename on Windows + (s/java/java.exe/). Based on a patch by Neeme Praks. (markt/kkolinko) +
  • +
+
+

not released Tomcat 8.0.10 (markt)

+

Catalina

+
    +
  • Fix: + 44312: Log an error if there is a conflict between Host and + Alias names. Improve host management methods in Mapper + to avoid occasionally removing a wrong host. Check that host management + operations are performed on the host and not on an alias. (kkolinko) +
  • +
  • Code: + 56611: Refactor code to remove inefficient calls to + Method.isAnnotationPresent(). Based on a patch by Jian Mou. + (markt/kkolinko) +
  • +
  • Fix: + Fix regression in + StandardContext.removeApplicationListener(), introduced by + the fix for bug 56588. (kkolinko) +
  • +
  • Fix: + 56653: Fix concurrency issue with lists of contexts in + Mapper when stopping Contexts. (kkolinko) +
  • +
  • Fix: + 56657: When using parallel deployment, if the same session id + matches different versions of a web application, prefer the latest + version. Ensure that remapping selects the version that we expect. + (kkolinko) +
  • +
  • Fix: + Assert that mapping result object is empty before performing mapping + work in Mapper. (kkolinko) +
  • +
  • Code: + Remove context and wrapper fields in + Request class and deprecate their setters. (kkolinko) +
  • +
  • Fix: + 56658: Avoid delay between registrations of mappings for + context and for its servlets. (kkolinko) +
  • +
  • Fix: + 56665: Correct the generation of the effective web.xml when + elements contain an empty string as value. (violetagg) +
  • +
  • Fix: + Fix storeconfig exception routing issues, so that a major problem + should avoid configuration overwrite. (remm) +
  • +
  • Fix: + Add configuration fields for header names in SSLValve. (remm) +
  • +
  • Fix: + 56666: When clearing the SSO cookie use the same values for + domain, path, httpOnly and secure as were used to set the SSO cookie. + (markt) +
  • +
  • Fix: + 56677: Ensure that + HttpServletRequest.getServletContext() returns the correct + value during a cross-context dispatch. (markt) +
  • +
  • Fix: + 56684: Ensure that Tomcat does not shut down if the socket + waiting for the shutdown command experiences a + SocketTimeoutException. (markt) +
  • +
  • Fix: + 56693: Fix various issues in the static resource cache + implementation where the cache retained a stale entry after the + successful completion of an operation that always invalidates the cache + entry such as a delete operation. + (markt) +
  • +
  • Fix: + When the current PathInfo is modified as a result of dispatching a + request, ensure that a call to + HttpServletRequest.getPathTranslated() returns a value that + is based on the modified PathInfo. (markt) +
  • +
  • Fix: + 56698: When persisting idle sessions, only persist newly idle + sessions. Patch provided by Felix Schumacher. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + 56663: Fix edge cases demonstrated by ByteCounter relating + to data available, remaining and extra write events, mostly occurring + with non blocking Servlet 3.1. (remm) +
  • +
  • Fix: + Avoid possible NPE stopping endpoints that are not started (stop + shouldn't do anything in that case). (remm) +
  • +
  • Add: + 56704: Add support for OpenSSL syntax for ciphers when + using JSSE SSL connectors. Submitted by Emmanuel Hugonnet. (remm) +
  • +
  • Update: + Allow to configure maxSwallowSize attribute of an HTTP + connector via JMX. (kkolinko) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56543: Update to the Eclipse JDT Compiler 4.4. (violetagg) +
  • +
  • Fix: + 56652: Add support for method parameters that use arrays and + varargs to ELProcessor.defineFunction().(markt) +
  • +
+
+

WebSocket

+
    +
  • Add: + Add support for the permessage-deflate extension. This is + currently limited to decompressing incoming messages on the server side. + It is expected that support will be extended to outgoing messages and to + the client side shortly. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Attempt to obfuscate session cookie values associated with other web + applications when viewing HTTP request headers with the Cookies example + from the examples web application. This reduces the opportunity to use + this example for malicious purposes should the advice to remove the + examples web application from security sensitive systems be ignored. + (markt) +
  • +
  • Fix: + 56694: Remove references to Manager attribute + checkInterval from documentation and Javadoc since it no + longer exists. Based on a patch by Felix Schumacher. Also remove other + references to checkInterval that are no longer valid. + (markt) +
  • +
+
+

Other

+
    +
  • Update: + Update the API stability section of the release notes now that Tomcat 8 + has had its first stable release. (markt) +
  • +
  • Update: + Improve build.xml so that when Eclipse JDT Compiler is + updated, it will delete the old JAR from build/lib + directory. (kkolinko) +
  • +
  • Code: + Simplify implementation of "setproxy" target in build.xml. + (kkolinko) +
  • +
  • Update: + Update optional Checkstyle library to 5.7. (kkolinko) +
  • +
  • Update: + 56596: Update to Tomcat Native Library version 1.1.31 to + pick up the Windows binaries that are based on OpenSSL 1.0.1h. (markt) +
  • +
  • Fix: + 56685: Add quotes necessary for daemon.sh to + work correctly on Solaris. Based on a suggestion by lfuka. (markt) +
  • +
  • Update: + Update package renamed Apache Commons Pool2 to r1609323 to pick various + bug fixes. (markt) +
  • +
  • Update: + Update package renamed Apache Commons DBCP2 to r1609329 to pick up a + minor bug fix. (markt) +
  • +
  • Update: + Update package renamed Apache Commons FileUpload to r1596086 to pick + various bug fixes. (markt) +
  • +
+
+

2014-06-24 Tomcat 8.0.9 (markt)

+

Catalina

+
    +
  • Fix: + 55282: Ensure that one and the same application listener is + added only once when starting the web application. (violetagg) +
  • +
  • Fix: + 55975: Apply consistent escaping for double quote and + backslash characters when escaping cookie values. (markt) +
  • +
  • Code: + 56387: Improve the code that handles an attempt to load a + class after a web application has been stopped. Use common code to handle + this case regardless of the access path and don't throw an exception + purely to log a stack trace. (markt) +
  • +
  • Code: + 56399: Improve implementation of CoyoteAdapter.checkRecycled() + to do not use an exception for flow control. (kkolinko) +
  • +
  • Add: + 56461: New failCtxIfServletStartFails attribute + on Context and Host configuration to force the context startup to fail + if a load-on-startup servlet fails its startup. (slaurent) +
  • +
  • Add: + 56526: Improved the StuckThreadDetectionValve to + optionally interrupt stuck threads to attempt to unblock them. + (slaurent) +
  • +
  • Fix: + 56545: Pre-load two additional classes, the loading of which + may otherwise be triggered by a web application which in turn would + trigger an exception when running under a security manager. (markt) +
  • +
  • Update: + 56546: Reduce logging level for stack traces of stuck web + application threads printed by WebappClassLoader.clearReferencesThreads() + from error to info. (kkolinko) +
  • +
  • Code: + Refactor and simplify common code in object factories in + org.apache.catalina.naming package, found thanks to Simian + (Similarity Analyser) tool. Improve handling of Throwable. + (markt/kkolinko) +
  • +
  • Fix: + Relax cookie naming restrictions. Cookie attribute names used in the + Set-Cookie header may be used unambiguously as cookie + names. The restriction that prevented such usage has been removed. + (jboynes/markt) +
  • +
  • Fix: + Further relax cookie naming restrictions. Version 0 (a.k.a Netscape + format) cookies may now use names that start with the $ + character. (jboynes/markt) +
  • +
  • Fix: + Restrict cookie naming so that the = character is no longer + permitted in a version 0 (a.k.a. Netscape format) cookie name. While + Tomcat allowed this, browsers always truncated the name at the + = character leading to a mis-match between the cookie the + server set and the cookie returned by the browser. (jboynes/markt) +
  • +
  • Add: + Add a simple ServiceLoader based discovery mechanism to the + JULI LogFactory to make it easier to use JULI and Tomcat + components that depend on JULI (such as Jasper) independently from + Tomcat. Patch provided by Greg Wilkins. (markt) +
  • +
  • Fix: + 56578: Correct regression in the fix for 56339 + that prevented sessions from expiring when using clustering. (markt) +
  • +
  • Fix: + 56588: Remove code previously added to enforce the + requirements of section 4.4 of the Servlet 3.1 specification. The code + is no longer required now that Jasper initialization has been refactored + and TLD defined listeners are added via a different code path that + already enforces the specification requirements. (markt) +
  • +
  • Fix: + 56600: In WebdavServlet: Do not waste time generating + response for broken PROPFIND request. (kkolinko) +
  • +
  • Fix: + Provide a better error message when asynchronous operations are not + supported by a filter or servlet. Patch provided by Romain Manni-Bucau. + (violetagg) +
  • +
  • Fix: + 56606: User entries in tomcat-users.xml file + are recommended to use "username" attribute rather than legacy "name" + attribute. Fix inconsistencies in Windows installer, examples. Update + digester rules and documentation for MemoryRealm. + (markt/kkolinko) +
  • +
+
+

Coyote

+
    +
  • Fix: + 56518: When using NIO, do not attempt to write to the socket + if the thread is marked interrupted as this will lead to a connection + limit leak. This fix was based on analysis of the issue by hanyong. + (markt) +
  • +
  • Fix: + 56521: Re-use the asynchronous write buffer between writes to + reduce allocation and GC overhead. Based on a patch by leonzhx. Also + make the buffer size configurable and remove copying of data within + buffer when the buffer is only partially written on a subsequent write. + (markt) +
  • +
  • Fix: + Ensure that a request without a body is correctly handled during Comet + processing. This fixes the Comet chat example. (markt) +
  • +
  • Fix: + Fix input concurrency issue in NIO2 upgrade. (remm) +
  • +
  • Fix: + Correct a copy/paste error and return a 500 response rather than a 400 + response when an internal server error occurs on early stages of + request processing. (markt) +
  • +
  • Code: + 56582: Use switch(actionCode) in processors instead of a + chain of "elseif"s. (kkolinko) +
  • +
  • Fix: + 56582#c1: Implement DISPATCH_EXECUTE action for AJP + connectors. (kkolinko) +
  • +
  • Fix: + Fix CVE-2014-0227: + Various improvements to ChunkedInputFilter including clean-up, i18n for + error messages and adding an error flag to allow subsequent attempts at + reading after an error to fail fast. (markt) +
  • +
  • Fix: + If request contains an unrecognized Expect header, respond with error + 417 (Expectation Failed), according to RFC2616 chapter 14.20. (markt) +
  • +
  • Fix: + When an error occurs after the response has been committed close the + connection immediately rather than attempting to finish the response to + make it easier for the client to differentiate between a complete + response and one that failed part way though. (markt) +
  • +
  • Code: + Remove the beta tag from the NIO2 connectors. (remm) +
  • +
  • Fix: + 56620: Avoid bogus access log entries when pausing the NIO + HTTP connector and ensure that access log entries generated by error + conditions use the correct request start time. (markt) +
  • +
  • Fix: + Improve configuration of cache sizes in the endpoint. (markt) +
  • +
  • Add: + Fix CVE-2014-0230: + Add a new limit, defaulting to 2MB, for the amount of data Tomcat will + swallow for an aborted upload. The limit is configurable by + maxSwallowSize attribute of an HTTP connector. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56334#c15: Fix a regression in EL parsing when quoted string + follows a whitespace. (kkolinko/markt) +
  • +
  • Update: + 56543: Update to the Eclipse JDT Compiler 4.4RC4 to pick up + some fixes for Java 8 support. (markt/kkolinko) +
  • +
  • Fix: + 56561: Avoid NoSuchElementException while + handling attributes with empty string value. (violetagg) +
  • +
  • Code: + Do not configure a JspFactory in the + JasperInitializer if one has already been set as might be + the case in some embedding scenarios. (markt) +
  • +
  • Add: + Add a simple implementation of InstanceManager and have + Jasper use it if no other InstanceManager is provided. This + makes it easier to use Jasper independently from Tomcat. Patch provided + by Greg Wilkins. (markt) +
  • +
  • Fix: + 56568: Allow any HTTP method when a JSP is being used as an + error page. (markt) +
  • +
  • Update: + 56581: If an error on a JSP page occurs when response has + already been committed, do not clear the buffer of JspWriter, but flush + it. It will make more clear where the error occurred. (kkolinko) +
  • +
  • Fix: + 56612: Correctly parse two consecutive escaped single quotes + when used in UEL expression in a JSP. (markt) +
  • +
  • Update: + Move code that parses EL expressions within JSP template text from + Parser to JspReader class for better + performance. (kkolinko) +
  • +
  • Fix: + 56636: Correctly identify the required method when specified + via ELProcessor.defineFunction(String,String,String,String) + when using Expression Language. (markt) +
  • +
  • Fix: + 56638: When using + ELProcessor.defineFunction(String,String,String,String) and + no function name is specified, use the method name as the function name + as required by the specification. (markt) +
  • +
+
+

WebSocket

+
    +
  • Code: + 56446: Clearer handling of exceptions when calling a method + on a POJO based WebSocket endpoint. Based on a suggestion by Eugene + Chung. (markt) +
  • +
  • Fix: + When a WebSocket client attempts to write to a closed connection, handle + the resulting IllegalStateException in a manner consistent + with the handling of an IOException. (markt) +
  • +
  • Fix: + Add more varied endpoints for echo testing. (remm) +
  • +
  • Fix: + 56577: Improve the executor configuration used for the + callbacks associated with asynchronous writes. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Set the path for cookies created by the examples web application so they + only returned to the examples application. This reduces the opportunity + for using such cookies for malicious purposes should the advice to + remove the examples web application from security sensitive systems be + ignored. (markt/kkolinko) +
  • +
  • Fix: + Attempt to obfuscate session cookie values associated with other web + applications when viewing HTTP request headers with the Request Header + example from the examples web application. This reduces the opportunity + to use this example for malicious purposes should the advice to remove + the examples web application from security sensitive systems be ignored. + (markt) +
  • +
  • Add: + Add options for all of the WebSocket echo endpoints to the WebSocket + echo example in the examples web application. (markt) +
  • +
  • Fix: + Ensure that the asynchronous WebSocket echo endpoint in the examples + web application always waits for the previous message to complete before + it sends the next. (markt) +
  • +
+
+

Other

+
    +
  • Update: + Update package renamed Apache Commons DBCP2 to r1596858. (markt) +
  • +
+
+

beta, 2014-05-21 Tomcat 8.0.8 (markt)

+

Catalina

+
    +
  • Fix: + 56536: Ensure that + HttpSessionBindingListener.valueUnbound() uses the correct + class loader when the SingleSignOn valve is used. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56529: Avoid NoSuchElementException while handling + attributes with empty string value in custom tags. Patch provided by + Hariprasad Manchi. (violetagg) +
  • +
+
+

not released Tomcat 8.0.7 (markt)

+

Catalina

+
    +
  • Fix: + 56523: When using SPNEGO authentication, log the exceptions + associated with failed user logins at debug level rather than error + level. (markt) +
  • +
+
+

Coyote

+
    +
  • Add: + 56399: Assert that both Coyote and Catalina request objects + have been properly recycled. (kkolinko) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56522: When setting a value for a + ValueExpression, ensure that the expected coercions take + place such as a null string being coerced to an empty + string. (markt) +
  • +
+
+

Other

+
    +
  • Fix: + Copy missing resources file from Apache Commons DBCP 2 to packaged + renamed copy of DBCP 2. (markt) +
  • +
+
+

not released Tomcat 8.0.6 (markt)

+

Catalina

+
    +
  • Fix: + Fix extension validation which was broken by refactoring for new + resources implementation. (markt) +
  • +
  • Fix: + Fix custom UTF-8 decoder so that a byte of value 0xC1 is always rejected + immediately as it is never valid in a UTF-8 byte sequence. Update UTF-8 + decoder tests to account for UTF-8 decoding improvements in Java 8. + The custom UTF-8 decoder is still required due to bugs in the UTF-8 + decoder provided by Java. Java 8's decoder is better than Java + 7's but it is still buggy. (markt) +
  • +
  • Fix: + 56027: Add more options for managing FIPS mode in the + AprLifecycleListener. (schultz/kkolinko) +
  • +
  • Fix: + 56320: Fix a file descriptor leak in the default servlet when + sendfile is used. (markt) +
  • +
  • Fix: + 56321: When a WAR is modified, undeploy the web application + before deleting any expanded directory as the undeploy process may + refer to classes that need to be loaded from the expanded directory. If + the expanded directory is deleted first, any attempt to load a new class + during undeploy will fail. (markt) +
  • +
  • Fix: + 56327: Enable AJP as well as HTTP connectors to be created + via JMX. Patch by kiran. (markt) +
  • +
  • Fix: + 56339: Avoid an infinite loop if an application calls + session.invalidate() from the session destroyed event for + that session. (markt) +
  • +
  • Code: + 56365: Simplify file name pattern matching code in + StandardJarScanner. Improve documentation. (kkolinko) +
  • +
  • Fix: + Ensure that the static resource cache is able to detect when a cache + entry is invalidated by being overridden by a new resource in a + different WebResourceSet. (markt) +
  • +
  • Fix: + 56369: Ensure that removing an MBean notification listener + reverts all the operations performed when adding an MBean notification + listener. (markt) +
  • +
  • Code: + Improve implementation of Lifecycle for + WebappClassLoader. State is now correctly reported rather + than always reporting as NEW. (markt) +
  • +
  • Add: + 56382: Information about finished deployment and its execution + time is added to the log files. Patch is provided by Danila Galimov. + (violetagg) +
  • +
  • Add: + 56383: Properties for disabling server information and error + report are added to the org.apache.catalina.valves.ErrorReportValve. + Based on the patch provided by Nick Bunn. (violetagg/kkolinko) +
  • +
  • Fix: + 56390: Fix JAR locking issue with JARs containing TLDs and + the TLD cache that prevented the undeployment of web applications when + the WAR was deleted. (markt) +
  • +
  • Fix: + Fix CVE-2014-0119: + Only create XML parsing objects if required and fix associated potential + memory leak in the default Servlet. + Extend XML factory, parser etc. memory leak protection to cover some + additional locations where, theoretically, a memory leak could occur. + (markt) +
  • +
  • Fix: + Modify generic exception handling so that + StackOverflowError is not treated as a fatal error and can + handled and/or logged as required. (markt) +
  • +
  • Fix: + 56409: Avoid StackOverflowError on non-Windows + systems if a file named \ is encountered when scanning for + TLDs. (markt) +
  • +
  • Add: + 56430: Extend checks for suspicious URL patterns to include + patterns of the form *.a.b which are not valid patterns for + extension mappings. (markt) +
  • +
  • Fix: + 56441: Raise the visibility of exceptions thrown when a + problem is encountered calling a getter or setter on a component + attribute. The logging level is raised from debug to warning. (markt) +
  • +
  • Add: + 56463: Property for disabling server information is added to + the DefaultServlet. Server information is presented in the + response sent to the client when directory listings is enabled. + (violetagg) +
  • +
  • Fix: + 56472: Allow NamingContextListener to clean up on stop if its + start failed. (kkolinko) +
  • +
  • Fix: + 56481: Work around case insensitivity issue in + URLClassLoader exposed by some recent refactoring. (markt) +
  • +
  • Add: + 56492: Avoid eclipse debugger pausing on uncaught exceptions + when tomcat renews its threads. (slaurent) +
  • +
  • Add: + Add the org.apache.naming package to the packages requiring + code to have the defineClassInPackage permission when + running under a security manager. (markt) +
  • +
  • Fix: + Make the naming context tokens for containers more robust by using a + separate object. Require RuntimePermission when introducing a new token. + (markt/kkolinko) +
  • +
  • Fix: + 56501: HttpServletRequest.getContextPath() + should return the undecoded context path used by the user agent. (markt) +
  • +
  • Fix: + Minor fixes to ThreadLocalLeakPreventionListener. Do not + trigger threads renewal for failed contexts. Do not ignore + threadRenewalDelay setting. Improve documentation. (kkolinko) +
  • +
  • Fix: + Correct regression introduced in r1239520 that broke loading + of users from tomcat-users.xml when using the + JAASMemoryLoginModule. (markt) +
  • +
  • Fix: + Correct regression introduced in r797162 that broke + authentication of users when using the + JAASMemoryLoginModule. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + More cleanup of NIO2 endpoint shutdown. (remm) +
  • +
  • Fix: + 56336: AJP output corruption and errors. (remm) +
  • +
  • Fix: + Handle various cases of incomplete writes in NIO2. (remm) +
  • +
  • Code: + Code cleanups and i18n in NIO2. (remm) +
  • +
  • Fix: + Fix extra onDataAvailable calls in the NIO2 connector. (remm) +
  • +
  • Fix: + Fix gather writes in NIO2 SSL. (remm) +
  • +
  • Code: + Upgrade the NIO2 connectors to beta, but still not ready for production. (remm) +
  • +
  • Code: + Fix code duplication between NIO and NIO2. (remm) +
  • +
  • Fix: + 56348: Fix slow asynchronous read when read was performed on + a non-container thread. (markt) +
  • +
  • Fix: + 56416: Correct documentation for default value of socket + linger for the AJP and HTTP connectors. (markt) +
  • +
  • Fix: + Fix possible corruption if doing keepalive after a comet request. (remm) +
  • +
  • Fix: + 56518: Fix connection limit latch leak when a non-container + thread is interrupted during asynchronous processing. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + 56334: Fix a regression in the handling of back-slash + escaping introduced by the fix for 55735. (markt/kkolinko) +
  • +
  • Fix: + 56425: Improve method matching for EL expressions. When + looking for matching methods, an exact match between parameter types is + preferred followed by an assignable match followed by a coercible match. + (markt) +
  • +
  • Fix: + Correct the handling of back-slash escaping in the EL parser and no + longer require that \$ or \# must be followed + by { in order for the back-slash escaping to take effect. + (markt) +
  • +
+
+

Cluster

+
    +
  • Code: + Remove the implementation of + org.apache.catalina.LifecycleListener from + org.apache.catalina.ha.tcp.SimpleTcpCluster. + SimpleTcpCluster does not work as + LifecycleListener, it works as nested components of Host or + Engine. (kfujino) +
  • +
  • Fix: + Remove cluster and replicationValve from cluster manager template. These + instance are not necessary to template. (kfujino) +
  • +
  • Fix: + Add support for cross context session replication to + org.apache.catalina.ha.session.BackupManager. (kfujino) +
  • +
  • Fix: + Remove the unnecessary cross context check. It does not matter whether + the context that is referenced by other context is set to + crossContext=true. The context that refers to the different + context must be set to crossContext=true. (kfujino) +
  • +
  • Code: + Move to org.apache.catalina.ha.session.ClusterManagerBase + common logics of + org.apache.catalina.ha.session.BackupManager and + org.apache.catalina.ha.session.DeltaManager. (kfujino) +
  • +
  • Code: + Simplify the code of o.a.c.ha.tcp.SimpleTcpCluster. In + order to add or remove cluster valve to Container, use pipeline instead + of IntrospectionUtils. (kfujino) +
  • +
  • Fix: + There is no need to set cluster instance when + SimpleTcpCluster.unregisterClusterValve is called. + Set null than cluster instance for cleanup. (kfujino) +
  • +
+
+

WebSocket

+
    +
  • Fix: + 56343: Avoid a NPE if Tomcat's Java WebSocket 1.0 + implementation is used with the Java WebSocket 1.0 API JAR from the + reference implementation. (markt) +
  • +
  • Fix: + Increase the default maximum size of the executor used by the WebSocket + implementation for call backs associated with asynchronous writes from + 10 to 200. (markt) +
  • +
  • Add: + Add a warning if the thread group created for WebSocket asynchronous + write call backs can not be destroyed when the web application is + stopped. (markt) +
  • +
  • Fix: + Ensure that threads created to support WebSocket clients are stopped + when no longer required. This will happen automatically for WebSocket + client connections initiated by web applications but stand alone clients + must call WsWebSocketContainer.destroy(). (markt) +
  • +
  • Fix: + 56449: When creating a new session, add the message handlers + to the session before calling Endpoint.onOpen() so the + message handlers are in place should the onOpen() method + trigger the sending of any messages. (markt) +
  • +
  • Fix: + 56458: Report WebSocket sessions that are created over secure + connections as secure rather than as not secure. (markt) +
  • +
  • Fix: + Stop threads used for secure WebSocket client connections when they are + no longer required and give them better names for easier debugging while + they are running. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + Add Support for copyXML attribute of Host to Host Manager. + (kfujino) +
  • +
  • Fix: + Ensure that "name" request parameter is used as a application base of + host if "webapps" request parameter is not set when adding host in + HostManager Application. (kfujino) +
  • +
  • Fix: + Correct documentation on Windows service options, aligning it with + Apache Commons Daemon documentation. (kkolinko) +
  • +
  • Fix: + 56418: Ensure that the Manager web application does not + report success for a web application deployment that fails. (slaurent) +
  • +
  • Update: + Improve valves documentation. Split valves into groups. (kkolinko) +
  • +
  • Fix: + 56513: Make the documentation crystal clear that using + sendfile will disable any compression that Tomcat may otherwise have + applied to the response. (markt) +
  • +
+
+

Other

+
    +
  • Code: + Review source code and take advantage of Java 7's + try-with-resources syntax where possible. (markt) +
  • +
  • Fix: + Align DisplayName of Tomcat installed by service.bat with + one installed by the *.exe installer. Print a warning in case if neither + server nor client jvm is found by service.bat. (kkolinko) +
  • +
  • Update: + 56363: Update to version 1.1.30 of Tomcat Native library. + (schultz) +
  • +
  • Update: + Update package renamed Apache Commons BCEL to r1593495 to pick up some + additional changes for Java 7 support and some code clean up. (markt) +
  • +
  • Update: + Update package renamed Apache Commons FileUpload to r1569132 to pick up + some small improvements (e.g. better null protection) and + some code clean up. (markt) +
  • +
  • Update: + Update package renamed Apache Commons Codec to r1586336 to pick up some + Javadoc fixes and some code clean up. (markt) +
  • +
  • Code: + Switch to including Apache Commons DBCP via a package renamed svn copy + rather than building from a source release for consistency with other + Commons packages and to allow faster releases to fix DBCP related + issues. (markt) +
  • +
  • Update: + Update package renamed Apache Commons Pool2 and DBCP2 to r1593563 to + pick various bug fixes. (markt) +
  • +
  • Add: + In tests: allow to configure directory where JUnit reports and access + log are written to. (kkolinko) +
  • +
+
+

beta, 2014-03-27 Tomcat 8.0.5 (markt)

+

Catalina

+
    +
  • Fix: + Rework the fix for 56190 as the previous fix did not recycle + the request in all cases leading to mis-routing of requests. (markt) +
  • +
  • Fix: + Allow web applications to package tomcat-jdbc.jar and their JDBC driver + of choice in the web application. (markt) +
  • +
  • Fix: + 56293: Cache resources loaded by the class loader from + /META-INF/services/ for better performance for repeated + look ups. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + Fix possibly incomplete final flush with NIO2 when using non blocking + mode. (remm) +
  • +
  • Fix: + Cleanup NIO2 endpoint shutdown. (remm) +
  • +
  • Fix: + Fix rare race condition notifying onWritePossible in the NIO2 + HTTP/1.1 connector. (remm) +
  • +
+
+

Jasper

+
    +
  • Fix: + 54475: Add Java 8 support to SMAP generation for JSPs. Patch + by Robbie Gibson. (markt) +
  • +
+
+

Web applications

+
    +
  • Fix: + 56273: If the Manager web application does not perform an + operation because the web application is already being serviced, report + an error rather than reporting success. (markt) +
  • +
  • Fix: + 56304: Add a note to the documentation about not using + WebSocket with BIO HTTP in production. (markt) +
  • +
+
+

not released Tomcat 8.0.4 (markt)

+

Catalina

+
    +
  • Fix: + Restore the ability to use the addURL() method of the + web application class loader to add external resources to the web + application. (markt) +
  • +
  • Fix: + Improve the robustness of web application undeployment based on some + code analysis triggered by the report for 54315. (markt) +
  • +
  • Fix: + 56125: Correctly construct the URL for a resource that + represents the root of a JAR file. (markt) +
  • +
  • Fix: + Generate a valid root element for the effective web.xml for a web + application for all supported versions of web.xml. (markt) +
  • +
  • Add: + Make it easier for applications embedding and/or extending Tomcat to + modify the javaseClassLoader attribute of the + WebappClassLoader. (markt) +
  • +
  • Fix: + Add missing support for <deny-uncovered-http-methods> + element when merging web.xml files. (markt) +
  • +
  • Fix: + Improve merging process for web.xml files to take account of the + elements and attributes supported by the Servlet version of the merged + file. (markt) +
  • +
  • Fix: + Avoid NullPointerException in resource cache when making an + invalid request for a resource outside of the web application. (markt) +
  • +
  • Fix: + Remove an unnecessary null check identified by FindBugs. (markt) +
  • +
  • Add: + In WebappClassLoader, when reporting threads that are still running + while web application is being stopped, print their stack traces to + the log. (kkolinko) +
  • +
  • Fix: + 56190: The response should be closed (i.e. no further output + is permitted) when a call to AsyncContext.complete() takes + effect. (markt) +
  • +
  • Fix: + 56236: Enable Tomcat to work with alternative Servlet and + JSP API JARs that package the XML schemas in such as way as to require + a dependency on the JSP API before enabling validation for web.xml. + Tomcat has no such dependency. (markt) +
  • +
  • Fix: + 56244: Fix MBeans descriptor for WebappClassLoader MBean. + (kkolinko) +
  • +
  • Add: + Add a work around for validating XML documents (often TLDs) that use + just the file name to refer to the JavaEE schema on which they + are based. (markt) +
  • +
  • Add: + Add methods of get the idle time from last client access time to + org.apache.catalina.Session. (kfujino) +
  • +
  • Fix: + 56246: Fix NullPointerException in MemoryRealm when + authenticating an unknown user. (markt) +
  • +
  • Fix: + 56248: Allow the deployer to update an existing WAR file + without undeploying the existing application if the update flag is set. + This allows any existing custom context.xml for the application to be + retained. To update an application and remove any existing context.xml + simply undeploy the old version of the application before deploying the + new version. (markt) +
  • +
  • Fix: + 56253: When listing resources that are provided by a JAR, fix + possible StringIndexOutOfBoundsExceptions. Add some unit + tests for this and similar scenarios and fix the additional issues those + unit tests identified. Based on a patch by Larry Isaacs. (markt) +
  • +
  • Fix: + Fix CVE-2014-0096: + Redefine the globalXsltFile initialisation parameter of the + DefaultServlet as relative to CATALINA_BASE/conf or CATALINA_HOME/conf. + Prevent user supplied XSLTs used by the DefaultServlet from defining + external entities. (markt) +
  • +
+
+

Coyote

+
    +
  • Fix: + In some circumstances asynchronous requests could time out too soon. + (markt) +
  • +
  • Fix: + 56172: Avoid possible request corruption when using the AJP + NIO connector and a request is sent using more than one AJP message. + Patch provided by Amund Elstad. (markt) +
  • +
  • Add: + Add experimental NIO2 connector. Based on code developed by + Nabil Benothman. (remm) +
  • +
  • Fix: + Fix CVE-2014-0075: + Improve processing of chuck size from chunked headers. Avoid overflow + and use a bit shift instead of a multiplication as it is marginally + faster. (markt/kkolinko) +
  • +
  • Fix: + Fix CVE-2014-0095: + Correct regression introduced in 8.0.0-RC2 as part of the Servlet 3.1 + non-blocking IO support that broke handling of requests with an explicit + content length of zero. (markt/kkolinko) +
  • +
  • Fix: + Fix CVE-2014-0099: + Fix possible overflow when parsing long values from a byte array. + (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Change the default compiler source and compiler target versions to 1.7 + since Tomcat 8 requires a minimum of Java 7. (markt) +
  • +
  • Fix: + 56179: Fix parsing of EL expressions that contain unnecessary + parentheses. (markt) +
  • +
  • Fix: + 56177: Handle dependency tracking for TLDs when using JspC + with a tag library JAR that is located outside of the web application. + (markt) +
  • +
  • Fix: + Remove an unnecessary null check identified by FindBugs. (markt) +
  • +
  • Fix: + 56199: Restore validateXml option for JspC which determines + if web.xml will be parsed with a validating parser. (markt) +
  • +
  • Fix: + 56223: Throw an IllegalStateException if a call + is made to ServletContext.setInitParameter() after the + ServletContext has been initialized. (markt) +
  • +
  • Fix: + 56265: Do not escape values of dynamic tag attributes + containing EL expressions. (kkolinko) +
  • +
  • Fix: + Make the default compiler source and target versions for JSPs Java 7 + since Tomcat 8 requires Java 7 as a minimum. (markt) +
  • +
  • Update: + 56283: Update to the Eclipse JDT Compiler P20140317-1600 + which adds support for Java 8 syntax to JSPs. Add support for value + "1.8" for the compilerSourceVM and + compilerTargetVM options. (markt) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Avoid a possible deadlock when one thread is shutting down a connection + while another thread is trying to write to it. (markt) +
  • +
  • Fix: + Avoid NPE when flushing batched messages. (markt) +
  • +
+
+

Web Applications

+
    +
  • Add: + 56093: Add the SSL Valve to the documentation web + application. (markt) +
  • +
  • Fix: + 56217: Improve readability by using left alignment for the + table cell containing the request information on the Manager application + status page. (markt) +
  • +
  • Fix: + Fixed java.lang.NegativeArraySizeException when using + "Expire sessions" command in the manager web application on a + context where the session timeout is disabled. (kfujino) +
  • +
  • Fix: + Add support for LAST_ACCESS_AT_START system property to + Manager web application. (kfujino) +
  • +
+
+

Other

+
    +
  • Fix: + 56115: Expose the httpusecaches property of + Ant's get task as some users may need to change the + default. Based on a suggestion by Anthony. (markt) +
  • +
  • Fix: + 56143: Improve service.bat so that it can be + launched from a non-UAC console. This includes using a single call to + tomcat8.exe to install the Windows service rather than + three calls, and using command line arguments instead of environment + variables to pass the settings. (markt/kkolinko) +
  • +
  • Code: + Simplify Windows *.bat files: remove %OS% checks, as current java does + not run on ancient non-NT operating systems. (kkolinko) +
  • +
  • Fix: + Align options between service.bat and exe + Windows installer. For service.bat the changes are in + --Classpath, --DisplayName, --StartPath, --StopPath. For + exe installer the changes are in --JvmMs, --JvmMx options, + which are now 128 Mb and 256 Mb respectively instead of being empty. + Explicitly specify --LogPath path when uninstalling Windows service, + avoiding default value for that option. (kkolinko) +
  • +
  • Fix: + 56137: Explicitly use NIO connector in SSL example in + server.xml so it doesn't break if APR is enabled. (markt) +
  • +
  • Fix: + 56139: Avoid a web application class loader leak in some unit + tests when running on Windows. (markt) +
  • +
  • Fix: + Correct build script to avoid building JARs with empty packages. (markt) +
  • +
  • Add: + Allow to limit JUnit test run to a number of selected test case + methods. (kkolinko) +
  • +
  • Update: + Update Commons Pool 2 to 2.2. (markt) +
  • +
  • Update: + Update Commons DBCP 2 to the 2.0 release. (markt) +
  • +
  • Fix: + 56189: Remove used file cpappend.bat from the distribution. + (markt) +
  • +
  • Fix: + 56204: Remove unnecessary dependency between tasks in the + build script. (markt) +
  • +
  • Fix: + Add definition of org.apache.catalina.ant.FindLeaksTask. + (kfujino) +
  • +
  • Fix: + Implement org.apache.catalina.ant.VminfoTask, + org.apache.catalina.ant.ThreaddumpTask and + org.apache.catalina.ant.SslConnectorCiphersTask. (kfujino) +
  • +
  • Add: + Add the option to the Apache Ant tasks to ignore the constraint of the + first line of the response message that must be "OK -" + (ignoreResponseConstraint in AbstractCatalinaTask). + Default is false. (kfujino) +
  • +
+
+

beta, 2014-02-11 Tomcat 8.0.3 (markt)

+

Other

+
    +
  • Fix: + Fix build of Apache Commons DBCP2 classes. (kkolinko) +
  • +
  • Update: + Update Commons DBCP 2 to snapshot 170 dated 07 Feb 2014. This enables + DBCP to work with a SecurityManager such that only DBCP needs to be + granted the necessary permissions to communicate with the database. + (markt) +
  • +
+
+

not released Tomcat 8.0.2 (markt)

+

Catalina

+
    +
  • Fix: + 56082: Fix a concurrency bug in JULI's LogManager + implementation. (markt) +
  • +
  • Fix: + 56085: ServletContext.getRealPath(String) should + return null for invalid input rather than throwing an + IllegalArgumentException. (markt) +
  • +
  • Fix: + Fix WebDAV support that was broken by the refactoring for the new + resources implementation. (markt) +
  • +
  • Code: + Simplify Catalina.initDirs(). (kkolinko) +
  • +
  • Fix: + 56096: When the attribute rmiBindAddress of the + JMX Remote Lifecycle Listener is specified it's value will be used when + constructing the address of a JMX API connector server. Patch is + provided by Jim Talbut. (violetagg) +
  • +
  • Fix: + When environment entry with one and the same name is defined in the web + deployment descriptor and with annotation then the one specified in the + web deployment descriptor is with priority. (violetagg) +
  • +
  • Fix: + Fix passing the value of false for xmlBlockExternal option + of Context to Jasper, as the default was changed in 8.0.1. (kkolinko) +
  • +
+
+

Coyote

+
    +
  • Fix: + Enable non-blocking reads to take place on non-container threads. + (markt) +
  • +
+
+

Cluster

+
    +
  • Code: + Simplify the code of + o.a.c.ha.tcp.SimpleTcpCluster.createManager(String). + Remove unnecessary class cast. (kfujino) +
  • +
+
+

Web applications

+
    +
  • Fix: + In Manager web application improve handling of file upload errors. + Display a message instead of error 500 page. Simplify. (kkolinko) +
  • +
+
+

Other

+
    +
  • Fix: + 56104: Correct the version number on the welcome page of the + Windows installer. (markt) +
  • +
  • Update: + Update Commons DBCP 2 to snapshot 168 dated 05 Feb 2014. (markt) +
  • +
  • Fix: + Fix CVE-2014-0050, a denial of service with a malicious, malformed + Content-Type header and multipart request processing. Fixed by merging + latest code (r1565159) from Commons FileUpload. (markt) +
  • +
+
+

beta, 2014-02-02 Tomcat 8.0.1 (markt)

+

Catalina

+
    +
  • Fix: + Change default value of xmlBlockExternal attribute of + Context. It is true now. (kkolinko) +
  • +
+
+

Coyote

+
    +
  • Fix: + Correct regression in the fix for 55996 that meant that + asynchronous requests might timeout too early. (markt) +
  • +
+
+

Jasper

+
    +
  • Fix: + Change default value of the blockExternal attribute of + JspC task. The default value is true. Add support for + -no-blockExternal switch when JspC is run as a + standalone application. (kkolinko) +
  • +
+
+

WebSocket

+
    +
  • Fix: + Do not return an empty string for the + Sec-WebSocket-Protocol HTTP header when no sub-protocol has + been requested or no sub-protocol could be agreed as RFC6455 requires + that no Sec-WebSocket-Protocol header is returned in this + case. (markt) +
  • +
+
+

not released Tomcat 8.0.0 (markt)

+

Catalina

+
    +
  • Add: + Implement JSR 340 - Servlet 3.1. The JSR 340 implementation includes + contributions from Nick Williams and Jeremy Boynes. (markt) +
  • +
  • Add: + Implement JSR 245 MR2 - JSP 2.3. (markt) +
  • +
  • Add: + Implement JSR 341 - Unified Expression Language 3.0. (markt) +
  • +
  • Add: + Implement JSR 356 - WebSockets. The JSR 356 implementation includes + contributions from Nick Williams, Rossen Stoyanchev and Niki Dokovski. + (markt) +
  • +
  • Update: + 46727: Refactor default servlet to make it easier to + sub-class to implement finer grained control of the file encoding. Based + on a patch by Fred Toth. (markt) +
  • +
  • Add: + 45995: Align Tomcat with Apache httpd and perform MIME type + mapping based on file extension in a case insensitive manner. (markt) +
  • +
  • Code: + Remove duplicate code that converted a Host's appBase attribute to + a canonical file. (markt) +
  • +
  • Code: + 51408: Replace calls to Charset.defaultCharset() + with an explicit reference to the ISO-8859-1 Charset. (markt) +
  • +
  • Code: + Refactor initialization code to use a single, consistent approach to + determining the Catalina home (binary) and base (instance) directories. + The search order for home is catalina.home system property, + parent of current directory if boootstrap.jar is present and finally + current working directory. The search order for Catalina base is + catalina.base system property falling back to the value for + Catalina home. (markt) +
  • +
  • Update: + 52092: JULI now uses the OneLineFormatter and + AsyncFileHandler by default. (markt) +
  • +
  • Fix: + 52558: Refactor CometConnectionManagerValve so + that it does not prevent the session from being serialized in when + running in a cluster. (markt) +
  • +
  • Fix: + 52767: Remove reference to MySQL specific autoReconnect + property in JDBCAccessLogValve. (markt) +
  • +
  • Code: + Make the Mapper type-safe. Hosts, Contexts and Wrappers are no + longer handled as plain objects, instead they keep their type. + Code using the Mapper doesn't need to cast objects returned by + the mapper. (rjung) +
  • +
  • Code: + Move Manager, Loader and Resources from Container to Context since + Context is the only place they are used. The documentation already + states (and has done for some time) that Context is the only valid + location for these nested components. (markt) +
  • +
  • Code: + Move the Mapper from the Connector to the Service since the Mapper is + identical for all Connectors of a given Service and it is common for + there to be multiple Connectors for a Service (http, https and ajp). + This means there is now only ever one Mapper per Service rather than + possibly multiple identically configured Mapper objects. (markt) +
  • +
  • Code: + Remove the per Context Mapper objects and use the Mapper from the + Service. This removes the need to maintain two copies of the mappings + for Servlets and Filters. (markt) +
  • +
  • Add: + Implement a new Resources implementation that merges Aliases, + VirtualLoader, VirtualDirContext, JAR resources and external + repositories into a single framework rather than a separate one for each + feature. (markt) +
  • +
  • Add: + URL rewrite valve, similar in functionality to mod_rewrite. (remm) +
  • +
  • Add: + Port storeconfig functionality, which can persist to server.xml and + context.xml runtime container configuration changes. (remm) +
  • +
  • Add: + 54095: Add support to the Default Servlet for serving + gzipped versions of static resources directly from disk as an + alternative to Tomcat compressing them on each request. Patch by + Philippe Marschall. (markt) +
  • +
  • Fix: + 54708: Change the name of the working directory for the ROOT + application (located under $CATALINA_BASE/work by default) from _ to + ROOT. (markt) +
  • +
  • Add: + Change default configuration so that a change to the global web.xml file + will trigger a reload of all web applications. (markt) +
  • +
  • Fix: + 55101: Make BASIC authentication more tolerant of whitespace. + Patch provided by Brian Burch. (markt) +
  • +
  • Fix: + 55166: Move JSP descriptor and tag library descriptor schemas + to servlet-api.jar to enable relative references between the schemas to + be correctly resolved. (markt) +
  • +
  • Code: + Refactor the descriptor parsing code into a separate module that can be + used by both Catalina and Jasper. Includes patches provided by Jeremy + Boynes. (violetagg/markt) +
  • +
  • Code: + 55246: Move TLD scanning to a ServletContainerInitializer + provided by Jasper. Includes removal of TldConfig lifecycle listener and + associated Context properties. (jboynes) +
  • +
  • Add: + 55317: Facilitate weaving by allowing ClassFileTransformer to + be added to WebappClassLoader. Patch by Nick Williams. (markt) +
  • +
  • Fix: + 55620: Enable Tomcat to start when either $CATALINA_HOME + and/or $CATALINA_BASE contains a comma character. Prevent Tomcat from + starting when $CATALINA_HOME and/or $CATALINA_BASE contains a semi-colon + on Windows. Prevent Tomcat from starting when $CATALINA_HOME and/or + $CATALINA_BASE contains a colon on Linux/FreeBSD/etc. (markt) +
  • +
  • Code: + Initialize the JSP runtime in Jasper's initializer to avoid need for a + Jasper-specific lifecycle listener. JasperListener has been + removed. (jboynes) +
  • +
  • Fix: + Change ordering of elements of JMX objects names so components are + grouped more logically in JConsole. Generally, components are now + grouped by Host and then by Context. (markt) +
  • +
  • Add: + Context listener to allow better EE and framework integration. (remm) +
  • +
  • Fix: + 57896: Support defensive copying of "cookie" header so that + unescaping double quotes in a cookie value does not corrupt original + value of "cookie" header. This is an opt-in feature, enabled by + org.apache.tomcat.util.http.ServerCookie.PRESERVE_COOKIE_HEADER + system property. (remm/kkolinko) +
  • +
+
+

Coyote

+
    +
  • Add: + Experimental support for SPDY. Includes contributions from Sheldon Shao. + (costin) +
  • +
  • Code: + The default connector is now the Java NIO connector even when specifying + HTTP/1.1 as protocol (fhanik) +
  • +
  • Code: + Update default value of pollerThreadCount for the NIO connector. The new + default value will never go above 2 regardless of available processors. + (fhanik) +
  • +
  • Fix: + 54010: Remove some unnecessary code (duplicate calls to + configure the scheme as https for AJP requests originally received over + HTTPS). (markt) +
  • +
  • Code: + Refactor char encoding/decoding using NIO APIs. (remm) +
  • +
  • Update: + Change the default URIEncoding for all connectors from ISO-8859-1 to + UTF-8. (markt) +
  • +
+
+

Jasper

+
    +
  • Code: + Simplify API of ErrorDispatcher class by using varargs. + (kkolinko) +
  • +
  • Code: + Update Jasper to use the new common web.xml parsing code. Includes + patches by Jeremy Boynes. (markt/violetagg) +
  • +
  • Add: + Create test cases for JspC. Patch by Jeremy Boynes. (markt) +
  • +
  • Code: + 55246: TLD scanning is now performed by JasperInitializer + (a ServletContainerInitializer) removing the need for support within the + Servlet container itself. The scan is now performed only once rather than + in two passes reducing startup time. (jboynes) +
  • +
  • Fix: + 55251: Do not allow JspC task to fail silently if the web.xml + or web.xml fragment can not be generated. (markt) +
  • +
+
+

Cluster

+
    +
  • Code: + Remove unused JvmRouteSessionIDBinderListener and SessionIDMessage. + (kfujino) +
  • +
  • Code: + Modify method signature in ReplicationValve. Cluster instance is not + necessary to argument of method. (kfujino) +
  • +
  • Code: + Remove unused expireSessionsOnShutdown attribute in + org.apache.catalina.ha.session.BackupManager. (kfujino) +
  • +
+
+

Web applications

+
    +
  • Add: + Extend the diagnostic information provided by the Manager web + application to include details of the configured SSL ciphers suites for + each connector. (markt) +
  • +
  • Update: + 48550: Update examples web application to use UTF-8. (markt) +
  • +
  • Update: + 55383: Improve the design and correct the HTML markup of + the documentation web application. Patches provided by Konstantin + Preißer. (markt) +
  • +
+
+

Tribes

+
    +
  • Code: + Refactor AbstractReplicatedMap to use generics. A key + side-effect of this is that the class now implements + Map<K,V> rather than extends + ConcurrentMap. (markt) +
  • +
+
+

Other

+
    +
  • Code: + Remove unused, deprecated code. (markt) +
  • +
  • Code: + Remove static info String and associated getInfo() method where present. + (markt) +
  • +
  • Update: + (r1353242, r1353410): + Remove Ant tasks jasper2 and jkstatus. + The correct names are jasper and jkupdate. + (kkolinko) +
  • +
  • Fix: + 53529: Clean-up the handling of + InterruptedException throughout the code base. (markt) +
  • +
  • Add: + 54899: Provide an initial implementation of NetBeans support. + Patch provided by Brian Burch. (markt) +
  • +
  • Fix: + 55166: Move the JSP descriptor and tag library descriptor + schema definition files from jsp-api.jar to servlet-api.jar so relative + includes between the J2EE, Servlet and JSP schemas are correctly + resolved. (markt) +
  • +
  • Fix: + 55372: When starting Tomcat with the jpda option + to enable remote debugging, by default only listen on localhost for + connections from a debugger. Prior to this change, Tomcat listened on + all known addresses. (markt) +
  • +
+
+
\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/class-loader-howto.html b/test.dockerapp/tomcat/webapps/docs/class-loader-howto.html new file mode 100644 index 0000000..eca7f5c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/class-loader-howto.html @@ -0,0 +1,262 @@ + +Apache Tomcat 8 (8.0.53) - Class Loader HOW-TO

Class Loader HOW-TO

Table of Contents

Overview

+ +

Like many server applications, Tomcat installs a variety of class loaders +(that is, classes that implement java.lang.ClassLoader) to allow +different portions of the container, and the web applications running on the +container, to have access to different repositories of available classes and +resources. This mechanism is used to provide the functionality defined in the +Servlet Specification, version 2.4 — in particular, Sections 9.4 +and 9.6.

+ +

In a Java environment, class loaders are +arranged in a parent-child tree. Normally, when a class loader is asked to +load a particular class or resource, it delegates the request to a parent +class loader first, and then looks in its own repositories only if the parent +class loader(s) cannot find the requested class or resource. Note, that the +model for web application class loaders differs slightly from this, +as discussed below, but the main principles are the same.

+ +

When Tomcat is started, it creates a set of class loaders that are +organized into the following parent-child relationships, where the parent +class loader is above the child class loader:

+ +
      Bootstrap
+          |
+       System
+          |
+       Common
+       /     \
+  Webapp1   Webapp2 ...
+ +

The characteristics of each of these class loaders, including the source +of classes and resources that they make visible, are discussed in detail in +the following section.

+ +

Class Loader Definitions

+ +

As indicated in the diagram above, Tomcat creates the following class +loaders as it is initialized:

+
    +
  • Bootstrap — This class loader contains the basic + runtime classes provided by the Java Virtual Machine, plus any classes from + JAR files present in the System Extensions directory + ($JAVA_HOME/jre/lib/ext). Note: some JVMs may + implement this as more than one class loader, or it may not be visible + (as a class loader) at all.

  • +
  • System — This class loader is normally initialized + from the contents of the CLASSPATH environment variable. All + such classes are visible to both Tomcat internal classes, and to web + applications. However, the standard Tomcat startup scripts + ($CATALINA_HOME/bin/catalina.sh or + %CATALINA_HOME%\bin\catalina.bat) totally ignore the contents + of the CLASSPATH environment variable itself, and instead + build the System class loader from the following repositories: +

    +
      +
    • $CATALINA_HOME/bin/bootstrap.jar — Contains the + main() method that is used to initialize the Tomcat server, and the + class loader implementation classes it depends on.

    • +
    • $CATALINA_BASE/bin/tomcat-juli.jar or + $CATALINA_HOME/bin/tomcat-juli.jar — Logging + implementation classes. These include enhancement classes to + java.util.logging API, known as Tomcat JULI, + and a package-renamed copy of Apache Commons Logging library + used internally by Tomcat. + See logging documentation for more + details.

      +

      If tomcat-juli.jar is present in + $CATALINA_BASE/bin, it is used instead of the one in + $CATALINA_HOME/bin. It is useful in certain logging + configurations

    • +
    • $CATALINA_HOME/bin/commons-daemon.jar — The classes + from Apache Commons + Daemon project. + This JAR file is not present in the CLASSPATH built by + catalina.bat|.sh scripts, but is referenced + from the manifest file of bootstrap.jar.

    • +
    +
  • +
  • Common — This class loader contains additional + classes that are made visible to both Tomcat internal classes and to all + web applications.

    +

    Normally, application classes should NOT + be placed here. The locations searched by this class loader are defined by + the common.loader property in + $CATALINA_BASE/conf/catalina.properties. The default setting will search the + following locations in the order they are listed:

    +
      +
    • unpacked classes and resources in $CATALINA_BASE/lib
    • +
    • JAR files in $CATALINA_BASE/lib
    • +
    • unpacked classes and resources in $CATALINA_HOME/lib
    • +
    • JAR files in $CATALINA_HOME/lib
    • +
    +

    By default, this includes the following:

    +
      +
    • annotations-api.jar — JavaEE annotations classes.
    • +
    • catalina.jar — Implementation of the Catalina servlet + container portion of Tomcat.
    • +
    • catalina-ant.jar — Tomcat Catalina Ant tasks.
    • +
    • catalina-ha.jar — High availability package.
    • +
    • catalina-storeconfig.jar — Generation of XML + configuration files from current state
    • +
    • catalina-tribes.jar — Group communication package.
    • +
    • ecj-*.jar — Eclipse JDT Java compiler.
    • +
    • el-api.jar — EL 3.0 API.
    • +
    • jasper.jar — Tomcat Jasper JSP Compiler and Runtime.
    • +
    • jasper-el.jar — Tomcat Jasper EL implementation.
    • +
    • jsp-api.jar — JSP 2.3 API.
    • +
    • servlet-api.jar — Servlet 3.1 API.
    • +
    • tomcat-api.jar — Several interfaces defined by Tomcat.
    • +
    • tomcat-coyote.jar — Tomcat connectors and utility classes.
    • +
    • tomcat-dbcp.jar — Database connection pool + implementation based on package-renamed copy of Apache Commons Pool + and Apache Commons DBCP.
    • +
    • tomcat-i18n-**.jar — Optional JARs containing resource bundles + for other languages. As default bundles are also included in each + individual JAR, they can be safely removed if no internationalization + of messages is needed.
    • +
    • tomcat-jdbc.jar — An alternative database connection pool + implementation, known as Tomcat JDBC pool. See + documentation for more details.
    • +
    • tomcat-util.jar — Common classes used by various components of + Apache Tomcat.
    • +
    • tomcat-websocket.jar — WebSocket 1.1 implementation
    • +
    • websocket-api.jar — WebSocket 1.1 API
    • +
  • +
  • WebappX — A class loader is created for each web + application that is deployed in a single Tomcat instance. All unpacked + classes and resources in the /WEB-INF/classes directory of + your web application, plus classes and resources in JAR files + under the /WEB-INF/lib directory of your web application, + are made visible to this web application, but not to other ones.

  • +
+ +

As mentioned above, the web application class loader diverges from the +default Java delegation model (in accordance with the recommendations in the +Servlet Specification, version 2.4, section 9.7.2 Web Application Classloader). +When a request to load a +class from the web application's WebappX class loader is processed, +this class loader will look in the local repositories first, +instead of delegating before looking. There are exceptions. Classes which are +part of the JRE base classes cannot be overridden. For some classes (such as +the XML parser components in J2SE 1.4+), the Java endorsed feature can be +used up to Java 8. +Lastly, the web application class loader will always delegate first for JavaEE +API classes for the specifications implemented by Tomcat +(Servlet, JSP, EL, WebSocket). All other class loaders in Tomcat follow the +usual delegation pattern.

+ +

Therefore, from the perspective of a web application, class or resource +loading looks in the following repositories, in this order:

+
    +
  • Bootstrap classes of your JVM
  • +
  • /WEB-INF/classes of your web application
  • +
  • /WEB-INF/lib/*.jar of your web application
  • +
  • System class loader classes (described above)
  • +
  • Common class loader classes (described above)
  • +
+ +

If the web application class loader is +configured with +<Loader delegate="true"/> +then the order becomes:

+
    +
  • Bootstrap classes of your JVM
  • +
  • System class loader classes (described above)
  • +
  • Common class loader classes (described above)
  • +
  • /WEB-INF/classes of your web application
  • +
  • /WEB-INF/lib/*.jar of your web application
  • +
+ +

XML Parsers and Java

+ +

Starting with Java 1.4 a copy of JAXP APIs and an XML parser are packed +inside the JRE. This has impacts on applications that wish to use their own +XML parser.

+ +

In old versions of Tomcat, you could simply replace the XML parser +in the Tomcat libraries directory to change the parser +used by all web applications. However, this technique will not be effective +when you are running modern versions of Java, because the usual class loader +delegation process will always choose the implementation inside the JDK in +preference to this one.

+ +

Java supports a mechanism called the "Endorsed Standards Override +Mechanism" to allow replacement of APIs created outside of the JCP +(i.e. DOM and SAX from W3C). It can also be used to update the XML parser +implementation. For more information, see: + +http://docs.oracle.com/javase/1.5.0/docs/guide/standards/index.html.

+ +

Tomcat utilizes this mechanism by including the system property setting +-Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS in the +command line that starts the container. The default value of this option is +$CATALINA_HOME/endorsed. This endorsed directory is not +created by default. Note that the endorsed feature is no longer supported +with Java 9 and the above system property will only be set if either the +directory $CATALINA_HOME/endorsed exists, or the variable +JAVA_ENDORSED_DIRS has been set. +

+ +

Note that overriding any JRE component carries risk. If the overriding +component does not provide a 100% compatible API (e.g. the API provided by +Xerces is not 100% compatible with the XML API provided by the JRE) then there +is a risk that Tomcat and/or the deployed application will experience errors.

+ +

Running under a security manager

+ +

When running under a security manager the locations from which classes +are permitted to be loaded will also depend on the contents of your policy +file. See Security Manager HOW-TO +for further information.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/cluster-howto.html b/test.dockerapp/tomcat/webapps/docs/cluster-howto.html new file mode 100644 index 0000000..2aa4fd0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/cluster-howto.html @@ -0,0 +1,668 @@ + +Apache Tomcat 8 (8.0.53) - Clustering/Session Replication HOW-TO

Clustering/Session Replication HOW-TO

Important Note

+

You can also check the configuration reference documentation. +

+

Table of Contents

For the impatient

+

+ Simply add +

+
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+

+ to your <Engine> or your <Host> element to enable clustering. +

+

+ Using the above configuration will enable all-to-all session replication + using the DeltaManager to replicate session deltas. By all-to-all we mean that the session gets replicated to all the other + nodes in the cluster. This works great for smaller cluster but we don't recommend it for larger clusters(a lot of Tomcat nodes). + Also when using the delta manager it will replicate to all nodes, even nodes that don't have the application deployed.
+ To get around this problem, you'll want to use the BackupManager. This manager only replicates the session data to one backup + node, and only to nodes that have the application deployed. Downside of the BackupManager: not quite as battle tested as the delta manager. +

+

+ Here are some of the important default values: +

+
    +
  1. Multicast address is 228.0.0.4
  2. +
  3. Multicast port is 45564 (the port and the address together determine cluster membership.
  4. +
  5. The IP broadcasted is java.net.InetAddress.getLocalHost().getHostAddress() (make sure you don't broadcast 127.0.0.1, this is a common error)
  6. +
  7. The TCP port listening for replication messages is the first available server socket in range 4000-4100
  8. +
  9. Listener is configured ClusterSessionListener
  10. +
  11. Two interceptors are configured TcpFailureDetector and MessageDispatch15Interceptor
  12. +
+

+ The following is the default cluster configuration: +

+
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
+                 channelSendOptions="8">
+
+          <Manager className="org.apache.catalina.ha.session.DeltaManager"
+                   expireSessionsOnShutdown="false"
+                   notifyListenersOnReplication="true"/>
+
+          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
+            <Membership className="org.apache.catalina.tribes.membership.McastService"
+                        address="228.0.0.4"
+                        port="45564"
+                        frequency="500"
+                        dropTime="3000"/>
+            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
+                      address="auto"
+                      port="4000"
+                      autoBind="100"
+                      selectorTimeout="5000"
+                      maxThreads="6"/>
+
+            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
+              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
+            </Sender>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
+          </Channel>
+
+          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
+                 filter=""/>
+          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
+
+          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
+                    tempDir="/tmp/war-temp/"
+                    deployDir="/tmp/war-deploy/"
+                    watchDir="/tmp/war-listen/"
+                    watchEnabled="false"/>
+
+          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
+        </Cluster>
+

Will cover this section in more detail later in this document.

+

Security

+ +

The cluster implementation is written on the basis that a secure, trusted +network is used for all of the cluster related network traffic. It is not safe +to run a cluster on a insecure, untrusted network.

+ +

There are many options for providing a secure, trusted network for use by a +Tomcat cluster. These include:

+
    +
  • private LAN
  • +
  • a Virtual Private Network (VPN)
  • +
  • IPSEC
  • +
+ +

Cluster Basics

+ +

To run session replication in your Tomcat 8 container, the following steps +should be completed:

+
    +
  • All your session attributes must implement java.io.Serializable
  • +
  • Uncomment the Cluster element in server.xml
  • +
  • If you have defined custom cluster valves, make sure you have the ReplicationValve defined as well under the Cluster element in server.xml
  • +
  • If your Tomcat instances are running on the same machine, make sure the Receiver.port + attribute is unique for each instance, in most cases Tomcat is smart enough to resolve this on it's own by autodetecting available ports in the range 4000-4100
  • +
  • Make sure your web.xml has the + <distributable/> element
  • +
  • If you are using mod_jk, make sure that jvmRoute attribute is set at your Engine <Engine name="Catalina" jvmRoute="node01" > + and that the jvmRoute attribute value matches your worker name in workers.properties
  • +
  • Make sure that all nodes have the same time and sync with NTP service!
  • +
  • Make sure that your loadbalancer is configured for sticky session mode.
  • +
+

Load balancing can be achieved through many techniques, as seen in the +Load Balancing chapter.

+

Note: Remember that your session state is tracked by a cookie, so your URL must look the same from the out + side otherwise, a new session will be created.

+

The Cluster module uses the Tomcat JULI logging framework, so you can configure logging + through the regular logging.properties file. To track messages, you can enable logging on the key: org.apache.catalina.tribes.MESSAGES

+

Overview

+ +

To enable session replication in Tomcat, three different paths can be followed to achieve the exact same thing:

+
    +
  1. Using session persistence, and saving the session to a shared file system (PersistenceManager + FileStore)
  2. +
  3. Using session persistence, and saving the session to a shared database (PersistenceManager + JDBCStore)
  4. +
  5. Using in-memory-replication, using the SimpleTcpCluster that ships with Tomcat (lib/catalina-tribes.jar + lib/catalina-ha.jar)
  6. +
+ +

In this release of session replication, Tomcat can perform an all-to-all replication of session state using the DeltaManager or + perform backup replication to only one node using the BackupManager. + The all-to-all replication is an algorithm that is only efficient when the clusters are small. For larger clusters, to use + a primary-secondary session replication where the session will only be stored at one backup server simply setup the BackupManager.
+ Currently you can use the domain worker attribute (mod_jk > 1.2.8) to build cluster partitions + with the potential of having a more scalable cluster solution with the DeltaManager(you'll need to configure the domain interceptor for this). + In order to keep the network traffic down in an all-to-all environment, you can split your cluster + into smaller groups. This can be easily achieved by using different multicast addresses for the different groups. + A very simple setup would look like this: +

+ +
        DNS Round Robin
+               |
+         Load Balancer
+          /           \
+      Cluster1      Cluster2
+      /     \        /     \
+  Tomcat1 Tomcat2  Tomcat3 Tomcat4
+ +

What is important to mention here, is that session replication is only the beginning of clustering. + Another popular concept used to implement clusters is farming, i.e., you deploy your apps only to one + server, and the cluster will distribute the deployments across the entire cluster. + This is all capabilities that can go into with the FarmWarDeployer (s. cluster example at server.xml)

+

In the next section will go deeper into how session replication works and how to configure it.

+ +

Cluster Information

+

Membership is established using multicast heartbeats. + Hence, if you wish to subdivide your clusters, you can do this by + changing the multicast IP address or port in the <Membership> element. +

+

+ The heartbeat contains the IP address of the Tomcat node and the TCP port that + Tomcat listens to for replication traffic. All data communication happens over TCP. +

+

+ The ReplicationValve is used to find out when the request has been completed and initiate the + replication, if any. Data is only replicated if the session has changed (by calling setAttribute or removeAttribute + on the session). +

+

+ One of the most important performance considerations is the synchronous versus asynchronous replication. + In a synchronous replication mode the request doesn't return until the replicated session has been + sent over the wire and reinstantiated on all the other cluster nodes. + Synchronous vs. asynchronous is configured using the channelSendOptions + flag and is an integer value. The default value for the SimpleTcpCluster/DeltaManager combo is + 8, which is asynchronous. You can read more on the send flag(overview) or the + send flag(javadoc). + During async replication, the request is returned before the data has been replicated. async replication yields shorter + request times, and synchronous replication guarantees the session to be replicated before the request returns. +

+

Bind session after crash to failover node

+

+ If you are using mod_jk and not using sticky sessions or for some reasons sticky session don't + work, or you are simply failing over, the session id will need to be modified as it previously contained + the worker id of the previous tomcat (as defined by jvmRoute in the Engine element). + To solve this, we will use the JvmRouteBinderValve. +

+

+ The JvmRouteBinderValve rewrites the session id to ensure that the next request will remain sticky + (and not fall back to go to random nodes since the worker is no longer available) after a fail over. + The valve rewrites the JSESSIONID value in the cookie with the same name. + Not having this valve in place, will make it harder to ensure stickiness in case of a failure for the mod_jk module. +

+

+ Remember, if you are adding your own valves in server.xml then the defaults are no longer valid, + make sure that you add in all the appropriate valves as defined by the default. +

+

+ Hint:
+ With attribute sessionIdAttribute you can change the request attribute name that included the old session id. + Default attribute name is org.apache.catalina.ha.session.JvmRouteOrignalSessionID. +

+

+ Trick:
+ You can enable this mod_jk turnover mode via JMX before you drop a node to all backup nodes! + Set enable true on all JvmRouteBinderValve backups, disable worker at mod_jk + and then drop node and restart it! Then enable mod_jk Worker and disable JvmRouteBinderValves again. + This use case means that only requested session are migrated. +

+ + +

Configuration Example

+
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
+                 channelSendOptions="6">
+
+          <Manager className="org.apache.catalina.ha.session.BackupManager"
+                   expireSessionsOnShutdown="false"
+                   notifyListenersOnReplication="true"
+                   mapSendOptions="6"/>
+          <!--
+          <Manager className="org.apache.catalina.ha.session.DeltaManager"
+                   expireSessionsOnShutdown="false"
+                   notifyListenersOnReplication="true"/>
+          -->
+          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
+            <Membership className="org.apache.catalina.tribes.membership.McastService"
+                        address="228.0.0.4"
+                        port="45564"
+                        frequency="500"
+                        dropTime="3000"/>
+            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
+                      address="auto"
+                      port="5000"
+                      selectorTimeout="100"
+                      maxThreads="6"/>
+
+            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
+              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
+            </Sender>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
+          </Channel>
+
+          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
+                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
+
+          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
+                    tempDir="/tmp/war-temp/"
+                    deployDir="/tmp/war-deploy/"
+                    watchDir="/tmp/war-listen/"
+                    watchEnabled="false"/>
+
+          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
+        </Cluster>
+

+ Break it down!! +

+
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
+                 channelSendOptions="6">
+

+ The main element, inside this element all cluster details can be configured. + The channelSendOptions is the flag that is attached to each message sent by the + SimpleTcpCluster class or any objects that are invoking the SimpleTcpCluster.send method. + The description of the send flags is available at + our javadoc site + The DeltaManager sends information using the SimpleTcpCluster.send method, while the backup manager + sends it itself directly through the channel. +
For more info, Please visit the reference documentation +

+
          <Manager className="org.apache.catalina.ha.session.BackupManager"
+                   expireSessionsOnShutdown="false"
+                   notifyListenersOnReplication="true"
+                   mapSendOptions="6"/>
+          <!--
+          <Manager className="org.apache.catalina.ha.session.DeltaManager"
+                   expireSessionsOnShutdown="false"
+                   notifyListenersOnReplication="true"/>
+          -->
+

+ This is a template for the manager configuration that will be used if no manager is defined in the <Context> + element. In Tomcat 5.x each webapp marked distributable had to use the same manager, this is no longer the case + since Tomcat you can define a manager class for each webapp, so that you can mix managers in your cluster. + Obviously the managers on one node's application has to correspond with the same manager on the same application on the other node. + If no manager has been specified for the webapp, and the webapp is marked <distributable/> Tomcat will take this manager configuration + and create a manager instance cloning this configuration. +
For more info, Please visit the reference documentation +

+
          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
+

+ The channel element is Tribes, the group communication framework + used inside Tomcat. This element encapsulates everything that has to do with communication and membership logic. +
For more info, Please visit the reference documentation +

+
            <Membership className="org.apache.catalina.tribes.membership.McastService"
+                        address="228.0.0.4"
+                        port="45564"
+                        frequency="500"
+                        dropTime="3000"/>
+

+ Membership is done using multicasting. Please note that Tribes also supports static memberships using the + StaticMembershipInterceptor if you want to extend your membership to points beyond multicasting. + The address attribute is the multicast address used and the port is the multicast port. These two together + create the cluster separation. If you want a QA cluster and a production cluster, the easiest config is to + have the QA cluster be on a separate multicast address/port combination than the production cluster.
+ The membership component broadcasts TCP address/port of itself to the other nodes so that communication between + nodes can be done over TCP. Please note that the address being broadcasted is the one of the + Receiver.address attribute. +
For more info, Please visit the reference documentation +

+
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
+                      address="auto"
+                      port="5000"
+                      selectorTimeout="100"
+                      maxThreads="6"/>
+

+ In tribes the logic of sending and receiving data has been broken into two functional components. The Receiver, as the name suggests + is responsible for receiving messages. Since the Tribes stack is thread less, (a popular improvement now adopted by other frameworks as well), + there is a thread pool in this component that has a maxThreads and minThreads setting.
+ The address attribute is the host address that will be broadcasted by the membership component to the other nodes. +
For more info, Please visit the reference documentation +

+
            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
+              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
+            </Sender>
+

+ The sender component, as the name indicates is responsible for sending messages to other nodes. + The sender has a shell component, the ReplicationTransmitter but the real stuff done is done in the + sub component, Transport. + Tribes support having a pool of senders, so that messages can be sent in parallel and if using the NIO sender, + you can send messages concurrently as well.
+ Concurrently means one message to multiple senders at the same time and Parallel means multiple messages to multiple senders + at the same time. +
For more info, Please visit the reference documentation +

+
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
+            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
+          </Channel>
+

+ Tribes uses a stack to send messages through. Each element in the stack is called an interceptor, and works much like the valves do + in the Tomcat servlet container. + Using interceptors, logic can be broken into more manageable pieces of code. The interceptors configured above are:
+ TcpFailureDetector - verifies crashed members through TCP, if multicast packets get dropped, this interceptor protects against false positives, + ie the node marked as crashed even though it still is alive and running.
+ MessageDispatch15Interceptor - dispatches messages to a thread (thread pool) to send message asynchronously.
+ ThroughputInterceptor - prints out simple stats on message traffic.
+ Please note that the order of interceptors is important. The way they are defined in server.xml is the way they are represented in the + channel stack. Think of it as a linked list, with the head being the first most interceptor and the tail the last. +
For more info, Please visit the reference documentation +

+
          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
+                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
+

+ The cluster uses valves to track requests to web applications, we've mentioned the ReplicationValve and the JvmRouteBinderValve above. + The <Cluster> element itself is not part of the pipeline in Tomcat, instead the cluster adds the valve to its parent container. + If the <Cluster> elements is configured in the <Engine> element, the valves get added to the engine and so on. +
For more info, Please visit the reference documentation +

+
          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
+                    tempDir="/tmp/war-temp/"
+                    deployDir="/tmp/war-deploy/"
+                    watchDir="/tmp/war-listen/"
+                    watchEnabled="false"/>
+

+ The default tomcat cluster supports farmed deployment, ie, the cluster can deploy and undeploy applications on the other nodes. + The state of this component is currently in flux but will be addressed soon. There was a change in the deployment algorithm + between Tomcat 5.0 and 5.5 and at that point, the logic of this component changed to where the deploy dir has to match the + webapps directory. +
For more info, Please visit the reference documentation +

+
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
+        </Cluster>
+

+ Since the SimpleTcpCluster itself is a sender and receiver of the Channel object, components can register themselves as listeners to + the SimpleTcpCluster. The listener above ClusterSessionListener listens for DeltaManager replication messages + and applies the deltas to the manager that in turn applies it to the session. +
For more info, Please visit the reference documentation +

+ +

Cluster Architecture

+ +

Component Levels:

+
         Server
+           |
+         Service
+           |
+         Engine
+           |  \
+           |  --- Cluster --*
+           |
+         Host
+           |
+         ------
+        /      \
+     Cluster    Context(1-N)
+        |             \
+        |             -- Manager
+        |                   \
+        |                   -- DeltaManager
+        |                   -- BackupManager
+        |
+     ---------------------------
+        |                       \
+      Channel                    \
+    ----------------------------- \
+        |                          \
+     Interceptor_1 ..               \
+        |                            \
+     Interceptor_N                    \
+    -----------------------------      \
+     |          |         |             \
+   Receiver    Sender   Membership       \
+                                         -- Valve
+                                         |      \
+                                         |       -- ReplicationValve
+                                         |       -- JvmRouteBinderValve
+                                         |
+                                         -- LifecycleListener
+                                         |
+                                         -- ClusterListener
+                                         |      \
+                                         |       -- ClusterSessionListener
+                                         |
+                                         -- Deployer
+                                                \
+                                                 -- FarmWarDeployer
+
+
+ + +

How it Works

+

To make it easy to understand how clustering works, We are gonna take you through a series of scenarios. + In the scenario we only plan to use two tomcat instances TomcatA and TomcatB. + We will cover the following sequence of events:

+ +
    +
  1. TomcatA starts up
  2. +
  3. TomcatB starts up (Wait that TomcatA start is complete)
  4. +
  5. TomcatA receives a request, a session S1 is created.
  6. +
  7. TomcatA crashes
  8. +
  9. TomcatB receives a request for session S1
  10. +
  11. TomcatA starts up
  12. +
  13. TomcatA receives a request, invalidate is called on the session (S1)
  14. +
  15. TomcatB receives a request, for a new session (S2)
  16. +
  17. TomcatA The session S2 expires due to inactivity.
  18. +
+ +

Ok, now that we have a good sequence, we will take you through exactly what happens in the session replication code

+ +
    +
  1. TomcatA starts up +

    + Tomcat starts up using the standard start up sequence. When the Host object is created, a cluster object is associated with it. + When the contexts are parsed, if the distributable element is in place in web.xml + Tomcat asks the Cluster class (in this case SimpleTcpCluster) to create a manager + for the replicated context. So with clustering enabled, distributable set in web.xml + Tomcat will create a DeltaManager for that context instead of a StandardManager. + The cluster class will start up a membership service (multicast) and a replication service (tcp unicast). + More on the architecture further down in this document. +

    +
  2. +
  3. TomcatB starts up +

    + When TomcatB starts up, it follows the same sequence as TomcatA did with one exception. + The cluster is started and will establish a membership (TomcatA,TomcatB). + TomcatB will now request the session state from a server that already exists in the cluster, + in this case TomcatA. TomcatA responds to the request, and before TomcatB starts listening + for HTTP requests, the state has been transferred from TomcatA to TomcatB. + In case TomcatA doesn't respond, TomcatB will time out after 60 seconds, and issue a log + entry. The session state gets transferred for each web application that has distributable in + its web.xml. Note: To use session replication efficiently, all your tomcat instances should be + configured the same. +

    +
  4. +
  5. TomcatA receives a request, a session S1 is created. +

    + The request coming in to TomcatA is treated exactly the same way as without session replication. + The action happens when the request is completed, the ReplicationValve will intercept + the request before the response is returned to the user. + At this point it finds that the session has been modified, and it uses TCP to replicate the + session to TomcatB. Once the serialized data has been handed off to the operating systems TCP logic, + the request returns to the user, back through the valve pipeline. + For each request the entire session is replicated, this allows code that modifies attributes + in the session without calling setAttribute or removeAttribute to be replicated. + a useDirtyFlag configuration parameter can be used to optimize the number of times + a session is replicated. +

    + +
  6. +
  7. TomcatA crashes +

    + When TomcatA crashes, TomcatB receives a notification that TomcatA has dropped out + of the cluster. TomcatB removes TomcatA from its membership list, and TomcatA will no longer + be notified of any changes that occurs in TomcatB. + The load balancer will redirect the requests from TomcatA to TomcatB and all the sessions + are current. +

    +
  8. +
  9. TomcatB receives a request for session S1 +

    Nothing exciting, TomcatB will process the request as any other request. +

    +
  10. +
  11. TomcatA starts up +

    Upon start up, before TomcatA starts taking new request and making itself + available to it will follow the start up sequence described above 1) 2). + It will join the cluster, contact TomcatB for the current state of all the sessions. + And once it receives the session state, it finishes loading and opens its HTTP/mod_jk ports. + So no requests will make it to TomcatA until it has received the session state from TomcatB. +

    +
  12. +
  13. TomcatA receives a request, invalidate is called on the session (S1) +

    The invalidate call is intercepted, and the session is queued with invalidated sessions. + When the request is complete, instead of sending out the session that has changed, it sends out + an "expire" message to TomcatB and TomcatB will invalidate the session as well. +

    + +
  14. +
  15. TomcatB receives a request, for a new session (S2) +

    Same scenario as in step 3) +

    + + +
  16. +
  17. TomcatA The session S2 expires due to inactivity. +

    The invalidate call is intercepted the same was as when a session is invalidated by the user, + and the session is queued with invalidated sessions. + At this point, the invalidated session will not be replicated across until + another request comes through the system and checks the invalid queue. +

    +
  18. +
+ +

Phuuuhh! :)

+ +

Membership + Clustering membership is established using very simple multicast pings. + Each Tomcat instance will periodically send out a multicast ping, + in the ping message the instance will broad cast its IP and TCP listen port + for replication. + If an instance has not received such a ping within a given timeframe, the + member is considered dead. Very simple, and very effective! + Of course, you need to enable multicasting on your system. +

+ +

TCP Replication + Once a multicast ping has been received, the member is added to the cluster + Upon the next replication request, the sending instance will use the host and + port info and establish a TCP socket. Using this socket it sends over the serialized data. + The reason I choose TCP sockets is because it has built in flow control and guaranteed delivery. + So I know, when I send some data, it will make it there :) +

+ +

Distributed locking and pages using frames + Tomcat does not keep session instances in sync across the cluster. + The implementation of such logic would be to much overhead and cause all + kinds of problems. If your client accesses the same session + simultaneously using multiple requests, then the last request + will override the other sessions in the cluster. +

+ +

Monitoring your Cluster with JMX

+

Monitoring is a very important question when you use a cluster. Some of the cluster objects are JMX MBeans

+

Add the following parameter to your startup script with Java 5:

+
set CATALINA_OPTS=\
+-Dcom.sun.management.jmxremote \
+-Dcom.sun.management.jmxremote.port=%my.jmx.port% \
+-Dcom.sun.management.jmxremote.ssl=false \
+-Dcom.sun.management.jmxremote.authenticate=false
+ +

+ List of Cluster Mbeans +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionMBean ObjectName - EngineMBean ObjectName - Host
ClusterThe complete cluster elementtype=Clustertype=Cluster,host=${HOST}
DeltaManagerThis manager control the sessions and handle session replication type=Manager,context=${APP.CONTEXT.PATH}, host=${HOST}type=Manager,context=${APP.CONTEXT.PATH}, host=${HOST}
FarmWarDeployerManages the process of deploying an application to all nodes in the clusterNot supportedtype=Cluster, host=${HOST}, component=deployer
MemberRepresents a node in the clustertype=Cluster, component=member, name=${NODE_NAME}type=Cluster, host=${HOST}, component=member, name=${NODE_NAME}
ReplicationValveThis valve control the replication to the backup nodestype=Valve,name=ReplicationValvetype=Valve,name=ReplicationValve,host=${HOST}
JvmRouteBinderValveThis is a cluster fallback valve to change the Session ID to the current tomcat jvmroute.type=Valve,name=JvmRouteBinderValve, + context=${APP.CONTEXT.PATH}type=Valve,name=JvmRouteBinderValve,host=${HOST}, + context=${APP.CONTEXT.PATH}
+

FAQ

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/comments.html b/test.dockerapp/tomcat/webapps/docs/comments.html new file mode 100644 index 0000000..4769cde --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/comments.html @@ -0,0 +1,122 @@ + +Apache Tomcat 8 (8.0.53) - Documentation User Comments

Documentation User Comments

Introduction

+ +

The Tomcat documentation integrates the +Apache Comments System. +It allows users to add comments to most documentation pages. The comments +section can be found at the end of each page.

+ +

Allowed Content

+ +

Please use the Apache Comments System responsibly. We can only provide +this service to the community as long as it isn't misused.

+ +

The comments are not for general Q&A. +Comments should be pointed towards suggestions on improving the documentation +or server. Questions on how to use Apache Tomcat should be directed +to our mailing lists.

+ +

Comments may be removed by moderators if they are either +implemented or considered invalid/off-topic.

+ +

HTML is not allowed in comments, and will just display as raw source code +if attempted. Links that do not point to an Apache site (*.apache.org) will +need approval by a moderator before the comment is visible to regular visitors.

+ +

License

+ +

Any submitted comments must be contributed under the terms of the +Apache License, Version 2.0.

+ +

Verified Users

+ +

Verified users gain the Apache feather next to their name, +and may post comments with links in them without requiring approval +by a moderator before the comments are shown. Being a verified user +in itself does not give you moderating rights. If you are interested +in becoming a verified user, please contact us on the +users mailing list.

+ +

All ASF committers are automatically verified users.

+ +

Moderators

+ +

Moderators are allowed to mark comments as "Resolved", "Invalid" +or "Sticky", remove marks, approve comments e.g. if they contain +a link, and delete comments. Moderators can also subscribe to new +comments and comment updates and use the dashboard to gain some +overview over all comments of a site.

+ +

To use the moderation features, you need to login to the comments +system. Furthermore you will need to allow cookies to be set for +comments.apache.org (this is done using a secure https cookie). Once +logged in as a moderator you will see additional moderation +options attached to each comment.

+ +

If you are a long time follower of the Apache Tomcat projects +and you are interested in becoming a moderator, please contact us on the +users mailing list.

+ +

Privacy Policy

+ +

No data except what you personally submit is kept on record. +A cookie is used to keep track of moderators and other people +who wish to create an account to avoid having to enter their +credentials whenever they wish to post a comment.

+ +

To prevent spam and unsolicited comments, we use a digest of +visitors' IPs to keep track of comments posted by them.

+ +

Entering an email address when you post a comment is completely +optional, and will not be shared with anyone. If you enter an +email address, it will be used to notify you when someone posts +a reply to one of your comments, provided you have registered +an account and validated your email address.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/ajp.html b/test.dockerapp/tomcat/webapps/docs/config/ajp.html new file mode 100644 index 0000000..5b605f8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/ajp.html @@ -0,0 +1,755 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The AJP Connector

The AJP Connector

Table of Contents

Introduction

+ +

The AJP Connector element represents a + Connector component that communicates with a web + connector via the AJP protocol. This is used for cases + where you wish to invisibly integrate Tomcat into an existing (or new) + Apache installation, and you want Apache to handle the static content + contained in the web application, and/or utilize Apache's SSL + processing.

+ +

This connector supports load balancing when used in conjunction with + the jvmRoute attribute of the + Engine.

+ +

The native connectors supported with this Tomcat release are:

+
    +
  • JK 1.2.x with any of the supported servers. See + the JK docs + for details.
  • +
  • mod_proxy on Apache httpd 2.x (included by default in Apache HTTP + Server 2.2), with AJP enabled: see + the + httpd docs for details.
  • +
+ +

Other native connectors supporting AJP may work, but are no longer + supported.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Connector + support the following attributes:

+ +
+ Attribute + + Description +
ajpFlush +

A boolean value which can be used to enable or disable sending + AJP flush messages to the fronting proxy whenever an explicit + flush happens. The default value is true.
+ An AJP flush message is a SEND_BODY_CHUNK packet with no body content. + Proxy implementations like mod_jk or mod_proxy_ajp will flush the + data buffered in the web server to the client when they receive + such a packet. Setting this to false can reduce + AJP packet traffic but might delay sending packets to the client. + At the end of the response, AJP does always flush to the client.

+
allowTrace +

A boolean value which can be used to enable or disable the TRACE + HTTP method. If not specified, this attribute is set to false.

+
asyncTimeout +

The default timeout for asynchronous requests in milliseconds. If not + specified, this attribute is set to the Servlet specification default of + 30000 (30 seconds).

+
enableLookups +

Set to true if you want calls to + request.getRemoteHost() to perform DNS lookups in + order to return the actual host name of the remote client. Set + to false to skip the DNS lookup and return the IP + address in String form instead (thereby improving performance). + By default, DNS lookups are disabled.

+
maxHeaderCount +

The maximum number of headers in a request that are allowed by the + container. A request that contains more headers than the specified limit + will be rejected. A value of less than 0 means no limit. + If not specified, a default of 100 is used.

+
maxParameterCount +

The maximum number of parameter and value pairs (GET plus POST) which + will be automatically parsed by the container. Parameter and value pairs + beyond this limit will be ignored. A value of less than 0 means no limit. + If not specified, a default of 10000 is used. Note that + FailedRequestFilter filter can be + used to reject requests that hit the limit.

+
maxPostSize +

The maximum size in bytes of the POST which will be handled by + the container FORM URL parameter parsing. The limit can be disabled by + setting this attribute to a value less than zero. If not specified, this + attribute is set to 2097152 (2 megabytes). Note that the + FailedRequestFilter + can be used to reject requests that exceed this limit.

+
maxSavePostSize +

The maximum size in bytes of the POST which will be saved/buffered by + the container during FORM or CLIENT-CERT authentication. For both types + of authentication, the POST will be saved/buffered before the user is + authenticated. For CLIENT-CERT authentication, the POST is buffered for + the duration of the SSL handshake and the buffer emptied when the request + is processed. For FORM authentication the POST is saved whilst the user + is re-directed to the login form and is retained until the user + successfully authenticates or the session associated with the + authentication request expires. The limit can be disabled by setting this + attribute to -1. Setting the attribute to zero will disable the saving of + POST data during authentication. If not specified, this attribute is set + to 4096 (4 kilobytes).

+
parseBodyMethods +

A comma-separated list of HTTP methods for which request + bodies will be parsed for request parameters identically + to POST. This is useful in RESTful applications that want to + support POST-style semantics for PUT requests. + Note that any setting other than POST causes Tomcat + to behave in a way that goes against the intent of the servlet + specification. + The HTTP method TRACE is specifically forbidden here in accordance + with the HTTP specification. + The default is POST

+
port +

The TCP port number on which this Connector + will create a server socket and await incoming connections. Your + operating system will allow only one server application to listen + to a particular port number on a particular IP address. If the special + value of 0 (zero) is used, then Tomcat will select a free port at random + to use for this connector. This is typically only useful in embedded and + testing applications.

+
protocol +

Sets the protocol to handle incoming traffic. To configure an AJP + connector this must be specified. If no value for protocol is provided, + an HTTP connector rather than an AJP connector + will be configured.
+ The standard protocol value for an AJP connector is AJP/1.3 + which uses an auto-switching mechanism to select either a Java NIO based + connector or an APR/native based connector. If the + PATH (Windows) or LD_LIBRARY_PATH (on most unix + systems) environment variables contain the Tomcat native library, the + native/APR connector will be used. If the native library cannot be + found, the Java NIO based connector will be used.
+ To use an explicit protocol rather than rely on the auto-switching + mechanism described above, the following values may be used:
+ org.apache.coyote.ajp.AjpProtocol + - blocking Java connector
+ org.apache.coyote.ajp.AjpNioProtocol + - non blocking Java NIO connector.
+ org.apache.coyote.ajp.AjpNio2Protocol + - non blocking Java NIO2 connector.
+ org.apache.coyote.ajp.AjpAprProtocol + - the APR/native connector.
+ Custom implementations may also be used.
+ Take a look at our Connector + Comparison chart. +

+
proxyName +

If this Connector is being used in a proxy + configuration, configure this attribute to specify the server name + to be returned for calls to request.getServerName(). + See Proxy Support for more + information.

+
proxyPort +

If this Connector is being used in a proxy + configuration, configure this attribute to specify the server port + to be returned for calls to request.getServerPort(). + See Proxy Support for more + information.

+
redirectPort +

If this Connector is supporting non-SSL + requests, and a request is received for which a matching + <security-constraint> requires SSL transport, + Catalina will automatically redirect the request to the port + number specified here.

+
scheme +

Set this attribute to the name of the protocol you wish to have + returned by calls to request.getScheme(). For + example, you would set this attribute to "https" + for an SSL Connector. The default value is "http". +

+
secure +

Set this attribute to true if you wish to have + calls to request.isSecure() to return true + for requests received by this Connector. You would want this on an + SSL Connector or a non SSL connector that is receiving data from a + SSL accelerator, like a crypto card, a SSL appliance or even a webserver. + The default value is false.

+
URIEncoding +

This specifies the character encoding used to decode the URI bytes, + after %xx decoding the URL. If not specified, UTF-8 will be used unless + the org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to true + in which case ISO-8859-1 will be used.

+
useBodyEncodingForURI +

This specifies if the encoding specified in contentType should be used + for URI query parameters, instead of using the URIEncoding. This + setting is present for compatibility with Tomcat 4.1.x, where the + encoding specified in the contentType, or explicitly set using + Request.setCharacterEncoding method was also used for the parameters from + the URL. The default value is false. +

+

Notes: See notes on this attribute in + HTTP Connector documentation.

+
useIPVHosts +

Set this attribute to true to cause Tomcat to use + the IP address passed by the native web server to determine the Host + to send the request to. The default value is false.

+
xpoweredBy +

Set this attribute to true to cause Tomcat to advertise + support for the Servlet specification using the header recommended in the + specification. The default value is false.

+
+ +
+ +

Standard Implementations

+ +

To use AJP, you must specify the protocol attribute (see above).

+ +

The standard AJP connectors (BIO, NIO, NIO2 and APR/native) all support + the following attributes in addition to the common Connector attributes + listed above.

+ +
+ Attribute + + Description +
acceptCount +

The maximum queue length for incoming connection requests when + all possible request processing threads are in use. Any requests + received when the queue is full will be refused. The default + value is 100.

+
acceptorThreadCount +

The number of threads to be used to accept connections. Increase this + value on a multi CPU machine, although you would never really need more + than 2. Also, with a lot of non keep alive connections, you + might want to increase this value as well. Default value is + 1.

+
acceptorThreadPriority +

The priority of the acceptor threads. The threads used to accept + new connections. The default value is 5 (the value of the + java.lang.Thread.NORM_PRIORITY constant). See the JavaDoc + for the java.lang.Thread class for more details on what + this priority means.

+
address +

For servers with more than one IP address, this attribute + specifies which address will be used for listening on the specified + port. By default, this port will be used on all IP addresses + associated with the server. A value of 127.0.0.1 + indicates that the Connector will only listen on the loopback + interface.

+
bindOnInit +

Controls when the socket used by the connector is bound. By default it + is bound when the connector is initiated and unbound when the connector is + destroyed. If set to false, the socket will be bound when the + connector is started and unbound when it is stopped.

+
clientCertProvider +

When client certificate information is presented in a form other than + instances of java.security.cert.X509Certificate it needs to + be converted before it can be used and this property controls which JSSE + provider is used to perform the conversion. For example it is used with + the AJP connectors, the HTTP APR connector and + with the + org.apache.catalina.valves.SSLValve.If not specified, the default + provider will be used.

+
connectionLinger +

The number of seconds during which the sockets used by this + Connector will linger when they are closed. The default + value is -1 which disables socket linger.

+
connectionTimeout +

The number of milliseconds this Connector will wait, + after accepting a connection, for the request URI line to be + presented. The default value for AJP protocol connectors + is -1 (i.e. infinite).

+
executor +

A reference to the name in an Executor + element. If this attribute is set, and the named executor exists, the + connector will use the executor, and all the other thread attributes will + be ignored. Note that if a shared executor is not specified for a + connector then the connector will use a private, internal executor to + provide the thread pool.

+
executorTerminationTimeoutMillis +

The time that the private internal executor will wait for request + processing threads to terminate before continuing with the process of + stopping the connector. If not set, the default is 0 (zero) + for the BIO connector and 5000 (5 seconds) for the NIO, NIO2 + and APR/native connectors.

+
keepAliveTimeout +

The number of milliseconds this Connector will wait for + another AJP request before closing the connection. + The default value is to use the value that has been set for the + connectionTimeout attribute.

+
maxConnections +

The maximum number of connections that the server will accept and + process at any given time. When this number has been reached, the server + will accept, but not process, one further connection. This additional + connection be blocked until the number of connections being processed + falls below maxConnections at which point the server will + start accepting and processing new connections again. Note that once the + limit has been reached, the operating system may still accept connections + based on the acceptCount setting. The default value varies by + connector type. For BIO the default is the value of + maxThreads unless an Executor + is used in which case the default will be the value of maxThreads from the + executor. For NIO and NIO2 the default is 10000. + For APR/native, the default is 8192.

+

Note that for APR/native on Windows, the configured value will be + reduced to the highest multiple of 1024 that is less than or equal to + maxConnections. This is done for performance reasons.
+ If set to a value of -1, the maxConnections feature is disabled + and connections are not counted.

+
maxCookieCount +

The maximum number of cookies that are permitted for a request. A value + of less than zero means no limit. If not specified, a default value of 200 + will be used.

+
maxThreads +

The maximum number of request processing threads to be created + by this Connector, which therefore determines the + maximum number of simultaneous requests that can be handled. If + not specified, this attribute is set to 200. If an executor is associated + with this connector, this attribute is ignored as the connector will + execute tasks using the executor rather than an internal thread pool. Note + that if an executor is configured any value set for this attribute will be + recorded correctly but it will be reported (e.g. via JMX) as + -1 to make clear that it is not used.

+
minSpareThreads +

The minimum number of threads always kept running. This includes both + active and idle threads. If not specified, the default of 10 + is used. If an executor is associated with this connector, this attribute + is ignored as the connector will execute tasks using the executor rather + than an internal thread pool. Note that if an executor is configured any + value set for this attribute will be recorded correctly but it will be + reported (e.g. via JMX) as -1 to make clear that it is not + used.

+
packetSize +

This attribute sets the maximum AJP packet size in Bytes. The maximum + value is 65536. It should be the same as the max_packet_size + directive configured for mod_jk. Normally it is not necessary to change + the maximum packet size. Problems with the default value have been + reported when sending certificates or certificate chains. The default + value is 8192. If set to less than 8192 then the setting will ignored and + the default value of 8192 used.

+
processorCache +

The protocol handler caches Processor objects to speed up performance. + This setting dictates how many of these objects get cached. + -1 means unlimited, default is 200. If not using + Servlet 3.0 asynchronous processing, a good default is to use the same as + the maxThreads setting. If using Servlet 3.0 asynchronous processing, a + good default is to use the larger of maxThreads and the maximum number of + expected concurrent requests (synchronous and asynchronous).

+
requiredSecret +

Only requests from workers with this secret keyword will be accepted. +

+
tcpNoDelay +

If set to true, the TCP_NO_DELAY option will be + set on the server socket, which improves performance under most + circumstances. This is set to true by default.

+
threadPriority +

The priority of the request processing threads within the JVM. + The default value is 5 (the value of the + java.lang.Thread.NORM_PRIORITY constant). See the JavaDoc + for the java.lang.Thread class for more details on what + this priority means.If an executor is associated + with this connector, this attribute is ignored as the connector will + execute tasks using the executor rather than an internal thread pool. Note + that if an executor is configured any value set for this attribute will be + recorded correctly but it will be reported (e.g. via JMX) as + -1 to make clear that it is not used.

+
tomcatAuthentication +

If set to true, the authentication will be done in Tomcat. + Otherwise, the authenticated principal will be propagated from the native + webserver and used for authorization in Tomcat. Note that this principal + will have no roles associated with it. + The default value is true. If + tomcatAuthorization is set to true this + attribute has no effect.

+
tomcatAuthorization +

If set to true, the authenticated principal will be + propagated from the native webserver and considered already authenticated + in Tomcat. If the web application has one or more security constraints, + authorization will then be performed by Tomcat and roles assigned to the + authenticated principal. If the appropriate Tomcat Realm for the request + does not recognise the provided user name, a Principal will be still be + created but it will have no roles. The default value is + false.

+
+ +
+ +

Java TCP socket attributes

+ +

The BIO, NIO and NIO2 implementation support the following Java TCP socket + attributes in addition to the common Connector and HTTP attributes listed + above.

+ +
+ Attribute + + Description +
socket.rxBufSize +

(int)The socket receive buffer (SO_RCVBUF) size in bytes. JVM default + used if not set.

+
socket.txBufSize +

(int)The socket send buffer (SO_SNDBUF) size in bytes. JVM default + used if not set.

+
socket.tcpNoDelay +

(bool)This is equivalent to standard attribute + tcpNoDelay.

+
socket.soKeepAlive +

(bool)Boolean value for the socket's keep alive setting + (SO_KEEPALIVE). JVM default used if not set.

+
socket.ooBInline +

(bool)Boolean value for the socket OOBINLINE setting. JVM default + used if not set.

+
socket.soReuseAddress +

(bool)Boolean value for the sockets reuse address option + (SO_REUSEADDR). JVM default used if not set.

+
socket.soLingerOn +

(bool)Boolean value for the sockets so linger option (SO_LINGER). + A value for the standard attribute connectionLinger + that is >=0 is equivalent to setting this to true. + A value for the standard attribute connectionLinger + that is <0 is equivalent to setting this to false. + Both this attribute and soLingerTime must be set else the + JVM defaults will be used for both.

+
socket.soLingerTime +

(int)Value in seconds for the sockets so linger option (SO_LINGER). + This is equivalent to standard attribute + connectionLinger. + Both this attribute and soLingerOn must be set else the + JVM defaults will be used for both.

+
socket.soTimeout +

This is equivalent to standard attribute + connectionTimeout.

+
socket.performanceConnectionTime +

(int)The first value for the performance settings. See + Socket Performance Options + All three performance attributes must be set else the JVM defaults will + be used for all three.

+
socket.performanceLatency +

(int)The second value for the performance settings. See + Socket Performance Options + All three performance attributes must be set else the JVM defaults will + be used for all three.

+
socket.performanceBandwidth +

(int)The third value for the performance settings. See + Socket Performance Options + All three performance attributes must be set else the JVM defaults will + be used for all three.

+
socket.unlockTimeout +

(int) The timeout for a socket unlock. When a connector is stopped, it will try to release the acceptor thread by opening a connector to itself. + The default value is 250 and the value is in milliseconds

+
+
+ +

NIO specific configuration

+ +

The following attributes are specific to the NIO connector.

+ +
+ Attribute + + Description +
socket.directBuffer +

(bool)Boolean value, whether to use direct ByteBuffers or java mapped + ByteBuffers. Default is false.
+ When you are using direct buffers, make sure you allocate the + appropriate amount of memory for the direct memory space. On Sun's JDK + that would be something like -XX:MaxDirectMemorySize=256m. +

+
socket.appReadBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a read ByteBuffer. This attribute controls the size of this buffer. By + default this read buffer is sized at 8192 bytes. For lower + concurrency, you can increase this to buffer more data. For an extreme + amount of keep alive connections, decrease this number or increase your + heap size.

+
socket.appWriteBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a write ByteBuffer. This attribute controls the size of this buffer. By + default this write buffer is sized at 8192 bytes. For low + concurrency you can increase this to buffer more response data. For an + extreme amount of keep alive connections, decrease this number or + increase your heap size.
+ The default value here is pretty low, you should up it if you are not + dealing with tens of thousands concurrent connections.

+
socket.bufferPool +

(int)The NIO connector uses a class called NioChannel that holds + elements linked to a socket. To reduce garbage collection, the NIO + connector caches these channel objects. This value specifies the size of + this cache. The default value is 500, and represents that + the cache will hold 500 NioChannel objects. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.bufferPoolSize +

(int)The NioChannel pool can also be size based, not used object + based. The size is calculated as follows:
+ NioChannel + buffer size = read buffer size + write buffer size
+ SecureNioChannel buffer size = application read buffer size + + application write buffer size + network read buffer size + + network write buffer size
+ The value is in bytes, the default value is 1024*1024*100 + (100MB).

+
socket.processorCache +

(int)Tomcat will cache SocketProcessor objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.keyCache +

(int)Tomcat will cache KeyAttachment objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.eventCache +

(int)Tomcat will cache PollerEvent objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
selectorPool.maxSelectors +

(int)The max selectors to be used in the pool, to reduce selector + contention. Use this option when the command line + org.apache.tomcat.util.net.NioSelectorShared value is set + to false. Default value is 200.

+
selectorPool.maxSpareSelectors +

(int)The max spare selectors to be used in the pool, to reduce + selector contention. When a selector is returned to the pool, the system + can decide to keep it or let it be GC'd. Use this option when the + command line org.apache.tomcat.util.net.NioSelectorShared + value is set to false. Default value is -1 (unlimited).

+
command-line-options +

The following command line options are available for the NIO + connector:
+ -Dorg.apache.tomcat.util.net.NioSelectorShared=true|false + - default is true. Set this value to false if you wish to + use a selector for each thread. When you set it to false, you can + control the size of the pool of selectors by using the + selectorPool.maxSelectors attribute.

+
+
+ +

NIO2 specific configuration

+ +

The following attributes are specific to the NIO2 connector.

+ +
+ Attribute + + Description +
useCaches +

(bool)Use this attribute to enable or disable object caching to + reduce the amount of GC objects produced. + The default value is false.

+
socket.directBuffer +

(bool)Boolean value, whether to use direct ByteBuffers or java mapped + ByteBuffers. Default is false.
+ When you are using direct buffers, make sure you allocate the + appropriate amount of memory for the direct memory space. On Sun's JDK + that would be something like -XX:MaxDirectMemorySize=256m. +

+
socket.appReadBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a read ByteBuffer. This attribute controls the size of this buffer. By + default this read buffer is sized at 8192 bytes. For lower + concurrency, you can increase this to buffer more data. For an extreme + amount of keep alive connections, decrease this number or increase your + heap size.

+
socket.appWriteBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a write ByteBuffer. This attribute controls the size of this buffer. By + default this write buffer is sized at 8192 bytes. For low + concurrency you can increase this to buffer more response data. For an + extreme amount of keep alive connections, decrease this number or + increase your heap size.
+ The default value here is pretty low, you should up it if you are not + dealing with tens of thousands concurrent connections.

+
socket.bufferPoolSize +

(int)The NIO2 connector uses a class called Nio2Channel that holds + elements linked to a socket. To reduce garbage collection, the NIO + connector caches these channel objects. This value specifies the size of + this cache. The default value is 500, and represents that + the cache will hold 500 Nio2Channel objects. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.processorCache +

(int)Tomcat will cache SocketProcessor objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.socketWrapperCache +

(int)Tomcat will cache SocketWrapper objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
+
+ +

APR/native specific configuration

+ +

The APR/native implementation supports the following attributes in + addition to the common Connector and AJP attributes listed above.

+ +
+ Attribute + + Description +
pollTime +

Duration of a poll call in microseconds. Lowering this value will + slightly decrease latency of connections being kept alive in some cases + , but will use more CPU as more poll calls are being made. The default + value is 2000 (2ms). +

+
pollerSize +

Amount of sockets that the poller responsible for polling kept alive + connections can hold at a given time. Extra connections will be closed + right away. The default value is 8192, corresponding to 8192 keep-alive + connections.

+
+ +
+ +

Nested Components

+ +

None at this time.

+ +

Special Features

+ +

Proxy Support

+ +

The proxyName and proxyPort attributes can + be used when Tomcat is run behind a proxy server. These attributes + modify the values returned to web applications that call the + request.getServerName() and request.getServerPort() + methods, which are often used to construct absolute URLs for redirects. + Without configuring these attributes, the values returned would reflect + the server name and port on which the connection from the proxy server + was received, rather than the server name and port to whom the client + directed the original request.

+ +

For more information, see the + Proxy Support HOW-TO.

+ +
+ +

Connector Comparison

+ +

Below is a small chart that shows how the connectors differ.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Java Blocking Connector
BIO
Java Nio Connector
NIO
Java Nio2 Connector
NIO2
APR/native Connector
APR
ClassnameAjpProtocolAjpNioProtocolAjpNio2ProtocolAjpAprProtocol
Tomcat Version3.x onwards7.x onwards8.x onwards5.5.x onwards
Support PollingNOYESYESYES
Polling SizeN/AmaxConnectionsmaxConnectionsmaxConnections
Read Request HeadersBlockingBlockingBlockingBlocking
Read Request BodyBlockingBlockingBlockingBlocking
Write Response Headers and BodyBlockingBlockingBlockingBlocking
Wait for next RequestBlockingNon BlockingNon BlockingNon Blocking
Max ConnectionsmaxConnectionsmaxConnectionsmaxConnectionsmaxConnections
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/automatic-deployment.html b/test.dockerapp/tomcat/webapps/docs/config/automatic-deployment.html new file mode 100644 index 0000000..cfbe282 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/automatic-deployment.html @@ -0,0 +1,540 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - Automatic Deployment - Use cases

Automatic Deployment - Use cases

Table of Contents

Introduction

+ +

This page defines the expected behaviour of the automatic deployer in many + typical use cases. This is a complex area of Tomcat's functionality. + While any difference between this document and Tomcat's behaviour is a + bug, the fix may be to change this document, Tomcat's behaviour or + both.

+ +

Key

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TermDescription
XMLAn XML configuration file located in the Host's + configBase. It must contain a single <Context> element + and may contain optional nested elements. It does not define an + explicit docBase attribute. It represents a single web + application. It is often referred to as a context.xml file.
XML+EWAn XML configuration file located in the Host's + configBase. It must contain a single <Context> element + and may contain optional nested elements. It includes an explicit + docBase attribute that points to an external WAR. It + represents a single web application. It is often referred to as a + context.xml file.
XML+EDAn XML configuration file located in the Host's + configBase. It must contain a single <Context> element + and may contain optional nested elements. It includes an explicit + docBase attribute that points to an external directory. It + represents a single web application. It is often referred to as a + context.xml file.
WARA WAR file located in the Host's appBase. The WAR does + not include an embedded context.xml file.
WAR+XMLA WAR file located in the Host's appBase. The WAR does + include an embedded context.xml file.
DIRA directory located in the Host's appBase. The directory + does not include an embedded context.xml file.
DIR+XMLA directory located in the Host's appBase. The directory + does include an embedded context.xml file.
redeployThe Context object that represents the web application is destroyed + and a new Context object is created. If present and permitted by the + configuration, this new Context object is created by parsing the + context.xml file. The web.xml file is parsed during the application + start process. Any sessions stored in the standard Manager in the + default configuration will not be persisted. Any requests to the web + application during the redeploy will be handled as if the web + application is not deployed.
reloadThe Context object that represents the web application is stopped and + then started. The web.xml file is parsed during the application start + process. Any sessions stored in the standard Manager in the default + configuration will not be persisted. Any requests to the web + application during the reload will be held until the reload completes + at which point they will continue using the reloaded web application. +
+ +

New files

+ +

This section describes Tomcat's behaviour when the automatic + deployment process discovers a new web application.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Starting artifact(s)Configuration SettingsResult
deployXMLcopyXMLunpackWARsXMLWARDIRNotes
XMLeithereithereitherYNN1, 2, 3
XML+EWeithereitherfalseYNN1
XML+EWeithereithertrueYNY1
XML+EDeithereithereitherYNN1, 2
WAR+XMLfalseeitherfalseNYN4
WAR+XMLfalseeithertrueNYY4
WAR+XMLtruefalsefalseNYN
WAR+XMLtruefalsetrueNYY
WAR+XMLtruetruefalseYYN
WAR+XMLtruetruetrueYYY
WAReithereitherfalseNYN
WAReithereithertrueNYY
DIR+XMLfalseeithereitherNNY4
DIR+XMLtruefalseeitherNNY
DIR+XMLtruetrueeitherYNY
DIRfalseeithereitherNNY
+ +

Deleted files

+ +

This section describes Tomcat's behaviour when the automatic + deployment process detects that a web application file has been deleted.

+ +

When a file is deleted or modified any redeploy resources that are listed + after the modified/deleted resource are themselves deleted (and possibly + re-created). The order of redeploy resources is:

+ +
    +
  1. WAR
  2. +
  3. DIR
  4. +
  5. XML
  6. +
  7. global resources
  8. +
+ +

There are some exceptions to the deletion rule above:

+ +
    +
  • global resources are never deleted
  • +
  • external resources are never deleted
  • +
  • if the WAR or DIR has been modified then the XML file is only deleted if + copyXML is true and deployXML is + true
  • +
+ +

In the following table:

+ +
    +
  • '-' means "unchanged from not present". i.e. the artifact wasn't present + before the change and isn't present after it either. '-' rather than 'N' + is used to focus attention on what changes.
  • +
  • 'R' means that the directory is re-created by expanding the WAR file. + This will only happen if unpackWARs is true.
  • +
  • 'XW' means that the if the WAR contains a META-INF/context.xml file it + will be extracted and placed in the Host's configBase. + This only happens if copyXML is true and + deployXML is true.
  • +
  • 'XD' means that the if the directory contains a META-INF/context.xml + file it will be copied to the Host's configBase. This only + happens if copyXML is true and deployXML + is true.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Artifacts presentArtifact removedArtifacts remaining
XMLWARDIRXMLWARDIRNotes
NNYDIR--N
NYNWAR-N-
NYYDIR-YR
NYYWAR-NN
YNNXMLN--
YNYDIRN-N5
YNYXMLXD-Y
YYNWARNN-5
YYNXMLXWY-
YYYDIRXWYR
YYYWARNNN
YYYXMLXWYY
YY (external)NWARYN-3
YY (external)NXMLNY (external)-6
YNY (external)DIRY-N3
YNY (external)XMLN-Y (external)6
YY (external)YDIRYY (external)R
YY (external)YWARYNN3
YY (external)YXMLNY (external)N6
+ +

Modified files

+ +

This section describes Tomcat's behaviour when the automatic + deployment process detects that a web application file has been modified.

+ +

In the following table:

+ +
    +
  • '-' means "unchanged from not present". i.e. the artifact wasn't present + before the change and isn't present after it either. '-' rather than 'N' + is used to focus attention on what changes.
  • +
  • 'M' means that the artifact has been modified.
  • +
  • 'R' means that the directory is deleted and re-created by expanding the + WAR file. This will only happen if unpackWARs is + true.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Artifacts presentArtifact modifiedArtifacts remaining
XMLWARDIRXMLWARDIRAction
NNYDIR--MNone
NYNWAR-M-Redeploy
NYYDIR-YMNone
NYYWAR-MRRedeploy
YNNXMLM--Redeploy
YNYDIRY-MNone
YNYXMLM-YRedeploy
YYNWARYM-Reload
YYNXMLMY-Redeploy
YYYDIRYYMNone
YYYWARYMRReload
YYYXMLMYYRedeploy
YY(external)NWARYM(external)-Reload
YY(external)NXMLMY(external)-Redeploy
YNY(external)DIRY-M(external)None
YNY(external)XMLM-Y(external)Redeploy
YY(external)YDIRYY(external)MNone
YY(external)YWARYM(external)RReload
YY(external)YXMLMY(external)YRedeploy
+ +

Added files

+ +

This is treated as if the added file has been modified with the following + additional actions:

+ +
    +
  • If a WAR is added, any DIR is removed and may be recreated depending on + unpackWARs.
  • +
  • If an XML file is added that refers to an external docBase any + WAR or DIR in the appBase will be removed. The DIR may be recreated if + the external resource is a WAR and unpackWARs is true.
  • +
  • If a DIR is added when a WAR already exists and unpackWARs is + false, the DIR will be ignored but a warning will be + logged when the DIR is first detected. If the WAR is removed, the DIR + will be left and may be deployed via automatic deployment.
  • +
  • If a WAR is added to the appBase when an external WAR already + exists, the WAR in the appBase will be ignored but a warning + will be logged when the WAR in the appBase is first detected. + If the external WAR is removed, the WAR in the appBase will be + left and may be deployed via automatic deployment.
  • +
  • If an XML file is added to the META-INF directory of an application + deployed from that DIR, the application will always be redeployed. The + result will be the same as for a new deployment.
  • +
+ +

Notes

+ +
    +
  1. deployXML and copyXML are ignored since an XML file + was discovered in the configBase.
  2. +
  3. unpackWARs is ignored since there is no WAR file.
  4. +
  5. The context will fail to start because there is no content in the + expected docBase.
  6. +
  7. The web application fails to deploy because it contains an embedded + META-INF/context.xml, deployXML is false and an + XML has not been provided in the configBase.
  8. +
  9. The XML file is only deleted if copyXML is true + and deployXML is true.
  10. +
  11. Although the external resource is still present, the web application is + fully undeployed as Tomcat has no knowledge of the external resource. +
  12. +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-channel.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-channel.html new file mode 100644 index 0000000..8777472 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-channel.html @@ -0,0 +1,130 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster Channel object

The Cluster Channel object

Table of Contents

Introduction

+ The cluster channel is the main component of a small framework we've nicknamed Apache Tribes.
+ The channel manages a set of sub components and together they create a group communication framework.
+ This framework is then used internally by the components that need to send messages between different Tomcat instances. +
+ A few examples of these components would be the SimpleTcpCluster that does the messaging for the DeltaManager, + or the BackupManager that uses a different replication strategy. The ReplicatedContext object does also + use the channel object to communicate context attribute changes. +

Nested Components

+

Channel/Membership:
+ The Membership component is responsible for auto discovering new nodes in the cluster + and also to provide for notifications for any nodes that have not responded with a heartbeat. + The default implementation uses multicast.
+ In the membership component you configure how your nodes, aka. members, are to be discovered and/or + divided up. + You can always find out more about Apache Tribes +

+

Channel/Sender:
+ The Sender component manages all outbound connections and data messages that are sent + over the network from one node to another. + This component allows messages to be sent in parallel. + The default implementation uses TCP client sockets, and socket tuning for outgoing messages are + configured here.
+ You can always find out more about Apache Tribes +

+

Channel/Sender/Transport:
+ The Transport component is the bottom IO layer for the sender component. + The default implementation uses non-blocking TCP client sockets.
+ You can always find out more about Apache Tribes +

+

Channel/Receiver:
+ The receiver component listens for messages from other nodes. + Here you will configure the cluster thread pool, as it will dispatch incoming + messages to a thread pool for faster processing. + The default implementation uses non-blocking TCP server sockets.
+ You can always find out more about Apache Tribes +

+

Channel/Interceptor:
+ The channel will send messages through an interceptor stack. Because of this, you have the ability to + customize the way messages are sent and received, and even how membership is handled.
+ You can always find out more about Apache Tribes +

+

Attributes

+ +

Common Attributes

+ +
+ Attribute + + Description +
className + The default value here is org.apache.catalina.tribes.group.GroupChannel and is + currently the only implementation available. +
+ + +
+ +

org.apache.catalina.tribes.group.GroupChannel Attributes

+ +
+ Attribute + + Description +
heartbeat + Flag whether the channel manages its own heartbeat. + If set to true, the channel start a local thread for the heart beat. + If set this flag to false, you must set SimpleTcpCluster#heartbeatBackgroundEnabled + to true. default value is true. +
heartbeatSleeptime + If heartbeat == true, specifies the interval of heartbeat thread in milliseconds. + The default is 5000 (5 seconds). +
optionCheck + If set to true, the GroupChannel will check the option flags that each + interceptor is using. Reports an error if two interceptor share the same + flag. The default is false. +
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-deployer.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-deployer.html new file mode 100644 index 0000000..5923a01 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-deployer.html @@ -0,0 +1,107 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster Deployer object

The Cluster Deployer object

Table of Contents

Introduction

+

The Farm War Deployer can deploy and undeploy web applications on the other + nodes in the cluster.

+

Note: FarmWarDeployer can be configured at host level + cluster only. +

+

org.apache.catalina.ha.deploy.FarmWarDeployer

+ +

Attributes

+ +
+ Attribute + + Description +
className + The cluster deployer class, currently only one is available, + org.apache.catalina.ha.deploy.FarmWarDeployer. +
deployDir + Deployment directory. This is the pathname of a directory where deploy + the web applications. You may specify an absolute pathname, or a + pathname that is relative to the $CATALINA_BASE directory. In the + current implementation, this attribute must be the same value as the + Host's appBase. +
tempDir + The temporaryDirectory to store binary data when downloading a war from + the cluster. You may specify an absolute pathname, or a pathname that is + relative to the $CATALINA_BASE directory. +
watchDir + This is the pathname of a directory where watch for changes(add/modify/remove) + of web applications. You may specify an absolute pathname, or a pathname + that is relative to the $CATALINA_BASE directory. + Note: if watchEnabled is false, this + attribute will have no effect. +
watchEnabled + Set to true if you want to watch for changes of web applications. + Only when this attribute set to true, you can trigger a deploy/undeploy + of web applications. The flag's value defaults to false. +
processDeployFrequency + Frequency of the Farm watchDir check. Cluster wide deployment will be + done once for the specified amount of backgroundProcess calls (ie, the + lower the amount, the most often the checks will occur). The minimum + value is 1, and the default value is 2. + Note: if watchEnabled is false, this + attribute will have no effect. +
maxValidTime + The maximum valid time(in seconds) of FileMessageFactory. + FileMessageFactory will be removed immediately after receiving the + complete WAR file but when failing to receive a FileMessage which was + sent dividing, FileMessageFactory will leak without being removed. + FileMessageFactory that is leaking will be automatically removed after + maxValidTime. If a negative value specified, FileMessageFactory will + never be removed. If the attribute is not provided, a default of 300 + seconds (5 minutes) is used. +
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-interceptor.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-interceptor.html new file mode 100644 index 0000000..513843b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-interceptor.html @@ -0,0 +1,291 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Channel Interceptor object

The Channel Interceptor object

Table of Contents

Introduction

+

+ Apache Tribes supports an interceptor architecture to intercept both messages and membership notifications. + This architecture allows decoupling of logic and opens the way for some very kewl feature add ons. +

+

Available Interceptors

+
    +
  • org.apache.catalina.tribes.group.interceptors.TcpFailureDetector
  • +
  • org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.NonBlockingCoordinator
  • +
  • org.apache.catalina.tribes.group.interceptors.OrderInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.SimpleCoordinator
  • +
  • org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.TwoPhaseCommitInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.DomainFilterInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.FragmentationInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.GzipInterceptor
  • +
  • org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor
  • +
+

Static Membership

+

+ In addition to dynamic discovery, Apache Tribes also supports static membership, with membership verification. + To achieve this add the org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor + after the org.apache.catalina.tribes.group.interceptors.TcpFailureDetector interceptor. + Inside the StaticMembershipInterceptor you can add the static members you wish to have. + The TcpFailureDetector will do a health check on the static members,and also monitor them for crashes + so they will have the same level of notification mechanism as the members that are automatically discovered.

+
     <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
+       <LocalMember className="org.apache.catalina.tribes.membership.StaticMember"
+                  domain="staging-cluster"
+                  uniqueId="{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1}"/>
+       <Member className="org.apache.catalina.tribes.membership.StaticMember"
+                  port="5678"
+                  securePort="-1"
+                  host="tomcat01.mydomain.com"
+                  domain="staging-cluster"
+                  uniqueId="{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}"/>
+     </Interceptor>
+

Attributes

+ +

Common Attributes

+
+ Attribute + + Description +
className + Required, as there is no default +
optionFlag + If you want the interceptor to trigger on certain message depending on the message's option flag, + you can setup the interceptors flag here. + The default value is 0, meaning this interceptor will trigger on all messages. +
+
+ +

org.apache.catalina.tribes.group.interceptors.DomainFilterInterceptor Attributes

+
+ Attribute + + Description +
domain + The logical cluster domain that this Interceptor accepts. + Two different type of values are possible:
+ 1. Regular string values like "staging-domain" or "tomcat-cluster" will be converted into bytes + using ISO-8859-1 encoding.
+ 2. byte array in string form, for example {216,123,12,3}
+
logInterval + This value indicates the interval for logging for messages from different domains. + The default is 100, which means that to log per 100 messages. +
+
+

org.apache.catalina.tribes.group.interceptors.FragmentationInterceptor Attributes

+
+ Attribute + + Description +
expire + How long do we keep the fragments in memory and wait for the rest to arrive. + The default is 60000 ms. +
maxSize + The maximum message size in bytes. If the message size exceeds this value, this interceptor fragments the message and sends them. + If it is less than this value, this interceptor does not fragment the message and sent in as one message. The default is 1024*100. +
+
+

org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor Attributes

+
+ Attribute + + Description +
className + Required, This dispatcher uses JDK 1.5 java.util.concurrent package +
optionFlag + The default and hard coded value is 8 (org.apache.catalina.tribes.Channel.SEND_OPTIONS_ASYNCHRONOUS). + The dispatcher will trigger on this value only, as it is predefined by Tribes. + The other attributes are inherited from its base class org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor. +
maxThreads + The maximum number of threads in this pool, default is 10. +
maxSpareThreads + The number of threads to keep in the pool, default is 2. +
keepAliveTime + Maximum number of milliseconds of until Idle thread terminates. Default value is 5000(5 seconds). +
+
+

org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor Attributes

+
+ Attribute + + Description +
className + Required, Same implementation as MessageDispatch15Interceptor, but with JDK 1.4 compliance. +
optionFlag + The default and hard coded value is 8 (org.apache.catalina.tribes.Channel.SEND_OPTIONS_ASYNCHRONOUS). + The dispatcher will trigger on this value only, as it is predefined by Tribes. +
alwaysSend + What behavior should be executed when the dispatch queue is full. If true (default), then the message is + is sent synchronously, if false an error is thrown. +
maxQueueSize + Size in bytes of the dispatch queue, the default value is 1024*1024*64 (64MB) sets the maximum queue size for the dispatch queue + if the queue fills up, one can trigger the behavior, if alwaysSend is set to true, the message will be sent synchronously + if the flag is false, an error is thrown +
+
+

org.apache.catalina.tribes.group.interceptors.TcpFailureDetector Attributes

+
+ Attribute + + Description +
connectTimeout + Specifies the timeout, in milliseconds, to use when attempting a TCP connection + to the suspect node. Default is 1000. +
performSendTest + If true is set, send a test message to the suspect node. Default is true. +
performReadTest + If true is set, read the response of the test message that sent. Default is false. + Note: if performSendTest is false, this attribute will have no effect. +
readTestTimeout + Specifies the timeout, in milliseconds, to use when performing a read test + to the suspicious node. Default is 5000. +
removeSuspectsTimeout + The maximum time(in seconds) for remove from removeSuspects. Member of + removeSuspects will be automatically removed after removeSuspectsTimeout. + If a negative value specified, the removeSuspects members never be + removed until disappeared really. If the attribute is not provided, + a default of 300 seconds (5 minutes) is used. +
+
+

org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor Attributes

+
+ Attribute + + Description +
interval + If useThread == true, defines the interval of sending a ping message. + default is 1000 ms. +
useThread + Flag of whether to start a thread for sending a ping message. + If set to true, this interceptor will start a local thread for sending a ping message. + if set to false, channel heartbeat will send a ping message. + default is false. +
+
+

org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor Attributes

+
+ Attribute + + Description +
interval + Defines the interval in number of messages when we are to report the throughput statistics. + The report is logged to the org.apache.juli.logging.LogFactory.getLog(ThroughputInterceptor.class) + logger under the INFO level. + Default value is to report every 10000 messages. +
+
+

Nested Components

+ +

StaticMember Attributes

+

LocalMember:
+ Static member that is the local member of the static cluster group. +

+
+ Attribute + + Description +
className + Only one implementation available:org.apache.catalina.tribes.membership.StaticMember +
port + There is no need to set. + The value of this attribute inherits from the cluster receiver setting. +
securePort + There is no need to set. + The value of this attribute inherits from the cluster receiver setting. +
host + There is no need to set. + The value of this attribute inherits from the cluster receiver setting. +
domain + The logical cluster domain for that this static member listens for cluster messages. + Two different type of values are possible:
+ 1. Regular string values like "staging-domain" or "tomcat-cluster" will be converted into bytes + using ISO-8859-1 encoding. + 2. byte array in string form, for example {216,123,12,3}
+
uniqueId + A universally uniqueId for this static member. + The values must be 16 bytes in the following form:
+ 1. byte array in string form, for example {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
+
+ +

Member:
+ Static member that add to the static cluster group. +

+
+ Attribute + + Description +
className + Only one implementation available:org.apache.catalina.tribes.membership.StaticMember +
port + The port that this static member listens to for cluster messages +
securePort + The secure port this static member listens to for encrypted cluster messages + default value is -1, this value means the member is not listening on a secure port +
host + The host (or network interface) that this static member listens for cluster messages. + Three different type of values are possible:
+ 1. IP address in the form of "216.123.1.23"
+ 2. Hostnames like "tomcat01.mydomain.com" or "tomcat01" as long as they resolve correctly
+ 3. byte array in string form, for example {216,123,12,3}
+
domain + The logical cluster domain for that this static member listens for cluster messages. + Two different type of values are possible:
+ 1. Regular string values like "staging-domain" or "tomcat-cluster" will be converted into bytes + using ISO-8859-1 encoding.
+ 2. byte array in string form, for example {216,123,12,3}
+
uniqueId + A universally uniqueId for this static member. + The values must be 16 bytes in the following form:
+ 1. byte array in string form, for example {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
+
+
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-listener.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-listener.html new file mode 100644 index 0000000..8ed1f25 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-listener.html @@ -0,0 +1,77 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The ClusterListener object

The ClusterListener object

Table of Contents

Introduction

+

+ The org.apache.catalina.ha.ClusterListener base class + lets you listen in on messages that are received by the Cluster component. +

+ +

org.apache.catalina.ha.session.ClusterSessionListener

+

+ When using the DeltaManager, the messages are received by the Cluster object and are propagated to the + to the manager through this listener. +

+

Attributes

+ +

Common Attributes

+ +
+ Attribute + + Description +
className + +
+ + +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-manager.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-manager.html new file mode 100644 index 0000000..d5b1580 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-manager.html @@ -0,0 +1,301 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The ClusterManager object

The ClusterManager object

Table of Contents

Introduction

+

A cluster manager is an extension to Tomcat's session manager interface, + org.apache.catalina.Manager. + A cluster manager must implement the + org.apache.catalina.ha.ClusterManager and is solely responsible + for how the session is replicated.
+ There are currently two different managers, the + org.apache.catalina.ha.session.DeltaManager replicates deltas of + session data to all members in the cluster. This implementation is proven and + works very well, but has a limitation as it requires the cluster members to be + homogeneous, all nodes must deploy the same applications and be exact + replicas. The org.apache.catalina.ha.session.BackupManager also + replicates deltas but only to one backup node. The location of the backup node + is known to all nodes in the cluster. It also supports heterogeneous + deployments, so the manager knows at what locations the web application is + deployed.

+

The <Manager>

+

The <Manager> element defined inside the + <Cluster> element is the template defined for all web + applications that are marked <distributable/> in their + web.xml file. However, you can still override the manager + implementation on a per web application basis, by putting the + <Manager> inside the <Context> element + either in the context.xml file or the + server.xml file.

+

Attributes

+

Common Attributes

+
+ Attribute + + Description +
className +
name + The name of this cluster manager, the name is used to identify a + session manager on a node. The name might get modified by the + Cluster element to make it unique in the container. +
notifyListenersOnReplication + Set to true if you wish to have session listeners notified + when session attributes are being replicated or removed across Tomcat + nodes in the cluster. +
maxInactiveInterval +

Deprecated: This should be configured via the + Context.

+

The initial maximum time interval, in seconds, + between client requests before a session is invalidated. A negative value + will result in sessions never timing out. If the attribute is not provided, + a default of 1800 seconds (30 minutes) is used.

+ +

This attribute provides the initial value whenever a + new session is created, but the interval may be dynamically + varied by a servlet via the + setMaxInactiveInterval method of the HttpSession object.

+
sessionIdLength +

The length of session ids created by this Manager, measured in bytes, + excluding subsequent conversion to a hexadecimal string and + excluding any JVM route information used for load balancing. + This attribute is deprecated. Set the length on a nested + SessionIdGenerator element instead.

+
processExpiresFrequency +

Frequency of the session expiration, and related manager operations. + Manager operations will be done once for the specified amount of + backgroundProcess calls (i.e., the lower the amount, the more often the + checks will occur). The minimum value is 1, and the default value is 6. +

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate session IDs. + If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the Manager + will use the platform default provider and the default algorithm. If not + specified, the platform default provider will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the Manager + will use the platform default provider and the default algorithm. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
recordAllActions +

Flag whether send all actions for session across Tomcat cluster + nodes. If set to false, if already done something to the same attribute, + make sure don't send multiple actions across Tomcat cluster nodes. + In that case, sends only the actions that have been added at last. + Default is false.

+
+
+

org.apache.catalina.ha.session.DeltaManager Attributes

+
+ Attribute + + Description +
expireSessionsOnShutdown + When a web application is being shutdown, Tomcat issues an expire call + to each session to notify all the listeners. If you wish for all + sessions to expire on all nodes when a shutdown occurs on one node, set + this value to true. + Default value is false. +
maxActiveSessions + The maximum number of active sessions that will be created by this + Manager, or -1 (the default) for no limit. For this manager, all + sessions are counted as active sessions irrespective if whether or not + the current node is the primary node for the session. +
notifySessionListenersOnReplication + Set to true if you wish to have session listeners notified + when sessions are created and expired across Tomcat nodes in the + cluster. +
notifyContainerListenersOnReplication + Set to true if you wish to have container listeners notified + across Tomcat nodes in the cluster. +
stateTransferTimeout + The time in seconds to wait for a session state transfer to complete + from another node when a node is starting up. + Default value is 60 seconds. +
sendAllSessions + Flag whether send sessions as split blocks. + If set to true, send all sessions as one big block. + If set to false, send sessions as split blocks. + Default value is true. +
sendAllSessionsSize + The number of sessions in a session block message. This value is + effective only when sendAllSessions is false. + Default is 1000. +
sendAllSessionsWaitTime + Wait time between sending of session block messages. This value is + effective only when sendAllSessions is false. + Default is 2000 milliseconds. +
sessionAttributeNameFilter +

A regular expression used to filter which session attributes will be + replicated. An attribute will only be replicated if its name matches + this pattern. If the pattern is zero length or null, all + attributes are eligible for replication. The pattern is anchored so the + session attribute name must fully match the pattern. As an example, the + value (userName|sessionHistory) will only replicate the + two session attributes named userName and + sessionHistory. If not specified, the default value of + null will be used.

+
sessionAttributeValueClassNameFilter +

A regular expression used to filter which session attributes will be + replicated. An attribute will only be replicated if the implementation + class name of the value matches this pattern. If the pattern is zero + length or null, all attributes are eligible for + replication. The pattern is anchored so the fully qualified class name + must fully match the pattern. If not specified, the default value of + null will be used unless a SecurityManager is + enabled in which case the default will be + java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

+
stateTimestampDrop + When this node sends a GET_ALL_SESSIONS message to other + node, all session messages that are received as a response are queued. + If this attribute is set to true, the received session + messages (except any GET_ALL_SESSIONS sent by other nodes) + are filtered by their timestamp. A message is dropped if it is not a + GET_ALL_SESSIONS message and its timestamp is earlier than + the timestamp of our GET_ALL_SESSIONS message. + If set to false, all queued session messages are handled. + Default is true. +
warnOnSessionAttributeFilterFailure +

If sessionAttributeNameFilter or + sessionAttributeValueClassNameFilter blocks an + attribute, should this be logged at WARN level? If + WARN level logging is disabled then it will be logged at + DEBUG. The default value of this attribute is + false unless a SecurityManager is enabled in + which case the default will be true.

+
+
+

org.apache.catalina.ha.session.BackupManager Attributes

+
+ Attribute + + Description +
mapSendOptions + The backup manager uses a replicated map, this map is sending and + receiving messages. You can setup the flag for how this map is sending + messages, the default value is 6(synchronous).
+ Note that if you use asynchronous messaging it is possible for update + messages for a session to be processed by the receiving node in a + different order to the order in which they were sent. +
maxActiveSessions + The maximum number of active sessions that will be created by this + Manager, or -1 (the default) for no limit. For this manager, only + sessions where the current node is the primary node for the session are + considered active sessions. +
rpcTimeout + Timeout for RPC message used for broadcast and transfer state from + another map. + Default value is 15000 milliseconds. +
sessionAttributeNameFilter +

A regular expression used to filter which session attributes will be + replicated. An attribute will only be replicated if its name matches + this pattern. If the pattern is zero length or null, all + attributes are eligible for replication. The pattern is anchored so the + session attribute name must fully match the pattern. As an example, the + value (userName|sessionHistory) will only replicate the + two session attributes named userName and + sessionHistory. If not specified, the default value of + null will be used.

+
sessionAttributeValueClassNameFilter +

A regular expression used to filter which session attributes will be + replicated. An attribute will only be replicated if the implementation + class name of the value matches this pattern. If the pattern is zero + length or null, all attributes are eligible for + replication. The pattern is anchored so the fully qualified class name + must fully match the pattern. If not specified, the default value of + null will be used unless a SecurityManager is + enabled in which case the default will be + java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

+
terminateOnStartFailure + Set to true if you wish to terminate replication map when replication + map fails to start. If replication map is terminated, associated context + will fail to start. If you set this attribute to false, replication map + does not end. It will try to join the map membership in the heartbeat. + Default value is false . +
warnOnSessionAttributeFilterFailure +

If sessionAttributeNameFilter or + sessionAttributeValueClassNameFilter blocks an + attribute, should this be logged at WARN level? If + WARN level logging is disabled then it will be logged at + DEBUG. The default value of this attribute is + false unless a SecurityManager is enabled in + which case the default will be true.

+
accessTimeout + The timeout for a ping message. If a remote map does not respond within + this timeout period, its regarded as disappeared. + Default value is 5000 milliseconds. +
+
+

Nested Components

+

All Manager Implementations

+

All Manager implementations allow nesting of a + <SessionIdGenerator> element. It defines + the behavior of session id generation. All implementations + of the SessionIdGenerator allow the + following attributes: +

+
+ Attribute + + Description +
sessionIdLength +

The length of the session ID may be changed with the + sessionIdLength attribute. +

+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-membership.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-membership.html new file mode 100644 index 0000000..de0b236 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-membership.html @@ -0,0 +1,163 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster Membership object

The Cluster Membership object

Table of Contents

Introduction

+

+ The membership component in the Apache Tribes Channel is responsible + for dynamic discovery of other members(nodes) in the cluster. +

+

Default Implementation

+

+ The default implementation of the cluster group notification is built on top of multicast heartbeats + sent using UDP packets to a multicast IP address. + Cluster members are grouped together by using the same multicast address/port combination. + Each member sends out a heartbeat with a given interval (frequency), and this + heartbeat is used for dynamic discovery. + In a similar fashion, if a heartbeat has not been received in a timeframe specified by dropTime + ms. a member is considered suspect and the channel and any membership listener will be notified. +

+

Attributes

+ +

Multicast Attributes

+ +
+ Attribute + + Description +
className +

+ The default value is org.apache.catalina.tribes.membership.McastService + and is currently the only implementation. + This implementation uses multicast heartbeats for member discovery. +

+
address +

+ The multicast address that the membership will broadcast its presence and listen + for other heartbeats on. The default value is 228.0.0.4 + Make sure your network is enabled for multicast traffic.
+ The multicast address, in conjunction with the port is what + creates a cluster group. To divide up your farm into several different group, or to + split up QA from production, change the port or the address +
Previously known as mcastAddr. +

+
port +

+ The multicast port, the default value is 45564
+ The multicast port, in conjunction with the address is what + creates a cluster group. To divide up your farm into several different group, or to + split up QA from production, change the port or the address +

+
frequency +

+ The frequency in milliseconds in which heartbeats are sent out. The default value is 500 ms.
+ In most cases the default value is sufficient. Changing this value, simply changes the interval in between heartbeats. +

+
dropTime +

+ The membership component will time out members and notify the Channel if a member fails to send a heartbeat within + a give time. The default value is 3000 ms. This means, that if a heartbeat is not received from a + member in that timeframe, the membership component will notify the cluster of this.
+ On a high latency network you may wish to increase this value, to protect against false positives.
+ Apache Tribes also provides a TcpFailureDetector that will + verify a timeout using a TCP connection when a heartbeat timeout has occurred. This protects against false positives. +

+
bind +

+ Use this attribute if you wish to bind your multicast traffic to a specific network interface. + By default, or when this attribute is unset, it tries to bind to 0.0.0.0 and sometimes on multihomed hosts + this becomes a problem. +

+
ttl +

+ The time-to-live setting for the multicast heartbeats. + This setting should be a value between 0 and 255. The default value is VM implementation specific. +

+
domain +

+ Apache Tribes has the ability to logically group members into domains, by using this domain attribute. + The org.apache.catalina.tribes.Member.getDomain() method returns the value specified here. +

+
soTimeout +

+ The sending and receiving of heartbeats is done on a single thread, hence to avoid blocking this thread forever, + you can control the SO_TIMEOUT value on this socket.
+ If a value smaller or equal to 0 is presented, the code will default this value to frequency +

+
recoveryEnabled +

+ In case of a network failure, Java multicast socket don't transparently fail over, instead the socket will continuously + throw IOException upon each receive request. When recoveryEnabled is set to true, this will close the multicast socket + and open a new socket with the same properties as defined above.
+ The default is true.
+

+
recoveryCounter +

+ When recoveryEnabled==true this value indicates how many + times an error has to occur before recovery is attempted. The default is + 10.
+

+
recoverySleepTime +

+ When recoveryEnabled==true this value indicates how long time (in milliseconds) + the system will sleep in between recovery attempts, until it recovers successfully. + The default is 5000 (5 seconds).
+

+
localLoopbackDisabled +

+ Membership uses multicast, it will call java.net.MulticastSocket.setLoopbackMode(localLoopbackDisabled). + When localLoopbackDisabled==true multicast messages will not reach other nodes on the same local machine. + The default is false.
+

+
+ + +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-receiver.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-receiver.html new file mode 100644 index 0000000..dd2c880 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-receiver.html @@ -0,0 +1,159 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster Receiver object

The Cluster Receiver object

Table of Contents

Introduction

+

+ The receiver component is responsible for receiving cluster messages. + As you might notice through the configuration, is that the receiving of messages + and sending of messages are two different components, this is different from many other + frameworks, but there is a good reason for it, to decouple the logic for how messages are sent from + how messages are received.
+ The receiver is very much like the Tomcat Connector, its the base of the thread pool + for incoming cluster messages. The receiver is straight forward, but all the socket settings + for incoming traffic are managed here. +

+

Blocking vs Non-Blocking Receiver

+

+ The receiver supports both a non blocking, org.apache.catalina.tribes.transport.nio.NioReceiver, and a + blocking, org.apache.catalina.tribes.transport.bio.BioReceiver. It is preferred to use the non blocking receiver + to be able to grow your cluster without running into thread starvation.
+ Using the non blocking receiver allows you to with a very limited thread count to serve a large number of messages. + Usually the rule is to use 1 thread per node in the cluster for small clusters, and then depending on your message frequency + and your hardware, you'll find an optimal number of threads peak out at a certain number. +

+

Attributes

+

Common Attributes

+
+ Attribute + + Description +
className + The implementation of the receiver component. Two implementations available, + org.apache.catalina.tribes.transport.nio.NioReceiver and + org.apache.catalina.tribes.transport.bio.BioReceiver.
+ The org.apache.catalina.tribes.transport.nio.NioReceiver is the + preferred implementation +
address + The address (network interface) to listen for incoming traffic. + Same as the bind address. The default value is auto and translates to + java.net.InetAddress.getLocalHost().getHostAddress(). +
direct + Possible values are true or false. + Set to true if you want the receiver to use direct bytebuffers when reading data + from the sockets. +
port + The listen port for incoming data. The default value is 4000. + To avoid port conflicts the receiver will automatically bind to a free port within the range of + port <= bindPort < port+autoBind + So for example, if port is 4000, and autoBind is set to 10, then the receiver will open up + a server socket on the first available port in the range 4000-4009. +
autoBind + Default value is 100. + Use this value if you wish to automatically avoid port conflicts the cluster receiver will try to open a + server socket on the port attribute port, and then work up autoBind number of times. +
securePort + The secure listen port. This port is SSL enabled. If this attribute is omitted no SSL port is opened up. + There default value is unset, meaning there is no SSL socket available. +
udpPort + The UDP listen port. If this attribute is omitted no UDP port is opened up. + There default value is unset, meaning there is no UDP listener available. +
selectorTimeout + The value in milliseconds for the polling timeout in the NioReceiver. On older versions of the JDK + there have been bugs, that should all now be cleared out where the selector never woke up. + The default value is a very high 5000 milliseconds. +
maxThreads + The maximum number of threads in the receiver thread pool. The default value is 6 + Adjust this value relative to the number of nodes in the cluster, the number of messages being exchanged and + the hardware you are running on. A higher value doesn't mean more efficiency, tune this value according to your + own test results. +
minThreads + Minimum number of threads to be created when the receiver is started up. Default value is 6 +
maxIdleTime + Maximum number of milliseconds of until Idle thread terminates. Default value is 60000 milliseconds. +
ooBInline + Boolean value for the socket OOBINLINE option. Possible values are true or false. +
rxBufSize + The receiver buffer size on the receiving sockets. Value is in bytes, the default value is 43800 bytes. +
txBufSize + The sending buffer size on the receiving sockets. Value is in bytes, the default value is 25188 bytes. +
udpRxBufSize + The receive buffer size on the datagram socket. + Default value is 25188 bytes. +
udpTxBufSize + The send buffer size on the datagram socket. + Default value is 43800 bytes. +
soKeepAlive + Boolean value for the socket SO_KEEPALIVE option. Possible values are true or false. +
soLingerOn + Boolean value to determine whether to use the SO_LINGER socket option. + Possible values are true or false. Default value is true. +
soLingerTime + Sets the SO_LINGER socket option time value. The value is in seconds. + The default value is 3 seconds. +
soReuseAddress + Boolean value for the socket SO_REUSEADDR option. Possible values are true or false. +
tcpNoDelay + Boolean value for the socket TCP_NODELAY option. Possible values are true or false. + The default value is true +
timeout + Sets the SO_TIMEOUT option on the socket. The value is in milliseconds and the default value is 3000 + milliseconds. +
useBufferPool + Boolean value whether to use a shared buffer pool of cached org.apache.catalina.tribes.io.XByteBuffer + objects. If set to true, the XByteBuffer that is used to pass a message up the channel, will be recycled at the end + of the requests. This means that interceptors in the channel must not maintain a reference to the object + after the org.apache.catalina.tribes.ChannelInterceptor#messageReceived method has exited. +
+
+

NioReceiver

+
+

BioReceiver

+
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-sender.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-sender.html new file mode 100644 index 0000000..4dad825 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-sender.html @@ -0,0 +1,175 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster Sender object

The Cluster Sender object

Table of Contents

Introduction

+

+ The channel sender component is responsible for delivering outgoing cluster messages over the network. + In the default implementation, org.apache.catalina.tribes.transport.ReplicationTransmitter, + the sender is a fairly empty shell with not much logic around a fairly complex <Transport> + component the implements the actual delivery mechanism. +

+

Concurrent Parallel Delivery

+

+ In the default transport implementation, org.apache.catalina.tribes.transport.nio.PooledParallelSender, + Apache Tribes implements what we like to call "Concurrent Parallel Delivery". + This means that we can send a message to more than one destination at the same time(parallel), and + deliver two messages to the same destination at the same time(concurrent). Combine these two and we have + "Concurrent Parallel Delivery". +

+

+ When is this useful? The simplest example we can think of is when part of your code is sending a 10MB message, + like a war file being deployed, and you need to push through a small 10KB message, say a session being replicated, + you don't have to wait for the 10MB message to finish, as a separate thread will push in the small message + transmission at the same time. Currently there is no interrupt, pause or priority mechanism available, but check back soon. +

+

Nested Elements

+

+ The nested element <Transport> is not required, but encouraged, as this is where + you would set all the socket options for the outgoing messages. Please see its attributes below. + There are two implementations, in a similar manner to the receiver, one is non-blocking + based and the other is built using blocking IO.
+ org.apache.catalina.tribes.transport.bio.PooledMultiSender is the blocking implementation and + org.apache.catalina.tribes.transport.nio.PooledParallelSender. + Parallel delivery is not available for the blocking implementation due to the fact that it is blocking a thread on sending data. +

+

Attributes

+

Common Sender Attributes

+
+ Attribute + + Description +
className + Required, only available implementation is org.apache.catalina.tribes.transport.ReplicationTransmitter +
+
+

Common Transport Attributes

+
+ Attribute + + Description +
className + Required, an implementation of the org.apache.catalina.tribes.transport.MultiPointSender.
+ Non-blocking implementation is org.apache.catalina.tribes.transport.nio.PooledParallelSender
+ Blocking implementation is org.apache.catalina.tribes.transport.bio.PooledMultiSender +
rxBufSize + The receive buffer size on the socket. + Default value is 25188 bytes. +
txBufSize + The send buffer size on the socket. + Default value is 43800 bytes. +
udpRxBufSize + The receive buffer size on the datagram socket. + Default value is 25188 bytes. +
udpTxBufSize + The send buffer size on the datagram socket. + Default value is 43800 bytes. +
directBuffer + Possible values are true or false. + Set to true if you want the receiver to use direct bytebuffers when writing data + to the sockets. Default value is false +
keepAliveCount + The number of requests that can go through the socket before the socket is closed, and reopened + for the next request. The default value is -1, which is unlimited. +
keepAliveTime + The number of milliseconds a connection is kept open after its been opened. + The default value is -1, which is unlimited. +
timeout + Sets the SO_TIMEOUT option on the socket. The value is in milliseconds and the default value is 3000 + milliseconds.(3 seconds) This timeout starts when a message send attempt is starting, until the transfer has been completed. + For the NIO sockets, this will mean, that the caller can guarantee that we will not attempt sending the message + longer than this timeout value. For the blocking IO implementation, this translated directly to the soTimeout.
+ A timeout will not spawn a retry attempt, in order to guarantee the return of the application thread. +
maxRetryAttempts + How many times do we retry a failed message, that received a IOException at the socket level. + The default value is 1, meaning we will retry a message that has failed once. + In other words, we will attempt a message send no more than twice. One is the original send, and one is the + maxRetryAttempts. +
ooBInline + Boolean value for the socket OOBINLINE option. Possible values are true or false. +
soKeepAlive + Boolean value for the socket SO_KEEPALIVE option. Possible values are true or false. +
soLingerOn + Boolean value to determine whether to use the SO_LINGER socket option. + Possible values are true or false. Default value is true. +
soLingerTime + Sets the SO_LINGER socket option time value. The value is in seconds. + The default value is 3 seconds. +
soReuseAddress + Boolean value for the socket SO_REUSEADDR option. Possible values are true or false. +
soTrafficClass + Sets the traffic class level for the socket, the value is between 0 and 255. + Default value is int soTrafficClass = 0x04 | 0x08 | 0x010; + Different values are defined in + java.net.Socket#setTrafficClass(int). +
tcpNoDelay + Boolean value for the socket TCP_NODELAY option. Possible values are true or false. + The default value is true +
throwOnFailedAck + Boolean value, default value is true. + If set to true, the sender will throw a org.apache.catalina.tribes.RemoteProcessException + when we receive a negative ack from the remote member. + Set to false, and Tribes will treat a positive ack the same way as a negative ack, that the message was received. +
+
+

Common PooledSender Attributes

+
+ Attribute + + Description +
poolSize + The maximum number of concurrent connections from A to B. + The value is based on a per-destination count. + The default value is 25 +
maxWait + The maximum number of milliseconds that the senderPool will wait when + there are no available senders. The default value is 3000 + milliseconds.(3 seconds). +
+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster-valve.html b/test.dockerapp/tomcat/webapps/docs/config/cluster-valve.html new file mode 100644 index 0000000..75a4298 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster-valve.html @@ -0,0 +1,168 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster Valve object

The Cluster Valve object

Table of Contents

Introduction

+

+ A cluster valve is no different from any other Tomcat Valve. + The cluster valves are interceptors in the invocation chain for HTTP requests, and the clustering implementation + uses these valves to make intelligent decision around data and when data should be replicated. +

+

+ A cluster valve must implement the org.apache.catalina.ha.ClusterValve interface. + This is a simple interface that extends the org.apache.catalina.Valve interface. +

+

org.apache.catalina.ha.tcp.ReplicationValve

+ The ReplicationValve will notify the cluster at the end of a HTTP request + so that the cluster can make a decision whether there is data to be replicated or not. +

Attributes

+
+ Attribute + + Description +
className + Set value to org.apache.catalina.ha.tcp.ReplicationValve +
filter + For known file extensions or urls, you can use this Valve to notify the + cluster that the session has not been modified during this request and + the cluster doesn't have to probe the session managers for changes. If + the request matches this filter pattern, the cluster assumes there has + been no session change. An example filter would look like + filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt" + . The filter is a regular expression using + java.util.regex. +
primaryIndicator + Boolean value, so to true, and the replication valve will insert a request attribute with the name + defined by the primaryIndicatorName attribute. + The value inserted into the request attribute is either Boolean.TRUE or + Boolean.FALSE +
primaryIndicatorName + Default value is org.apache.catalina.ha.tcp.isPrimarySession + The value defined here is the name of the request attribute that contains the boolean value + if the session is primary on this server or not. +
statistics + Boolean value. Set to true if you want the valve to collect request statistics. + Default value is false +
+
+

org.apache.catalina.ha.session.JvmRouteBinderValve

+ In case of a mod_jk failover, the JvmRouteBinderValve will replace the + jvmWorker attribute in the session Id, to make future requests stick to this + node. If you want fallback capability, don't enable this valve, but if you want your failover to stick, + and for mod_jk not to have to keep probing the node that went down, you use this valve. +

Attributes

+
+ Attribute + + Description +
className + org.apache.catalina.ha.session.JvmRouteBinderValve +
enabled + Default value is true + Runtime attribute to turn on and off turn over of the session's jvmRoute value. +
sessionIdAttribute + Old sessionid before failover is registered in request attributes with this attribute. + Default attribute name is org.apache.catalina.ha.session.JvmRouteOrignalSessionID. +
+
+

org.apache.catalina.ha.authenticator.ClusterSingleSignOn

+ The ClusterSingleSignOn supports feature of single sign on in cluster. + By using ClusterSingleSignOn, the security identity authenticated + by one web application is recognized by other web applications on the same virtual host, + and it is propagated to other nodes in the cluster. + +

See the Single Sign On special + feature on the Host element for more information.

+ +

Note: ClusterSingleSignOn can be configured at host level cluster only. +

+ +

Attributes

+
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.ha.authenticator.ClusterSingleSignOn.

+
cookieDomain +

Sets the host domain to be used for sso cookies.

+
mapSendOptions +

The Valve uses a replicated map. You can setup the flag for how this + map sends messages. The default value is 6 (synchronous). + Note that if you use asynchronous messaging it is possible for update + messages to be processed by the receiving node in a different order to + the order in which they were sent.

+
requireReauthentication +

Default false. Flag to determine whether each request needs to be + reauthenticated to the security Realm. If "true", this + Valve uses cached security credentials (username and password) to + reauthenticate to the Realm each request associated + with an SSO session. If "false", the Valve can itself authenticate + requests based on the presence of a valid SSO cookie, without + rechecking with the Realm.

+
rpcTimeout +

The Valve uses a replicated map. This is the timeout for messages + that transfer state to/from the other nodes in the cluster. If not + specified, a default value of 15000 milliseconds is used. +

+
terminateOnStartFailure +

Set to true if you wish this Valve to fail if the + underlying replication fails to start. If the Valve fails, then the + associated container will fail to start. If you set this attribute to + false, and the underlying replications fails to start, the Valve will + start and it will attempt to join the cluster and start replication as + part of the heartbeat process. If not specified, the default value of + false is used.

+
accessTimeout + The timeout for a ping message. If a remote map does not respond within + this timeout period, its regarded as disappeared. + Default value is 5000 milliseconds. +
+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cluster.html b/test.dockerapp/tomcat/webapps/docs/config/cluster.html new file mode 100644 index 0000000..6baf273 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cluster.html @@ -0,0 +1,176 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cluster object

The Cluster object

Table of Contents

Introduction

+

+ The tomcat cluster implementation provides session replication, context attribute replication and + cluster wide WAR file deployment. + While the Cluster configuration is fairly complex, the default configuration will work + for most people out of the box.

+ The Tomcat Cluster implementation is very extensible, and hence we have exposed a myriad of options, + making the configuration seem like a lot, but don't lose faith, instead you have a tremendous control + over what is going on.

+

Security

+ +

The cluster implementation is written on the basis that a secure, trusted +network is used for all of the cluster related network traffic. It is not safe +to run a cluster on a insecure, untrusted network.

+ +

There are many options for providing a secure, trusted network for use by a +Tomcat cluster. These include:

+
    +
  • private LAN
  • +
  • a Virtual Private Network (VPN)
  • +
  • IPSEC
  • +
+ +

Engine vs Host placement

+

+ You can place the <Cluster> element inside either the <Engine> + container or the <Host> container.
+ Placing it in the engine, means that you will support clustering in all virtual hosts of Tomcat, + and share the messaging component. When you place the <Cluster> inside the <Engine> + element, the cluster will append the host name of each session manager to the managers name so that two contexts with + the same name but sitting inside two different hosts will be distinguishable. +

+

Context Attribute Replication

+

To configure context attribute replication, simply do this by swapping out the context implementation + used for your application context.

+
<Context className="org.apache.catalina.ha.context.ReplicatedContext"/>
+

+ This context extends the Tomcat StandardContext + so all the options from the base implementation are valid. +

+

Nested Components

+

Manager:
+ The session manager element identifies what kind of session manager is used in this cluster implementation. + This manager configuration is identical to the one you would use in a regular <Context> configuration. +
The default value is the org.apache.catalina.ha.session.DeltaManager that is closely coupled with + the SimpleTcpCluster implementation. Other managers like the org.apache.catalina.ha.session.BackupManager + are/could be loosely coupled and don't rely on the SimpleTcpCluster for its data replication. +

+

Channel:
+ The Channel and its sub components are all part of the IO layer + for the cluster group, and is a module in it's own that we have nick named "Tribes" +
+ Any configuring and tuning of the network layer, the messaging and the membership logic + will be done in the channel and its nested components. + You can always find out more about Apache Tribes +

+

Valve:
+ The Tomcat Cluster implementation uses Tomcat Valves to + track when requests enter and exit the servlet container. It uses these valves to be able to make + intelligent decisions on when to replicate data, which is always at the end of a request. +

+

Deployer:
+ The Deployer component is the Tomcat Farm Deployer. It allows you to deploy and undeploy applications + cluster wide. +

+

ClusterListener:
+ ClusterListener's are used to track messages sent and received using the SimpleTcpCluster. + If you wish to track messages, you can add a listener here, or you can add a valve to the channel object. +

+

Deprecated configuration options

+

+ Deprecated settings: In the previous version of Tomcat you were able to control session + manager settings using manager.<property>=value. + This has been discontinued, as the way it was written interferes with + the ability to support multiple different manager classes under one cluster implementation, + as the same properties might have the different effect on different managers. +

+

Attributes

+

SimpleTcpCluster Attributes

+
+ Attribute + + Description +
className +

The main cluster class, currently only one is available, + org.apache.catalina.ha.tcp.SimpleTcpCluster +

+
channelSendOptions +

The Tribes channel send options, default is 8.
+ This option is used to set the flag that all messages sent through the + SimpleTcpCluster uses. The flag decides how the messages are sent, and is a simple logical OR.

+ +
int options = Channel.SEND_OPTIONS_ASYNCHRONOUS |
+              Channel.SEND_OPTIONS_SYNCHRONIZED_ACK |
+              Channel.SEND_OPTIONS_USE_ACK;
+

Some of the values are:
+ Channel.SEND_OPTIONS_SYNCHRONIZED_ACK = 0x0004
+ Channel.SEND_OPTIONS_ASYNCHRONOUS = 0x0008
+ Channel.SEND_OPTIONS_USE_ACK = 0x0002
+ So to use ACK and ASYNC messaging, the flag would be 10 (8+2) +
+ Note that if you use ASYNC messaging it is possible for update messages + for a session to be processed by the receiving nodes in a different order + to the order in which they were sent.

+
channelStartOptions +

Sets the start and stop flags for the <Channel> object used by the cluster. + The default is Channel.DEFAULT which starts all the channel services, such as + sender, receiver, multicast sender and multicast receiver. + The following flags are available today:

+
Channel.DEFAULT = Channel.SND_RX_SEQ (1) |
+                  Channel.SND_TX_SEQ (2) |
+                  Channel.MBR_RX_SEQ (4) |
+                  Channel.MBR_TX_SEQ (8);
+

To start a channel without multicasting, you would want to use the value Channel.SND_RX_SEQ | Channel.SND_TX_SEQ + that equals to 3. +

+
heartbeatBackgroundEnabled +

Flag whether invoke channel heartbeat at container background thread. Default value is false. + Enable this flag don't forget to disable the channel heartbeat thread. +

+
notifyLifecycleListenerOnFailure +

Flag whether notify LifecycleListeners if all ClusterListener couldn't accept channel message. + Default value is false. +

+
+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/context.html b/test.dockerapp/tomcat/webapps/docs/config/context.html new file mode 100644 index 0000000..74ad879 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/context.html @@ -0,0 +1,1260 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Context Container

The Context Container

Table of Contents

Introduction

+ +

+ The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat. +

+ +

The Context element represents a web + application, which is run within a particular virtual host. + Each web application is based on a Web Application Archive + (WAR) file, or a corresponding directory containing the corresponding + unpacked contents, as described in the Servlet Specification (version + 2.2 or later). For more information about web application archives, + you can download the + Servlet + Specification, and review the Tomcat + Application Developer's Guide.

+ +

The web application used to process each HTTP request is selected + by Catalina based on matching the longest possible prefix of the + Request URI against the context path of each defined Context. + Once selected, that Context will select an appropriate servlet to + process the incoming request, according to the servlet mappings defined + by the web application deployment.

+ +

You may define as many Context elements as you + wish. Each such Context MUST have a unique context name within a virtual + host. The context path does not need to be unique (see parallel + deployment below). In addition, a Context must be present with a + context path equal to + a zero-length string. This Context becomes the default + web application for this virtual host, and is used to process all + requests that do not match any other Context's context path.

+ +

Parallel deployment

+

You may deploy multiple versions of a web application with the same + context path at the same time. The rules used to match requests to a + context version are as follows: +

+
    +
  • If no session information is present in the request, use the latest + version.
  • +
  • If session information is present in the request, check the session + manager of each version for a matching session and if one is found, use that + version.
  • +
  • If session information is present in the request but no matching session + can be found, use the latest version.
  • +
+

The Host may be configured (via the + undeployOldVersions) to remove old versions deployed in this way + once they are no longer in use.

+
+ +

Naming

+

When autoDeploy or deployOnStartup operations + are performed by a Host, the name and context path of the web application are + derived from the name(s) of the file(s) that define(s) the web application. + Consequently, the context path may not be defined in a + META-INF/context.xml embedded in the application and there is a + close relationship between the context name, context path, + context version and the base file name (the name minus any + .war or .xml extension) of the file.

+ +

If no version is specified then the context name is always the + same as the context path. If the context path is the empty + string then the base name will be ROOT (always in upper case) + otherwise the base name will be the context path with the + leading '/' removed and any remaining '/' characters replaced with '#'.

+ +

If a version is specified then the context path remains unchanged + and both the context name and the base name have the string + '##' appended to them followed by the version identifier.

+ +

Some examples of these naming conventions are given below.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Context PathContext VersionContext NameBase File NameExample File Names (.xml, .war & directory)
/fooNone/foofoofoo.xml, foo.war, foo
/foo/barNone/foo/barfoo#barfoo#bar.xml, foo#bar.war, foo#bar
Empty StringNoneEmpty StringROOTROOT.xml, ROOT.war, ROOT
/foo42/foo##42foo##42foo##42.xml, foo##42.war, foo##42
/foo/bar42/foo/bar##42foo#bar##42foo#bar##42.xml, foo#bar##42.war, foo#bar##42
Empty String42##42ROOT##42ROOT##42.xml, ROOT##42.war, ROOT##42
+ +

The version component is treated as a String both for + performance reasons and to allow flexibility in versioning schemes. String + comparisons are used to determine version order. If version is not specified, + it is treated as the empty string. + Therefore, + foo.war will be treated as an earlier version than + foo##11.war and + foo##11.war will be treated as an earlier version than + foo##2.war. If using a purely numerical versioning scheme it is + recommended that zero padding is used so that foo##002.war is + treated as an earlier version than foo##011.war. +

+ +

If you want to deploy a WAR file or a directory using a context path that + is not related to the base file name then one of the following options must + be used to prevent double-deployment: +

+
    +
  • Disable autoDeploy and deployOnStartup and define all + Contexts in server.xml
  • +
  • Locate the WAR and/or directory outside of the Host's appBase and use + a context.xml file with a docBase attribute to define it.
  • +
+
+ +

Defining a context

+

It is NOT recommended to place <Context> elements directly in the + server.xml file. This is because it makes modifying the + Context configuration more invasive since the main + conf/server.xml file cannot be reloaded without restarting + Tomcat.

+ +

Individual Context elements may be explicitly defined: +

+
    +
  • In an individual file at /META-INF/context.xml inside the + application files. Optionally (based on the Host's copyXML attribute) + this may be copied to + $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to + application's base file name plus a ".xml" extension.
  • +
  • In individual files (with a ".xml" extension) in the + $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. + The context path and version will be derived from the base name of the file + (the file name less the .xml extension). This file will always take precedence + over any context.xml file packaged in the web application's META-INF + directory.
  • +
  • Inside a Host element in the main + conf/server.xml.
  • +
+ +

Default Context elements may be defined that apply to + multiple web applications. Configuration for an individual web application + will override anything configured in one of these defaults. Any nested + elements, e.g. <Resource> elements, that are defined in a default + Context will be created once for each + Context to which the default applies. They will not be + shared between Context elements. +

+
    +
  • In the $CATALINA_BASE/conf/context.xml file: + the Context element information will be loaded by all web applications.
  • +
  • In the + $CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default + file: the Context element information will be loaded by all web applications + of that host.
  • +
+ +

With the exception of server.xml, files that define Context + elements may only define a single Context element. +

+ +

In addition to explicitly specified Context elements, there are + several techniques by which Context elements can be created automatically + for you. See + Automatic Application Deployment and + User Web Applications + for more information.

+ +

To define multiple contexts that use a single WAR file or directory, + use one of the options described in the Naming + section above for creating a Context that has a path + that is not related to the base file name.

+
+

Attributes

+ +

Common Attributes

+ +

All implementations of Context + support the following attributes:

+ +
+ Attribute + + Description +
allowCasualMultipartParsing +

Set to true if Tomcat should automatically parse + multipart/form-data request bodies when HttpServletRequest.getPart* + or HttpServletRequest.getParameter* is called, even when the + target servlet isn't marked with the @MultipartConfig annotation + (See Servlet Specification 3.0, Section 3.2 for details). + Note that any setting other than false causes Tomcat + to behave in a way that is not technically spec-compliant. + The default is false

+
allowMultipleLeadingForwardSlashInPath +

Tomcat normalises sequences of multiple / characters in + a URI to a single /. This is for consistencuy with the + behaviour of file systems as URIs are often translated to file system + paths. As a result, the return value of + HttpServletRequest#getContextPath() is expected to start + with multiple / characters for some URIs. This will cause + problems if this value is used directly with + HttpServletResponse#sendRedirect() as redirect paths that + start with // are treated as protocol relative redirects. + To avoid potential issues, Tomcat will collapse multiple leading + / characters at the start of the return value for + HttpServletRequest#getContextPath() to a single + /. This attribute has a default value of false + which enables the collapsing of multiple / characters. To + disable this behaviour, set this attribute to true.

+
altDDName +

The absolute path to the alternative deployment descriptor for this + context. This overrides the default deployment descriptor located at + /WEB-INF/web.xml.

+
backgroundProcessorDelay +

This value represents the delay in seconds between the + invocation of the backgroundProcess method on this context and + its child containers, including all wrappers. + Child containers will not be invoked if their delay value is not + negative (which would mean they are using their own processing + thread). Setting this to a positive value will cause + a thread to be spawn. After waiting the specified amount of time, + the thread will invoke the backgroundProcess method on this host + and all its child containers. A context will use background + processing to perform session expiration and class monitoring for + reloading. If not specified, the default value for this attribute is + -1, which means the context will rely on the background processing + thread of its parent host.

+
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Context interface. + If not specified, the standard value (defined below) will be used.

+
containerSciFilter +

The regular expression that specifies which container provided SCIs + should be filtered out and not used for this context. Matching uses + java.util.regex.Matcher.find() so the regular expression + only has to match a sub-string of the fully qualified class name of the + container provided SCI for it to be filtered out. If not specified, + no filtering will be applied.

+
cookies +

Set to true if you want cookies to be used for + session identifier communication if supported by the client (this + is the default). Set to false if you want to disable + the use of cookies for session identifier communication, and rely + only on URL rewriting by the application.

+
crossContext +

Set to true if you want calls within this application + to ServletContext.getContext() to successfully return a + request dispatcher for other web applications running on this virtual + host. Set to false (the default) in security + conscious environments, to make getContext() always + return null.

+
docBase +

The Document Base (also known as the Context + Root) directory for this web application, or the pathname + to the web application archive file (if this web application is + being executed directly from the WAR file). You may specify + an absolute pathname for this directory or WAR file, or a pathname + that is relative to the appBase directory of the + owning Host.

+

The value of this field must not be set unless the Context element is + defined in server.xml or the docBase is not located under + the Host's appBase.

+

If a symbolic link is used for docBase then changes to the + symbolic link will only be effective after a Tomcat restart or + by undeploying and redeploying the context. A context reload is not + sufficient.

+
dispatchersUseEncodedPaths +

Controls whether paths used in calls to obtain a request dispatcher + ares expected to be encoded. This affects both how Tomcat handles calls + to obtain a request dispatcher as well as how Tomcat generates paths + used to obtain request dispatchers internally. If not specified, the + default value of true is used.

+
failCtxIfServletStartFails +

Set to true to have the context fail its startup if any + servlet that has load-on-startup >=0 fails its own startup.

+

If not specified, the attribute of the same name in the parent Host + configuration is used if specified. Otherwise the default value of + false is used.

+
fireRequestListenersOnForwards +

Set to true to fire any configured + ServletRequestListeners when Tomcat forwards a request. This is + primarily of use to users of CDI frameworks that use + ServletRequestListeners to configure the necessary environment for a + request. If not specified, the default value of false is + used.

+
logEffectiveWebXml +

Set to true if you want the effective web.xml used for a + web application to be logged (at INFO level) when the application + starts. The effective web.xml is the result of combining the + application's web.xml with any defaults configured by Tomcat and any + web-fragment.xml files and annotations discovered. If not specified, the + default value of false is used.

+
mapperContextRootRedirectEnabled +

If enabled, requests for a web application context root will be + redirected (adding a trailing slash) if necessary by the Mapper rather + than the default Servlet. This is more efficient but has the side effect + of confirming that the context path exists. If not specified, the + default value of true is used.

+
mapperDirectoryRedirectEnabled +

If enabled, requests for a web application directory will be + redirected (adding a trailing slash) if necessary by the Mapper rather + than the default Servlet. This is more efficient but has the side effect + of confirming that the directory is exists. If not specified, the + default value of false is used.

+
override +

Set to true to ignore any settings in both the global + or Host default contexts. By default, settings + from a default context will be used but may be overridden by a setting + the same attribute explicitly for the Context.

+
path +

The context path of this web application, which is + matched against the beginning of each request URI to select the + appropriate web application for processing. All of the context paths + within a particular Host must be unique. + If you specify a context path of an empty string (""), you are + defining the default web application for this Host, which + will process all requests not assigned to other Contexts.

+

This attribute must only be used when statically defining a Context + in server.xml. In all other circumstances, the path will be inferred + from the filenames used for either the .xml context file or the docBase. +

+

Even when statically defining a Context in server.xml, this attribute + must not be set unless either the docBase is not located under the + Host's appBase or both + deployOnStartup and autoDeploy are false. If + this rule is not followed, double deployment is likely to result.

+
preemptiveAuthentication +

When set to true and the user presents credentials for a + resource that is not protected by a security constraint, if the + authenticator supports preemptive authentication (the standard + authenticators provided with Tomcat do) then the user' credentials + will be processed. If not specified, the default of falseis + used. +

+
privileged +

Set to true to allow this context to use container + servlets, like the manager servlet. Use of the privileged + attribute will change the context's parent class loader to be the + Server class loader rather than the Shared class + loader. Note that in a default installation, the Common class + loader is used for both the Server and the Shared + class loaders.

+
reloadable +

Set to true if you want Catalina to monitor classes in + /WEB-INF/classes/ and /WEB-INF/lib for + changes, and automatically reload the web application if a change + is detected. This feature is very useful during application + development, but it requires significant runtime overhead and is + not recommended for use on deployed production applications. That's + why the default setting for this attribute is false. You + can use the Manager web + application, however, to trigger reloads of deployed applications + on demand.

+
resourceOnlyServlets +

Comma separated list of Servlet names (as used in + /WEB-INF/web.xml) that expect a resource to be present. + Ensures that welcome files associated with Servlets that expect a + resource to be present (such as the JSP Servlet) are not used when there + is no resource present. This prevents issues caused by the clarification + of welcome file mapping in section 10.10 of the Servlet 3.0 + specification. If the + org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to + true, the default value of this attribute will be the empty + string, else the default value will be jsp.

+
sendRedirectBody +

If true, redirect responses will include a short + response body that includes details of the redirect as recommended by + RFC 2616. This is disabled by default since including a response body + may cause problems for some application component such as compression + filters.

+
sessionCookieDomain +

The domain to be used for all session cookies created for this + context. If set, this overrides any domain set by the web application. + If not set, the value specified by the web application, if any, will be + used.

+
sessionCookieName +

The name to be used for all session cookies created for this + context. If set, this overrides any name set by the web application. + If not set, the value specified by the web application, if any, will be + used, or the name JSESSIONID if the web application does + not explicitly set one.

+
sessionCookiePath +

The path to be used for all session cookies created for this + context. If set, this overrides any path set by the web application. + If not set, the value specified by the web application will be used, or + the context path used if the web application does not explicitly set + one. To configure all web application to use an empty path (this can be + useful for portlet specification implementations) set this attribute to + / in the global CATALINA_BASE/conf/context.xml + file.

+

Note: Once one web application using + sessionCookiePath="/" obtains a session, all + subsequent sessions for any other web application in the same host also + configured with sessionCookiePath="/" will always + use the same session ID. This holds even if the session is invalidated + and a new one created. This makes session fixation protection more + difficult and requires custom, Tomcat specific code to change the + session ID shared by the multiple applications.

+
sessionCookiePathUsesTrailingSlash +

Some browsers, such as Internet Explorer, Safari and Edge, will send + a session cookie for a context with a path of /foo with a + request to /foobar in violation of RFC6265. This could + expose a session ID from an application deployed at /foo to + an application deployed at /foobar. If the application + deployed at /foobar is untrusted, this could create a + security risk. However, it should be noted that RFC 6265, section 8.5 + makes clear that path alone should not be view as sufficient to prevent + untrusted applications accessing cookies from other applications. To + mitigate this risk, this attribute may be set to true and + Tomcat will add a trailing slash to the path associated with the session + cookie so, in the above example, the cookie path becomes /foo/. However, + with a cookie path of /foo/, browsers will no longer send the cookie + with a request to /foo. This should not be a problem unless there is a + servlet mapped to /*. In this case this attribute will need to be set to + false to disable this feature. The default value for this + attribute is false.

+
swallowAbortedUploads +

Set to false if Tomcat should not read any additional request + body data for aborted uploads and instead abort the client connection. + This setting is used in the following situations: +

+
    +
  • the size of the request body is larger than the + maxPostSize configured in the connector
  • +
  • the size limit of a MultiPart upload is reached
  • +
  • the servlet sets the response status to 413 (Request Entity Too + Large)
  • +
+

+ Not reading the additional data will free the request processing thread + more quickly. Unfortunately most HTTP clients will not read the response + if they can not write the full request.

+

The default is true, so additional data will be + read.

+

Note if an error occurs during the request processing that triggers + a 5xx response, any unread request data will always be ignored and the + client connection will be closed once the error response has been + written.

+
swallowOutput +

If the value of this flag is true, the bytes output to + System.out and System.err by the web application will be redirected to + the web application logger. If not specified, the default value + of the flag is false.

+
tldValidation +

If the value of this flag is true, the TLD files + will be XML validated on context startup. If the + org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to + true, the default value of this attribute will be + true, else the default value will be false. + Setting this attribute to true will incur a performance + penalty.

+
useHttpOnly +

Should the HttpOnly flag be set on session cookies to prevent client + side script from accessing the session ID? Defaults to + true.

+
useRelativeRedirects +

Controls whether HTTP 1.1 and later location headers generated by a + call to + javax.servlet.http.HttpServletResponse#sendRedirect(String) + will use relative or absolute redirects. Relative redirects are more + efficient but may not work with reverse proxies that change the context + path. It should be noted that it is not recommended to use a reverse + proxy to change the context path because of the multiple issues it + creates. Absolute redirects should work with reverse proxies that change + the context path but may cause issues with the + org.apache.catalina.filters.RemoteIpFilter if the filter is + changing the scheme and/or port. If the + org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to + true, the default value of this attribute will be + false, else the default value will be true. +

+
validateClientProvidedNewSessionId +

When a client provides the ID for a new session, this attribute + controls whether that ID is validated. The only use case for using a + client provided session ID is to have a common session ID across + multiple web applications. Therefore, any client provided session ID + should already exist in another web application. If this check is + enabled, the client provided session ID will only be used if the session + ID exists in at least one other web application for the current host. + Note that the following additional tests are always applied, + irrespective of this setting:

+
    +
  • The session ID is provided by a cookie
  • +
  • The session cookie has a path of {@code /}
  • +
+

If not specified, the default value of true will be + used.

+
wrapperClass +

Java class name of the org.apache.catalina.Wrapper + implementation class that will be used for servlets managed by this + Context. If not specified, a standard default value will be used.

+
xmlBlockExternal +

If the value of this flag is true, the parsing of + web.xml, web-fragment.xml, *.tld, + *.jspx, *.tagx and tagPlugins.xml + files for this web application will not permit external entities to be + loaded. If not specified, the default value of true will + be used.

+
xmlNamespaceAware +

If the value of this flag is true, the parsing of + web.xml and web-fragment.xml files for this + web application will be namespace-aware. Note that *.tld, + *.jspx and *.tagx files are always parsed + using a namespace-aware parser and that the tagPlugins.xml + file (if any) is never parsed using a namespace-aware parser. Note also + that if you turn this flag on, you should probably also turn + xmlValidation on. If the + org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to + true, the default value of this attribute will be + true, else the default value will be false. + Setting this attribute to true will incur a performance + penalty.

+
xmlValidation +

If the value of this flag is true, the parsing of + web.xml and web-fragment.xml files for this + web application will use a validating parser. If the + org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to + true, the default value of this attribute will be + true, else the default value will be false. + Setting this attribute to true will incur a performance + penalty.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of Context is + org.apache.catalina.core.StandardContext. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
addWebinfClassesResources +

This attribute controls if, in addition to static resources being + served from META-INF/resources inside web application JAR + files, static resources are also served from + WEB-INF/classes/META-INF/resources. This only applies to + web applications with a major version of 3 or higher. Since this is a + proprietary extension to the Servlet 3 specification, it is disabled by + default. To enable this feature, set the attribute to true. +

+
antiResourceLocking +

If true, Tomcat will prevent any file locking. + This will significantly impact startup time of applications, + but allows full webapp hot deploy and undeploy on platforms + or configurations where file locking can occur. + If not specified, the default value is false.

+ +

Please note that setting this to true has some side + effects, including the disabling of JSP reloading in a running server: + see + Bugzilla 37668.

+ +

Please note that setting this flag to true in applications that are + outside the appBase for the Host (the webapps directory + by default) will cause the application to be deleted on + Tomcat shutdown. You probably don't want to do this, so think twice + before setting antiResourceLocking=true on a webapp that's outside the + appBase for its Host.

+
clearReferencesHttpClientKeepAliveThread +

If true and an sun.net.www.http.HttpClient + keep-alive timer thread has been started by this web application and is + still running, Tomcat will change the context class loader for that + thread from the web application class loader to the parent of the web + application class loader to prevent a memory leak. Note that the + keep-alive timer thread will stop on its own once the keep-alives all + expire however, on a busy system that might not happen for some time. If + not specified, the default value of true will be used.

+
clearReferencesObjectStreamClassCaches +

If true, when the web application is stopped Tomcat + looks for SoftReferences to classes loaded by the web + application in the ObjectStreamClass class used for + serialization and clears any SoftReferences it finds. This + feature uses reflection to identify the SoftReferences and + therefore requires that the command line option + -XaddExports:java.base/java.io=ALL-UNNAMED is set + when running on Java 9 and above. If not specified, the default value of + true will be used.

+
clearReferencesRmiTargets +

If true, Tomcat looks for memory leaks associated with + RMI Targets and clears any it finds. This feature uses reflection to + identify the leaks and therefore requires that the command line option + -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED is set + when running on Java 9 and above. Applications without memory leaks + should operate correctly with this attribute set to false. + If not specified, the default value of true will be used.

+
clearReferencesStatic +

If true, Tomcat attempts to null out any static or final + fields from loaded classes when a web application is stopped as a work + around for apparent garbage collection bugs and application coding + errors. There have been some issues reported with log4j when this + is true. Applications without memory leaks using recent + JVMs should operate correctly with this attribute set to + false. If not specified, the default value of + false will be used.

+

This attribute has been deprecated and will be removed in Tomcat + 8.5.

+
clearReferencesStopThreads +

If true, Tomcat attempts to terminate threads that have + been started by the web application. Stopping threads is performed via + the deprecated (for good reason) Thread.stop() method and + is likely to result in instability. As such, enabling this should be + viewed as an option of last resort in a development environment and is + not recommended in a production environment. If not specified, the + default value of false will be used. If this feature is + enabled, web applications may take up to two seconds longer to stop as + executor threads are given up to two seconds to stop gracefully before + Thread.stop() is called on any remaining threads.

+
clearReferencesStopTimerThreads +

If true, Tomcat attempts to terminate + java.util.Timer threads that have been started by the web + application. Unlike standard threads, timer threads can be stopped + safely although there may still be side-effects for the application. If + not specified, the default value of false will be used.

+
copyXML +

Set to true if you want a context XML descriptor + embedded inside the application (located at + /META-INF/context.xml) to be copied to the owning + Host's xmlBase when the application + is deployed. On subsequent starts, the copied context XML descriptor + will be used in preference to any context XML descriptor embedded inside + the application even if the descriptor embedded inside the application + is more recent. The flag's value defaults to false. Note if + the deployXML attribute of the owning + Host is false or if the + copyXML attribute of the owning + Host is true, this attribute will + have no effect.

+
jndiExceptionOnFailedWrite +

If true, any attempt by an application to modify the + provided JNDI context with a call to bind(), unbind(), + createSubContext(), destroySubContext() or close() will trigger a + javax.naming.OperationNotSupportedException as required by + section EE.5.3.4 of the Java EE specification. This exception can be + disabled by setting this attribute to false in which case any calls to + modify the JNDI context will return without making any changes + and methods that return values will return null. If not + specified, the specification compliant default of true will + be used.

+
renewThreadsWhenStoppingContext +

If true, when this context is stopped, Tomcat renews all + the threads from the thread pool that was used to serve this context. + This also requires that the + ThreadLocalLeakPreventionListener be configured in + server.xml and that the threadRenewalDelay + property of the Executor be >=0. If not specified, the + default value of true will be used.

+
unloadDelay +

Number of ms that the container will wait for servlets to unload. + If not specified, the default value is 2000 ms.

+
unpackWAR +

If false, the unpackWARs attribute of + the owning Host will be overridden and the WAR + file will not be unpacked. If true, the value of the owning + Host's unpackWARs + attribute will determine if the WAR is unpacked. If not specified, the + default value is true.

+
useNaming +

Set to true (the default) to have Catalina enable a + JNDI InitialContext for this web application that is + compatible with Java2 Enterprise Edition (J2EE) platform + conventions.

+
workDir +

Pathname to a scratch directory to be provided by this Context + for temporary read-write use by servlets within the associated web + application. This directory will be made visible to servlets in the + web application by a servlet context attribute (of type + java.io.File) named + javax.servlet.context.tempdir as described in the + Servlet Specification. If not specified, a suitable directory + underneath $CATALINA_BASE/work will be provided.

+
+ +
+ + +

Nested Components

+ +

You can nest at most one instance of the following utility components + by nesting a corresponding element inside your Context + element:

+
    +
  • Cookie Processor - + Configure parsing and generation of HTTP cookie headers.
  • +
  • Loader - + Configure the web application class loader that will be used to load + servlet and bean classes for this web application. Normally, the + default configuration of the class loader will be sufficient.
  • +
  • Manager - + Configure the session manager that will be used to create, destroy, + and persist HTTP sessions for this web application. Normally, the + default configuration of the session manager will be sufficient.
  • +
  • Realm - + Configure a realm that will allow its + database of users, and their associated roles, to be utilized solely + for this particular web application. If not specified, this web + application will utilize the Realm associated with the owning + Host or Engine.
  • +
  • Resources - + Configure the resource manager that will be used to access the static + resources associated with this web application. Normally, the + default configuration of the resource manager will be sufficient.
  • +
  • WatchedResource - The auto deployer will monitor the + specified static resource of the web application for updates, and will + reload the web application if it is updated. The content of this element + must be a string.
  • +
  • JarScanner - + Configure the Jar Scanner that will be used to scan the web application + for JAR files and directories of class files. It is typically used during + web application start to identify configuration files such as TLDs o + web-fragment.xml files that must be processed as part of the web + application initialisation. Normally, the default Jar Scanner + configuration will be sufficient.
  • +
+ +

Special Features

+ + +

Logging

+ +

A context is associated with the + org.apache.catalina.core.ContainerBase.[enginename].[hostname].[path] + log category. Note that the brackets are actually part of the name, don't omit them.

+ +
+ + +

Access Logs

+ +

When you run a web server, one of the output files normally generated + is an access log, which generates one line of information for + each request processed by the server, in a standard format. Catalina + includes an optional Valve implementation that + can create access logs in the same standard format created by web servers, + or in any number of custom formats.

+ +

You can ask Catalina to create an access log for all requests + processed by an Engine, + Host, or Context + by nesting a Valve element like this:

+ +
<Context>
+  ...
+  <Valve className="org.apache.catalina.valves.AccessLogValve"
+         prefix="localhost_access_log" suffix=".txt"
+         pattern="common"/>
+  ...
+</Context>
+ +

See Access Logging Valves + for more information on the configuration attributes that are + supported.

+ +
+ + +

Automatic Context Configuration

+ +

If you use the standard Context implementation, + the following configuration steps occur automatically when Catalina + is started, or whenever this web application is reloaded. No special + configuration is required to enable this feature.

+ +
    +
  • If you have not declared your own Loader + element, a standard web application class loader will be configured. +
  • +
  • If you have not declared your own Manager + element, a standard session manager will be configured.
  • +
  • If you have not declared your own Resources + element, a standard resources manager will be configured.
  • +
  • The web application properties listed in conf/web.xml + will be processed as defaults for this web application. This is used + to establish default mappings (such as mapping the *.jsp + extension to the corresponding JSP servlet), and other standard + features that apply to all web applications.
  • +
  • The web application properties listed in the + /WEB-INF/web.xml resource for this web application + will be processed (if this resource exists).
  • +
  • If your web application has specified security constraints that might + require user authentication, an appropriate Authenticator that + implements the login method you have selected will be configured.
  • +
+ +
+ + +

Context Parameters

+ +

You can configure named values that will be made visible to the + web application as servlet context initialization parameters by nesting + <Parameter> elements inside this element. For + example, you can create an initialization parameter like this:

+
<Context>
+  ...
+  <Parameter name="companyName" value="My Company, Incorporated"
+         override="false"/>
+  ...
+</Context>
+ +

This is equivalent to the inclusion of the following element in the + web application deployment descriptor (/WEB-INF/web.xml): +

+
<context-param>
+  <param-name>companyName</param-name>
+  <param-value>My Company, Incorporated</param-value>
+</context-param>
+

but does not require modification of the deployment descriptor + to customize this value.

+ +

The valid attributes for a <Parameter> element + are as follows:

+ +
+ Attribute + + Description +
description +

Optional, human-readable description of this context + initialization parameter.

+
name +

The name of the context initialization parameter to be created.

+
override +

Set this to false if you do not want + a <context-param> for the same parameter name, + found in the web application deployment descriptor, to override the + value specified here. By default, overrides are allowed.

+
value +

The parameter value that will be presented to the application + when requested by calling + ServletContext.getInitParameter().

+
+ +
+ + +

Environment Entries

+ +

You can configure named values that will be made visible to the + web application as environment entry resources, by nesting + <Environment> entries inside this element. For + example, you can create an environment entry like this:

+
<Context>
+  ...
+  <Environment name="maxExemptions" value="10"
+         type="java.lang.Integer" override="false"/>
+  ...
+</Context>
+ +

This is equivalent to the inclusion of the following element in the + web application deployment descriptor (/WEB-INF/web.xml): +

+
<env-entry>
+  <env-entry-name>maxExemptions</env-entry-name>
+  <env-entry-value>10</env-entry-value>
+  <env-entry-type>java.lang.Integer</env-entry-type>
+</env-entry>
+

but does not require modification of the deployment descriptor + to customize this value.

+ +

The valid attributes for an <Environment> element + are as follows:

+ +
+ Attribute + + Description +
description +

Optional, human-readable description of this environment entry.

+
name +

The name of the environment entry to be created, relative to the + java:comp/env context.

+
override +

Set this to false if you do not want + an <env-entry> for the same environment entry name, + found in the web application deployment descriptor, to override the + value specified here. By default, overrides are allowed.

+
type +

The fully qualified Java class name expected by the web application + for this environment entry. Must be a legal value for + <env-entry-type> in the web application deployment + descriptor.

+
value +

The parameter value that will be presented to the application + when requested from the JNDI context. This value must be convertable + to the Java type defined by the type attribute.

+
+ +
+ + +

Lifecycle Listeners

+ +

If you have implemented a Java object that needs to know when this + Context is started or stopped, you can declare it by + nesting a Listener element inside this element. The + class name you specify must implement the + org.apache.catalina.LifecycleListener interface, and + the class must be packaged in a jar and placed in the + $CATALINA_HOME/lib directory. + It will be notified about the occurrence of the corresponding + lifecycle events. Configuration of such a listener looks like this:

+ +
<Context>
+  ...
+  <Listener className="com.mycompany.mypackage.MyListener" ... >
+  ...
+</Context>
+ +

Note that a Listener can have any number of additional properties + that may be configured from this element. Attribute names are matched + to corresponding JavaBean property names using the standard property + method naming patterns.

+ +
+ + +

Request Filters

+ +

You can ask Catalina to check the IP address, or host name, on every + incoming request directed to the surrounding + Engine, Host, or + Context element. The remote address or name + will be checked against configured "accept" and/or "deny" + filters, which are defined using java.util.regex Regular + Expression syntax. Requests that come from locations that are + not accepted will be rejected with an HTTP "Forbidden" error. + Example filter declarations:

+ +
<Context>
+  ...
+  <Valve className="org.apache.catalina.valves.RemoteHostValve"
+         allow=".*\.mycompany\.com|www\.yourcompany\.com"/>
+  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
+         deny="192\.168\.1\.\d+"/>
+  ...
+</Context>
+ +

See Remote Address Filter + and Remote Host Filter for + more information about the configuration options that are supported.

+ +
+ + +

Resource Definitions

+ +

You can declare the characteristics of the resource + to be returned for JNDI lookups of <resource-ref> and + <resource-env-ref> elements in the web application + deployment descriptor. You MUST also define + the needed resource parameters as attributes of the Resource + element, to configure the object factory to be used (if not known to Tomcat + already), and the properties used to configure that object factory.

+ +

For example, you can create a resource definition like this:

+
<Context>
+  ...
+  <Resource name="jdbc/EmployeeDB" auth="Container"
+            type="javax.sql.DataSource"
+     description="Employees Database for HR Applications"/>
+  ...
+</Context>
+ +

This is equivalent to the inclusion of the following element in the + web application deployment descriptor (/WEB-INF/web.xml):

+
<resource-ref>
+  <description>Employees Database for HR Applications</description>
+  <res-ref-name>jdbc/EmployeeDB</res-ref-name>
+  <res-ref-type>javax.sql.DataSource</res-ref-type>
+  <res-auth>Container</res-auth>
+</resource-ref>
+ +

but does not require modification of the deployment + descriptor to customize this value.

+ +

The valid attributes for a <Resource> element + are as follows:

+ +
+ Attribute + + Description +
auth +

Specify whether the web Application code signs on to the + corresponding resource manager programmatically, or whether the + Container will sign on to the resource manager on behalf of the + application. The value of this attribute must be + Application or Container. This + attribute is required if the web application + will use a <resource-ref> element in the web + application deployment descriptor, but is optional if the + application uses a <resource-env-ref> instead.

+
closeMethod +

Name of the zero-argument method to call on a singleton resource when + it is no longer required. This is intended to speed up clean-up of + resources that would otherwise happen as part of garbage collection. + This attribute is ignored if the singleton attribute is + false. If not specified, no default is defined and no close method will + be called.

+

For Apache Commons DBCP and Apache Tomcat JDBC connection pools + you can use closeMethod="close".

+
description +

Optional, human-readable description of this resource.

+
name +

The name of the resource to be created, relative to the + java:comp/env context.

+
scope +

Specify whether connections obtained through this resource + manager can be shared. The value of this attribute must be + Shareable or Unshareable. By default, + connections are assumed to be shareable.

+
singleton +

Specify whether this resource definition is for a singleton resource, + i.e. one where there is only a single instance of the resource. If this + attribute is true, multiple JNDI lookups for this resource + will return the same object. If this attribute is false, + multiple JNDI lookups for this resource will return different objects. + This attribute must be true for + javax.sql.DataSource resources to enable JMX registration + of the DataSource. The value of this attribute must be true + or false. By default, this attribute is true. +

+
type +

The fully qualified Java class name expected by the web + application when it performs a lookup for this resource.

+
+ + +
+ + +
+ +

This element is used to create a link to a global JNDI resource. Doing + a JNDI lookup on the link name will then return the linked global + resource.

+ +

For example, you can create a resource link like this:

+
<Context>
+  ...
+  <ResourceLink name="linkToGlobalResource"
+            global="simpleValue"
+            type="java.lang.Integer"
+  ...
+</Context>
+ +

The valid attributes for a <ResourceLink> element + are as follows:

+ +
+ Attribute + + Description +
global +

The name of the linked global resource in the + global JNDI context.

+
name +

The name of the resource link to be created, relative to the + java:comp/env context.

+
type +

The fully qualified Java class name expected by the web + application when it performs a lookup for this resource link.

+
factory +

The fully qualified Java class name for the class creating these objects. + This class should implement the javax.naming.spi.ObjectFactory interface.

+
+ +

When the attribute factory="org.apache.naming.factory.DataSourceLinkFactory" the resource link can be used with + two additional attributes to allow a shared data source to be used with different credentials. + When these two additional attributes are used in combination with the javax.sql.DataSource + type, different contexts can share a global data source with different credentials. + Under the hood, what happens is that a call to getConnection() + is simply translated to a call + getConnection(username, password) on the global data source. This is an easy way to get code to be transparent to what schemas are being used, + yet be able to control connections (or pools) in the global configuration. +

+
+ Attribute + + Description +
username +

username value for the getConnection(username, password) + call on the linked global DataSource. +

+
password +

password value for the getConnection(username, password) + call on the linked global DataSource. +

+
+

Shared Data Source Example:

+

Warning: This feature works only if the global DataSource +supports getConnection(username, password) method. +Apache Commons DBCP pool that +Tomcat uses by default does not support it. See its Javadoc for +BasicDataSource class. +Apache Tomcat JDBC pool does support it, +but by default this support is disabled and can be enabled by +alternateUsernameAllowed attribute. See its documentation +for details.

+
<GlobalNamingResources>
+  ...
+  <Resource name="sharedDataSource"
+            global="sharedDataSource"
+            type="javax.sql.DataSource"
+            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
+            alternateUsernameAllowed="true"
+            username="bar"
+            password="barpass"
+            ...
+  ...
+</GlobalNamingResources>
+
+<Context path="/foo"...>
+  ...
+  <ResourceLink
+            name="appDataSource"
+            global="sharedDataSource"
+            type="javax.sql.DataSource"
+            factory="org.apache.naming.factory.DataSourceLinkFactory"
+            username="foo"
+            password="foopass"
+  ...
+</Context>
+<Context path="/bar"...>
+  ...
+  <ResourceLink
+            name="appDataSource"
+            global="sharedDataSource"
+            type="javax.sql.DataSource"
+  ...
+</Context>
+

When a request for getConnection() is made in the + /foo context, the request is translated into + getConnection("foo","foopass"), + while a request in the /bar gets passed straight through.

+
+ +

Transaction

+ +

You can declare the characteristics of the UserTransaction + to be returned for JNDI lookup for java:comp/UserTransaction. + You MUST define an object factory class to instantiate + this object as well as the needed resource parameters as attributes of the + Transaction + element, and the properties used to configure that object factory.

+ +

The valid attributes for the <Transaction> element + are as follows:

+ +
+ Attribute + + Description +
factory +

The class name for the JNDI object factory.

+
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/cookie-processor.html b/test.dockerapp/tomcat/webapps/docs/config/cookie-processor.html new file mode 100644 index 0000000..6e1a3e0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/cookie-processor.html @@ -0,0 +1,209 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Cookie Processor Component

The Cookie Processor Component

Table of Contents

Introduction

+ +

The CookieProcessor element represents the component that + parses received cookie headers into javax.servlet.http.Cookie + objects accessible through HttpServletRequest.getCookies() and + converts javax.servlet.http.Cookie objects added to the response + through HttpServletResponse.addCookie() to the HTTP headers + returned to the client.

+ +

A CookieProcessor element MAY be nested inside a + Context component. If it is not included, a default + implementation will be created automatically.

+ +

Note: CookieProcessor is a new + configuration element, introduced in Tomcat 8.0.15.

+
    +
  • The CookieProcessor element allows different cookie + parsing configuration in each web application, or globally in the default + conf/context.xml file. The legacy cookie parsing algorithm + supported only limited global configuration via several + system properties. Those + system properties are still supported, but are going to be deprecated in + favor of this new configuration element. +
  • +
  • The new RFC6265-compliant implementation is a drop-in replacement for + the original legacy one. The legacy implementation remains the default. You + can select the implementation by setting className attribute + on CookieProcessor element.
  • +
+ +

Attributes

+ +

Common Attributes

+ +

All implementations of CookieProcessor support the + following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.tomcat.util.http.CookieProcessor + interface. If not specified, the standard value (defined below) will be + used.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of CookieProcessor is + org.apache.tomcat.util.http.LegacyCookieProcessor. Note + that it is anticipated that this will change to + org.apache.tomcat.util.http.Rfc6265CookieProcessor in a future + Tomcat 8 release.

+ +

This is the legacy cookie parser based on RFC6265, RFC2109 and RFC2616. + It implements a strict interpretation of the cookie specifications. Due to + various interoperability issues with browsers not all strict behaviours + are enabled by default and additional options are available to further + relax the behaviour of this cookie processor if required.

+ +
+ Attribute + + Description +
allowEqualsInValue +

If this is true Tomcat will allow '=' + characters when parsing unquoted cookie values. If false, + cookie values containing '=' will be terminated when the + '=' is encountered and the remainder of the cookie value + will be dropped.

+

If not set the specification compliant default value of + false will be used. This default may be changed by setting + the + org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE + system property.

+
allowHttpSepsInV0 +

If this is true Tomcat will allow HTTP separators in + cookie names and values.

+

If not specified, the default specification compliant value of + false will be used. This default may be changed by setting + the + org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0 + system property.

+
allowNameOnly +

If this is true Tomcat will allow name only cookies + (with or without trailing '=') when parsing cookie headers. + If false, name only cookies will be dropped.

+

If not set the specification compliant default value of + false will be used. This default may be changed by setting + the + org.apache.tomcat.util.http.ServerCookie.ALLOW_NAME_ONLY + system property.

+
alwaysAddExpires +

If this is true Tomcat will always add an expires + parameter to a SetCookie header even for cookies with version greater + than zero. This is to work around a known IE6 and IE7 bug that causes I + to ignore the Max-Age parameter in a SetCookie header.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set + to true, the default of this setting will be + false, else the default value will be true. +

+
forwardSlashIsSeparator +

If this is true Tomcat will treat the forward slash + character ('/') as an HTTP separator when processing cookie + headers. If org.apache.catalina.STRICT_SERVLET_COMPLIANCE + is set to true, the default of this setting will be + true, else the default value will be false. + This default may be overridden by setting the + org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR + system property.

+
preserveCookieHeader +

This attribute is no longer used. From Tomcat 8.0.31, Tomcat will + always preserve the cookie header returned by + HttpServletRequest.getHeader().

+
+ +
+ +
+ +

This cookie processor is based on RFC6265 with the following changes to + support better interoperability:

+ +
    +
  • Values 0x80 to 0xFF are permitted in cookie-octet to support the use + of UTF-8 in cookie values as used by HTML 5.
  • +
  • For cookies without a value, the '=' is not required after the name as + some browsers do not sent it.
  • +
+ +

The RFC 6265 cookie processor is generally more lenient than the legacy + cookie parser. In particular:

+ +
    +
  • The '=' and '/' characters are always + permitted in a cookie value.
  • +
  • Name only cookies are always permitted.
  • +
  • The cookie header is always preserved.
  • +
+ +

No additional attributes are supported by the RFC 6265 Cookie + Processor.

+ +
+ +

Nested Components

+ +

No element may be nested inside a CookieProcessor.

+ +

Special Features

+ +

No special features are associated with a CookieProcessor + element.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/credentialhandler.html b/test.dockerapp/tomcat/webapps/docs/config/credentialhandler.html new file mode 100644 index 0000000..ea26178 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/credentialhandler.html @@ -0,0 +1,209 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The CredentialHandler Component

The CredentialHandler Component

Table of Contents

Introduction

+ +

The CredentialHandler element represents the component + used by a Realm to compare a provided credential such + as a password with the version of the credential stored by the + Realm. The CredentialHandler can + also be used to generate a new stored version of a given credential that would + be required, for example, when adding a new user to a + Realm or when changing a user's password.

+ +

A CredentialHandler element MUST be nested inside a + Realm component. If it is not included, + a default CredentialHandler will be created using the + MessageDigestCredentialHandler.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of CredentialHandler support the + following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.CredentialHandler + interface.

+
+ +

Unlike most Catalina components, there are several standard + CredentialHandler implementations available. As a result, + if a CredentialHandler element is present then the + className attribute MUST be used to select the implementation + you wish to use.

+ +
+ + +

MessageDigestCredentialHandler

+ +

The MessageDigestCredentialHandler is used when stored + passwords are protected by a message digest. This credential handler + supports the following forms of stored passwords:

+
    +
  • plainText - the plain text credentials if no + algorithm is specified
  • +
  • encodedCredential - a hex encoded digest of the + password digested using the configured digest
  • +
  • {MD5}encodedCredential - a Base64 encoded MD5 + digest of the password
  • +
  • {SHA}encodedCredential - a Base64 encoded SHA1 digest + of the password
  • +
  • {SSHA}encodedCredential - 20 character salt followed + by the salted SHA1 digest Base64 encoded
  • +
  • salt$iterationCount$encodedCredential - a hex encoded + salt, iteration code and a hex encoded credential, each separated by + $
  • +
+ +

If the stored password form does not include an iteration count then an + iteration count of 1 is used.

+ +

If the stored password form does not include salt then no salt is + used.

+ +
+ Attribute + + Description +
algorithm +

The name of the java.security.MessageDigest algorithm + used to encode user passwords stored in the database. If not specified, + user passwords are assumed to be stored in clear-text.

+
encoding +

Digesting the password requires that it is converted to bytes. This + attribute determines the character encoding to use for conversions + between characters and bytes. If not specified, UTF-8 will be used.

+
iterations +

The number of iterations to use when creating a new stored credential + from a clear text credential.

+
saltLength +

The length of the randomly generated salt to use when creating a + new stored credential from a clear text credential.

+
+ +
+ +

NestedCredentialHandler

+ +

The NestedCredentialHandler is an implementation of + CredentialHandler that delegates to one or more + sub-CredentialHandlers.

+ +

Using the NestedCredentialHandler gives the developer + the ability to combine multiple CredentialHandlers of the + same or different types.

+ +

Sub-CredentialHandlers are defined by nesting CredentialHandler elements + inside the CredentialHandler element that defines the + NestedCredentialHandler. Credentials will be matched against each + CredentialHandler in the order they are listed. A match against + any CredentialHandler will be sufficient for the credentials to be + considered matched.

+ +
+ +

SecretKeyCredentialHandler

+ +

The SecretKeyCredentialHandler is used when stored + passwords are built using javax.crypto.SecretKeyFactory. This + credential handler supports the following forms of stored passwords:

+
    +
  • salt$iterationCount$encodedCredential - a hex encoded + salt, iteration code and a hex encoded credential, each separated by + $
  • +
+ +

If the stored password form does not include an iteration count then an + iteration count of 1 is used.

+ +

If the stored password form does not include salt then no salt is + used.

+ +
+ Attribute + + Description +
algorithm +

The name of the secret key algorithm used to encode user passwords + stored in the database. If not specified, a default of + PBKDF2WithHmacSHA1 is used.

+
keyLength +

The length of key to generate for the stored credential. If not + specified, a default of 160 is used.

+
iterations +

The number of iterations to use when creating a new stored credential + from a clear text credential.

+
saltLength +

The length of the randomly generated salt to use when creating a + new stored credential from a clear text credential.

+
+ +
+ +

Nested Components

+ +

If you are using the NestedCredentialHandler Implementation or a + CredentialHandler that extends the NestedCredentialHandler one or more + <CredentialHandler> elements may be nested inside it. +

+ +

Special Features

+ +

No special features are associated with a + CredentialHandler element.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/engine.html b/test.dockerapp/tomcat/webapps/docs/config/engine.html new file mode 100644 index 0000000..fae7e0c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/engine.html @@ -0,0 +1,259 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Engine Container

The Engine Container

Table of Contents

Introduction

+ +

The Engine element represents the entire request + processing machinery associated with a particular Catalina + Service. It receives and processes + all requests from one or more Connectors, + and returns the completed response to the Connector for ultimate + transmission back to the client.

+ +

Exactly one Engine element MUST be nested inside + a Service element, following all of the + corresponding Connector elements associated with this Service.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Engine + support the following attributes:

+ +
+ Attribute + + Description +
backgroundProcessorDelay +

This value represents the delay in seconds between the + invocation of the backgroundProcess method on this engine and + its child containers, including all hosts and contexts. + Child containers will not be invoked if their delay value is not + negative (which would mean they are using their own processing + thread). Setting this to a positive value will cause + a thread to be spawn. After waiting the specified amount of time, + the thread will invoke the backgroundProcess method on this engine + and all its child containers. If not specified, the default value for + this attribute is 10, which represent a 10 seconds delay.

+
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Engine interface. + If not specified, the standard value (defined below) will be used.

+
defaultHost +

The default host name, which identifies the + Host that will process requests directed + to host names on this server, but which are not configured in + this configuration file. This name MUST match the name + attributes of one of the Host elements + nested immediately inside.

+
jvmRoute +

Identifier which must be used in load balancing scenarios to enable + session affinity. The identifier, which must be unique across all + Tomcat servers which participate in the cluster, will be appended to + the generated session identifier, therefore allowing the front end + proxy to always forward a particular session to the same Tomcat + instance.

+

+ Note that the jvmRoute can also be set using the + jvmRoute system property. The jvmRoute + set in an <Engine> attribute will override + any jvmRoute system property. +

+
name +

Logical name of this Engine, used in log and error messages. When + using multiple Service elements in the same + Server, each Engine MUST be assigned a unique + name.

+
startStopThreads +

The number of threads this Engine will use to start + child Host elements in parallel. The special + value of 0 will result in the value of + Runtime.getRuntime().availableProcessors() being used. + Negative values will result in + Runtime.getRuntime().availableProcessors() + value being + used unless this is less than 1 in which case 1 thread will be used. If + not specified, the default value of 1 will be used.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of Engine is + org.apache.catalina.core.StandardEngine. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
+ +
+ + +

Nested Components

+ +

You can nest one or more Host elements inside + this Engine element, each representing a different virtual + host associated with this server. At least one Host + is required, and one of the nested Hosts MUST + have a name that matches the name specified for the + defaultHost attribute, listed above.

+ +

You can nest at most one instance of the following utility components + by nesting a corresponding element inside your Engine + element:

+
    +
  • Realm - + Configure a realm that will allow its + database of users, and their associated roles, to be shared across all + Hosts and Contexts + nested inside this Engine, unless overridden by a + Realm configuration at a lower level.
  • +
+ +

Special Features

+ + +

Logging

+ +

An engine is associated with the + org.apache.catalina.core.ContainerBase.[enginename] + log category. Note that the brackets are actually part of the name, + don't omit them.

+ +
+ + +

Access Logs

+ +

When you run a web server, one of the output files normally generated + is an access log, which generates one line of information for + each request processed by the server, in a standard format. Catalina + includes an optional Valve implementation that + can create access logs in the same standard format created by web servers, + or in any number of custom formats.

+ +

You can ask Catalina to create an access log for all requests + processed by an Engine, + Host, or Context + by nesting a Valve element like this:

+ +
<Engine name="Standalone" ...>
+  ...
+  <Valve className="org.apache.catalina.valves.AccessLogValve"
+         prefix="catalina_access_log" suffix=".txt"
+         pattern="common"/>
+  ...
+</Engine>
+ +

See Access Logging Valves + for more information on the configuration attributes that are + supported.

+ +
+ + +

Lifecycle Listeners

+ +

If you have implemented a Java object that needs to know when this + Engine is started or stopped, you can declare it by + nesting a Listener element inside this element. The + class name you specify must implement the + org.apache.catalina.LifecycleListener interface, and + it will be notified about the occurrence of the corresponding + lifecycle events. Configuration of such a listener looks like this:

+ +
<Engine name="Standalone" ...>
+  ...
+  <Listener className="com.mycompany.mypackage.MyListener" ... >
+  ...
+</Engine>
+ +

Note that a Listener can have any number of additional properties + that may be configured from this element. Attribute names are matched + to corresponding JavaBean property names using the standard property + method naming patterns.

+ +
+ + +

Request Filters

+ +

You can ask Catalina to check the IP address, or host name, on every + incoming request directed to the surrounding + Engine, Host, or + Context element. The remote address or name + will be checked against configured "accept" and/or "deny" + filters, which are defined using java.util.regex Regular + Expression syntax. Requests that come from locations that are + not accepted will be rejected with an HTTP "Forbidden" error. + Example filter declarations:

+ +
<Engine name="Standalone" ...>
+  ...
+  <Valve className="org.apache.catalina.valves.RemoteHostValve"
+         allow=".*\.mycompany\.com|www\.yourcompany\.com"/>
+  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
+         deny="192\.168\.1\.\d+"/>
+  ...
+</Engine>
+ +

See Remote Address Filter + and Remote Host Filter for + more information about the configuration options that are supported.

+ +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/executor.html b/test.dockerapp/tomcat/webapps/docs/config/executor.html new file mode 100644 index 0000000..9614a8b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/executor.html @@ -0,0 +1,127 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Executor (thread pool)

The Executor (thread pool)

Table of Contents

Introduction

+ +

The Executor represents a thread pool that can be shared + between components in Tomcat. Historically there has been a thread pool per + connector created but this allows you to share a thread pool, between (primarily) connector + but also other components when those get configured to support executors

+ + +

The executor has to implement the org.apache.catalina.Executor interface.

+ +

The executor is a nested element to the Service element. + And in order for it to be picked up by the connectors, the Executor element has to appear + prior to the Connector element in server.xml

+

Attributes

+ +

Common Attributes

+ +

All implementations of Executor + support the following attributes:

+ +
+ Attribute + + Description +
className +

The class of the implementation. The implementation has to implement the + org.apache.catalina.Executor interface. + This interface ensures that the object can be referenced through its name attribute + and that implements Lifecycle, so that it can be started and stopped with the container. + The default value for the className is org.apache.catalina.core.StandardThreadExecutor

+
name +

The name used to reference this pool in other places in server.xml. + The name is required and must be unique.

+
+ +
+ +

Standard Implementation

+ +

+ The default implementation supports the following attributes:

+ +
+ Attribute + + Description +
threadPriority +

(int) The thread priority for threads in the executor, the default is + 5 (the value of the Thread.NORM_PRIORITY constant)

+
daemon +

(boolean) Whether the threads should be daemon threads or not, the default is true

+
namePrefix +

(String) The name prefix for each thread created by the executor. + The thread name for an individual thread will be namePrefix+threadNumber

+
maxThreads +

(int) The max number of active threads in this pool, default is 200

+
minSpareThreads +

(int) The minimum number of threads (idle and active) always kept alive, default is 25

+
maxIdleTime +

(int) The number of milliseconds before an idle thread shutsdown, unless the number of active threads are less + or equal to minSpareThreads. Default value is 60000(1 minute)

+
maxQueueSize +

(int) The maximum number of runnable tasks that can queue up awaiting + execution before we reject them. Default value is Integer.MAX_VALUE

+
prestartminSpareThreads +

(boolean) Whether minSpareThreads should be started when starting the Executor or not, + the default is false

+
threadRenewalDelay +

(long) If a ThreadLocalLeakPreventionListener is configured, + it will notify this executor about stopped contexts. + After a context is stopped, threads in the pool are renewed. To avoid renewing all threads at the same time, + this option sets a delay between renewal of any 2 threads. The value is in ms, + default value is 1000 ms. If value is negative, threads are not renewed.

+
+ + +
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/filter.html b/test.dockerapp/tomcat/webapps/docs/config/filter.html new file mode 100644 index 0000000..d7c8696 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/filter.html @@ -0,0 +1,1633 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - Container Provided Filters

Container Provided Filters

Table of Contents

+ +

Introduction

+ +

Tomcat provides a number of Filters which may be + configured for use with all web applications using + $CATALINA_BASE/conf/web.xml or may be configured for individual + web applications by configuring them in the application's + WEB-INF/web.xml. Each filter is described below.

+ +

This description uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

Add Default Character Set Filter

+ +

Introduction

+ +

The HTTP specification is clear that if no character set is specified for + media sub-types of the "text" media type, the ISO-8859-1 character set must + be used. However, browsers may attempt to auto-detect the character set. + This may be exploited by an attacker to perform an XSS attack. Internet + Explorer and other browsers have an option to + enable this behavior.

+ +

This filter prevents the attack by explicitly setting a character set. + Unless the provided character set is explicitly overridden by the user the + browser will adhere to the explicitly set character set, thus preventing the + XSS attack.

+ +
+ +

Filter Class Name

+ +

The filter class name for the Add Default Character Set Filter is + org.apache.catalina.filters.AddDefaultCharsetFilter + .

+ +
+ +

Initialisation parameters

+ +

The Add Default Character Set Filter supports the following initialization + parameters:

+ +
+ Attribute + + Description +
encoding +

Name of the character set which should be set, if no other character set + was set explicitly by a Servlet. This parameter has two special values + default and system. A value of system + uses the JVM wide default character set, which is usually set by locale. + A value of default will use ISO-8859-1.

+
+ +
+ +

CORS Filter

+

Introduction

+

This filter is an implementation of W3C's CORS (Cross-Origin Resource + Sharing) specification, which is a + mechanism that enables cross-origin requests.

+

The filter works by adding required Access-Control-* headers + to HttpServletResponse object. The filter also protects against HTTP + response splitting. If request is invalid, or is not permitted, then request + is rejected with HTTP status code 403 (Forbidden). A + flowchart that + demonstrates request processing by this filter is available.

+

The minimal configuration required to use this filter is:

+
<filter>
+  <filter-name>CorsFilter</filter-name>
+  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
+</filter>
+<filter-mapping>
+  <filter-name>CorsFilter</filter-name>
+  <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+

Filter Class Name

+

The filter class name for the CORS Filter is + org.apache.catalina.filters.CorsFilter.

+
+

Initialisation parameters

+

The CORS Filter supports following initialisation parameters:

+
+ Attribute + + Description +
cors.allowed.origins +

A list of origins + that are allowed to access the resource. A * can be + specified to enable access to resource from any origin. Otherwise, a + whitelist of comma separated origins can be provided. Eg: + https://www.w3.org, https://www.apache.org. + Defaults: The empty String. (No origin is allowed to + access the resource).

+
cors.allowed.methods +

A comma separated list of HTTP methods that can be used to access the + resource, using cross-origin requests. These are the methods which will + also be included as part of Access-Control-Allow-Methods + header in pre-flight response. Eg: GET, POST. + Defaults: GET, POST, HEAD, OPTIONS

+
cors.allowed.headers +

A comma separated list of request headers that can be used when + making an actual request. These headers will also be returned as part + of Access-Control-Allow-Headers header in a pre-flight + response. Eg: Origin,Accept. Defaults: + Origin, Accept, X-Requested-With, Content-Type, + Access-Control-Request-Method, Access-Control-Request-Headers

+
cors.exposed.headers +

A comma separated list of headers other than simple response headers + that browsers are allowed to access. These are the headers which will + also be included as part of Access-Control-Expose-Headers + header in the pre-flight response. Eg: + X-CUSTOM-HEADER-PING,X-CUSTOM-HEADER-PONG. + Default: None. Non-simple headers are not exposed by + default.

+
cors.preflight.maxage +

The amount of seconds, browser is allowed to cache the result of the + pre-flight request. This will be included as part of + Access-Control-Max-Age header in the pre-flight response. + A negative value will prevent CORS Filter from adding this response + header to pre-flight response. Defaults: + 1800

+
cors.support.credentials +

A flag that indicates whether the resource supports user credentials. + This flag is exposed as part of + Access-Control-Allow-Credentials header in a pre-flight + response. It helps browser determine whether or not an actual request + can be made using credentials. Defaults: + false

+
cors.request.decorate +

A flag to control if CORS specific attributes should be added to + HttpServletRequest object or not. Defaults: + true

+
+

Here's an example of a more advanced configuration, that overrides + defaults:

+
<filter>
+  <filter-name>CorsFilter</filter-name>
+  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
+  <init-param>
+    <param-name>cors.allowed.origins</param-name>
+    <param-value>*</param-value>
+  </init-param>
+  <init-param>
+    <param-name>cors.allowed.methods</param-name>
+    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
+  </init-param>
+  <init-param>
+    <param-name>cors.allowed.headers</param-name>
+    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
+  </init-param>
+  <init-param>
+    <param-name>cors.exposed.headers</param-name>
+    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
+  </init-param>
+  <init-param>
+    <param-name>cors.support.credentials</param-name>
+    <param-value>true</param-value>
+  </init-param>
+  <init-param>
+    <param-name>cors.preflight.maxage</param-name>
+    <param-value>10</param-value>
+  </init-param>
+</filter>
+<filter-mapping>
+  <filter-name>CorsFilter</filter-name>
+  <url-pattern>/*</url-pattern>
+</filter-mapping>
+
+

CORS Filter and HttpServletRequest attributes

+

CORS Filter adds information about the request, in HttpServletRequest + object, for consumption downstream. Following attributes are set, if + cors.request.decorate initialisation parameter is + true:

+
    +
  • cors.isCorsRequest: Flag to determine if request is + a CORS request.
  • +
  • cors.request.origin: The Origin URL, i.e. the URL of + the page from where the request originated.
  • +
  • cors.request.type: Type of CORS request. Possible + values: +
      +
    • SIMPLE: A request which is not preceded by a + pre-flight request.
    • +
    • ACTUAL: A request which is preceded by a pre-flight + request.
    • +
    • PRE_FLIGHT: A pre-flight request.
    • +
    • NOT_CORS: A normal same-origin request.
    • +
    • INVALID_CORS: A cross-origin request, which is + invalid.
    • +
    +
  • +
  • cors.request.headers: Request headers sent as + Access-Control-Request-Headers header, for a pre-flight + request. +
  • +
+
+

CSRF Prevention Filter

+ +

Introduction

+ +

This filter provides basic CSRF protection for a web application. The + filter assumes that it is mapped to /* and that all URLs + returned to the client are encoded via a call to + HttpServletResponse#encodeRedirectURL(String) or + HttpServletResponse#encodeURL(String).

+ +

This filter prevents CSRF by generating a nonce and storing it in the + session. URLs are also encoded with the same nonce. When the next request is + received the nonce in the request is compared to the nonce in the session + and only if they are the same is the request allowed to continue.

+ +
+ +

Filter Class Name

+ +

The filter class name for the CSRF Prevention Filter is + org.apache.catalina.filters.CsrfPreventionFilter + .

+ +
+ +

Initialisation parameters

+ +

The CSRF Prevention Filter supports the following initialisation + parameters:

+ +
+ Attribute + + Description +
denyStatus +

HTTP response status code that is used when rejecting denied + request. The default value is 403.

+
entryPoints +

A comma separated list of URLs that will not be tested for the + presence of a valid nonce. They are used to provide a way to navigate + back to a protected application after having navigated away from it. + Entry points will be limited to HTTP GET requests and should not trigger + any security sensitive actions.

+
nonceCacheSize +

The number of previously issued nonces that will be cached on a LRU + basis to support parallel requests, limited use of the refresh and back + in the browser and similar behaviors that may result in the submission + of a previous nonce rather than the current one. If not set, the default + value of 5 will be used.

+
randomClass +

The name of the class to use to generate nonces. The class must be an + instance of java.util.Random. If not set, the default value + of java.security.SecureRandom will be used.

+
+ +
+ +

CSRF Prevention Filter for REST APIs

+ +

Introduction

+ +

This filter provides basic CSRF protection for REST APIs. The CSRF + protection is applied only for modifying HTTP requests (different from GET, + HEAD, OPTIONS) to protected resources. It is based on a custom header + X-CSRF-Token that provides a valid nonce.

+ +

CSRF protection mechanism for REST APIs consists of the following steps: +

    +
  • Client asks for a valid nonce. This is performed with a + non-modifying "Fetch" request to protected resource.
  • +
  • Server responds with a valid nonce mapped to the current user + session.
  • +
  • Client provides this nonce in the subsequent modifying requests in + the frame of the same user session.
  • +
  • Server rejects all modifying requests to protected resources that + do not contain a valid nonce.
  • +
+

+ +
+ +

Basic configuration sample

+ +

On the server side

+ +
    +
  • All CSRF protected REST APIs should be protected with an authentication + mechanism.
  • +
  • Protect modifying REST APIs with this filter.
  • +
  • Provide at least one non-modifying operation.
  • +
+
<filter>
+  <filter-name>RestCSRF</filter-name>
+  <filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
+</filter>
+<filter-mapping>
+  <filter-name>RestCSRF</filter-name>
+  <!-- Modifying operations -->
+  <url-pattern>/resources/removeResource</url-pattern>
+  <url-pattern>/resources/addResource</url-pattern>
+  <!-- Non-modifying operations -->
+  <url-pattern>/resources/listResources</url-pattern>
+</filter-mapping>
+ +

On the client side

+ +
    +
  • Make a non-modifying "Fetch" request in order to obtain a valid nonce. + This can be done with sending additional header + X-CSRF-Token: Fetch
  • +
  • Cache the returned session id and nonce in order to provide them in + the subsequent modifying requests to protected resources.
  • +
  • Modifying requests can be denied and header + X-CSRF-Token: Required will be returned in case of + invalid or missing nonce, expired session or in case the session + id is changed by the server.
  • +
+
Client Request:
+GET /rest/resources/listResources HTTP/1.1
+X-CSRF-Token: Fetch
+Authorization: Basic ...
+Host: localhost:8080
+...
+
+Server Response:
+HTTP/1.1 200 OK
+Set-Cookie: JSESSIONID=...; Path=/rest; HttpOnly
+X-CSRF-Token: ...
+...
+
+Client Request:
+POST /rest/resources/addResource HTTP/1.1
+Cookie: JSESSIONID=...
+X-CSRF-Token: ...
+Authorization: Basic ...
+Host: localhost:8080
+...
+
+Server Response:
+HTTP/1.1 200 OK
+...
+ +
+ +

RestCsrfPreventionFilter and HttpServletRequest parameters

+ +

When the client is not able to insert custom headers in its calls to + REST APIs there is additional capability to configure URLs for which a + valid nonce will be accepted as a request parameter.

+ +

Note: If there is a X-CSRF-Token header, it will be taken + with preference over any parameter with the same name in the request. + Request parameters cannot be used to fetch new nonce, only header can be + used to request a new nonce.

+ +
<filter>
+  <filter-name>RestCSRF</filter-name>
+  <filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
+  <init-param>
+    <param-name>pathsAcceptingParams</param-name>
+    <param-value>/resources/removeResource,/resources/addResource</param-value>
+  </init-param>
+</filter>
+<filter-mapping>
+  <filter-name>RestCSRF</filter-name>
+  <url-pattern>/resources/*</url-pattern>
+</filter-mapping>
+ +
+ +

Filter Class Name

+ +

The filter class name for the CSRF Prevention Filter for REST APIs is + org.apache.catalina.filters.RestCsrfPreventionFilter + .

+ +
+ +

Initialisation parameters

+ +

The CSRF Prevention Filter for REST APIs supports the following + initialisation parameters:

+ +
+ Attribute + + Description +
denyStatus +

HTTP response status code that is used when rejecting denied + request. The default value is 403.

+
pathsAcceptingParams +

A comma separated list of URLs that can accept nonces via request + parameter X-CSRF-Token. For use cases when a nonce information cannot + be provided via header, one can provide it via request parameters. If + there is a X-CSRF-Token header, it will be taken with preference over + any parameter with the same name in the request. Request parameters + cannot be used to fetch new nonce, only header can be used to request a + new nonce.

+
randomClass +

The name of the class to use to generate nonces. The class must be an + instance of java.util.Random. If not set, the default value + of java.security.SecureRandom will be used.

+
+ +
+ +

Expires Filter

+ +

Introduction

+ +

+ ExpiresFilter is a Java Servlet API port of Apache + mod_expires. + This filter controls the setting of the Expires HTTP header and the + max-age directive of the Cache-Control HTTP header in + server responses. The expiration date can set to be relative to either the + time the source file was last modified, or to the time of the client access. +

+ +

+ These HTTP headers are an instruction to the client about the document's + validity and persistence. If cached, the document may be fetched from the + cache rather than from the source until this time has passed. After that, the + cache copy is considered "expired" and invalid, and a new copy must + be obtained from the source. +

+

+ To modify Cache-Control directives other than max-age (see + RFC + 2616 section 14.9), you can use other servlet filters or Apache Httpd + mod_headers module. +

+ +
+ +

Basic configuration sample

+

+ Basic configuration to add 'Expires' and 'Cache-Control: max-age=' + headers to images, css and javascript. +

+ +
<filter>
+ <filter-name>ExpiresFilter</filter-name>
+ <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
+ <init-param>
+    <param-name>ExpiresByType image</param-name>
+    <param-value>access plus 10 minutes</param-value>
+ </init-param>
+ <init-param>
+    <param-name>ExpiresByType text/css</param-name>
+    <param-value>access plus 10 minutes</param-value>
+ </init-param>
+ <init-param>
+    <param-name>ExpiresByType application/javascript</param-name>
+    <param-value>access plus 10 minutes</param-value>
+ </init-param>
+</filter>
+...
+<filter-mapping>
+ <filter-name>ExpiresFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+</filter-mapping>
+ +
+ +

Alternate Syntax

+

+ The ExpiresDefault and ExpiresByType directives can also be + defined in a more readable syntax of the form: +

+ +
<init-param>
+ <param-name>ExpiresDefault</param-name>
+ <param-value><base> [plus] {<num> <type>}*</param-value>
+</init-param>
+
+<init-param>
+ <param-name>ExpiresByType type</param-name>
+ <param-value><base> [plus] {<num> <type>}*</param-value>
+</init-param>
+
+<init-param>
+ <param-name>ExpiresByType type;encoding</param-name>
+ <param-value><base> [plus] {<num> <type>}*</param-value>
+</init-param>
+

+ where <base> is one of: +

+
    +
  • access
  • +
  • now (equivalent to 'access')
  • +
  • modification
  • +
+ +

+ The plus keyword is optional. <num> should be an + integer value (acceptable to Integer.parseInt()), and + <type> is one of: +

+
    +
  • year, years
  • +
  • month, months
  • +
  • week, weeks
  • +
  • day, days
  • +
  • hour, hours
  • +
  • minute, minutes
  • +
  • second, seconds
  • +
+

+ For example, any of the following directives can be used to make documents + expire 1 month after being accessed, by default: +

+ +
<init-param>
+ <param-name>ExpiresDefault</param-name>
+ <param-value>access plus 1 month</param-value>
+</init-param>
+
+<init-param>
+ <param-name>ExpiresDefault</param-name>
+ <param-value>access plus 4 weeks</param-value>
+</init-param>
+
+<init-param>
+ <param-name>ExpiresDefault</param-name>
+ <param-value>access plus 30 days</param-value>
+</init-param>
+

+The expiry time can be fine-tuned by adding several +'<num> <type>' clauses: +

+ +
<init-param>
+ <param-name>ExpiresByType text/html</param-name>
+ <param-value>access plus 1 month 15 days 2 hours</param-value>
+</init-param>
+
+<init-param>
+ <param-name>ExpiresByType image/gif</param-name>
+ <param-value>modification plus 5 hours 3 minutes</param-value>
+</init-param>
+

+ Note that if you use a modification date based setting, the Expires + header will not be added to content that does not come from + a file on disk. This is due to the fact that there is no modification time + for such content. +

+
+ +

Expiration headers generation eligibility

+

+ A response is eligible to be enriched by ExpiresFilter if : +

+
    +
  1. no expiration header is defined (Expires header or the + max-age directive of the Cache-Control header),
  2. +
  3. the response status code is not excluded by the directive + ExpiresExcludedResponseStatusCodes,
  4. +
  5. the Content-Type of the response matches one of the types + defined the in ExpiresByType directives or the + ExpiresDefault directive is defined.
  6. +
+ +

+ Note : If Cache-Control header contains other directives than + max-age, they are concatenated with the max-age directive + that is added by the ExpiresFilter. +

+ +
+ +

Expiration configuration selection

+

+ The expiration configuration if elected according to the following algorithm: +

+
    +
  1. ExpiresByType matching the exact content-type returned by + HttpServletResponse.getContentType() possibly including the charset + (e.g. 'text/xml;charset=UTF-8'),
  2. +
  3. ExpiresByType matching the content-type without the charset if + HttpServletResponse.getContentType() contains a charset (e.g. + 'text/xml;charset=UTF-8' -> 'text/xml'),
  4. +
  5. ExpiresByType matching the major type (e.g. substring before + '/') of HttpServletResponse.getContentType() + (e.g. 'text/xml;charset=UTF-8' -> 'text'),
  6. +
  7. ExpiresDefault
  8. +
+ +
+ +

Filter Class Name

+ +

The filter class name for the Expires Filter is + org.apache.catalina.filters.ExpiresFilter + .

+ +
+ +

Initialisation parameters

+ +

The Expires Filter supports the following + initialisation parameters:

+ +
+ Attribute + + Description +
ExpiresExcludedResponseStatusCodes +

+ This directive defines the http response status codes for which the + ExpiresFilter will not generate expiration headers. By default, the + 304 status code ("Not modified") is skipped. The + value is a comma separated list of http status codes. +

+

+ This directive is useful to ease usage of ExpiresDefault directive. + Indeed, the behavior of 304 Not modified (which does specify a + Content-Type header) combined with Expires and + Cache-Control:max-age= headers can be unnecessarily tricky to + understand. +

+

See sample below the table

+
ExpiresByType <content-type> +

+ This directive defines the value of the Expires header and the + max-age directive of the Cache-Control header generated for + documents of the specified type (e.g., text/html). The second + argument sets the number of seconds that will be added to a base time to + construct the expiration date. The Cache-Control: max-age is + calculated by subtracting the request time from the expiration date and + expressing the result in seconds. +

+

+ The base time is either the last modification time of the file, or the time + of the client's access to the document. Which should be used is + specified by the <code> field; M means that the + file's last modification time should be used as the base time, and + A means the client's access time should be used. The duration + is expressed in seconds. A2592000 stands for + access plus 30 days in alternate syntax. +

+

+ The difference in effect is subtle. If M (modification in + alternate syntax) is used, all current copies of the document in all caches + will expire at the same time, which can be good for something like a weekly + notice that's always found at the same URL. If A ( + access or now in alternate syntax) is used, the date of + expiration is different for each client; this can be good for image files + that don't change very often, particularly for a set of related + documents that all refer to the same images (i.e., the images will be + accessed repeatedly within a relatively short timespan). +

+

+ Note: When the content type includes a charset (e.g. + 'ExpiresByType text/xml;charset=utf-8'), Tomcat removes blank chars + between the ';' and the 'charset' keyword. Due to this, + configuration of an expiration with a charset must not include + such a space character. +

+

See sample below the table

+

+ It overrides, for the specified MIME type only, any + expiration date set by the ExpiresDefault directive. +

+

+ You can also specify the expiration time calculation using an alternate + syntax, described earlier in this document. +

+
ExpiresDefault +

+ This directive sets the default algorithm for calculating the + expiration time for all documents in the affected realm. It can be + overridden on a type-by-type basis by the ExpiresByType directive. See the + description of that directive for details about the syntax of the + argument, and the "alternate syntax" + description as well. +

+
+ +

Sample: exclude response status codes 302, 500 and 503

+ +
<init-param>
+ <param-name>ExpiresExcludedResponseStatusCodes</param-name>
+ <param-value>302, 500, 503</param-value>
+</init-param>
+ +

Sample for ExpiresByType initialization parameter

+ +
<init-param>
+   <param-name>ExpiresByType text/html</param-name>
+   <param-value>access plus 1 month 15   days 2 hours</param-value>
+</init-param>
+
+<init-param>
+   <!-- 2592000 seconds = 30 days -->
+   <param-name>ExpiresByType image/gif</param-name>
+   <param-value>A2592000</param-value>
+</init-param>
+ +
+ +

Troubleshooting

+

+ To troubleshoot, enable logging on the + org.apache.catalina.filters.ExpiresFilter. +

+

+ Extract of logging.properties +

+ +
org.apache.catalina.filters.ExpiresFilter.level = FINE    
+

+ Sample of initialization log message: +

+ +
Mar 26, 2010 2:01:41 PM org.apache.catalina.filters.ExpiresFilter init
+FINE: Filter initialized with configuration ExpiresFilter[
+ excludedResponseStatusCode=[304],
+ default=null,
+ byType={
+    image=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]],
+    text/css=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]],
+    text/javascript=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]]}]
+

+ Sample of per-request log message where ExpiresFilter adds an + expiration date is below. The message is on one line and is wrapped here + for better readability. +

+ +
Mar 26, 2010 2:09:47 PM org.apache.catalina.filters.ExpiresFilter onBeforeWriteResponseBody
+FINE: Request "/tomcat.gif" with response status "200"
+ content-type "image/gif", set expiration date 3/26/10 2:19 PM
+

+ Sample of per-request log message where ExpiresFilter does not add + an expiration date: +

+ +
Mar 26, 2010 2:10:27 PM org.apache.catalina.filters.ExpiresFilter onBeforeWriteResponseBody
+FINE: Request "/docs/config/manager.html" with response status "200"
+ content-type "text/html", no expiration configured
+
+ +

Failed Request Filter

+ +

Introduction

+ +

This filter triggers parameters parsing in a request and rejects the + request if some parameters were skipped during parameter parsing because + of parsing errors or request size limitations (such as + maxParameterCount attribute in a + Connector). + This filter can be used to ensure that none parameter values submitted by + client are lost.

+ +

Note that parameter parsing may consume the body of an HTTP request, so + caution is needed if the servlet protected by this filter uses + request.getInputStream() or request.getReader() + calls. In general the risk of breaking a web application by adding this + filter is not so high, because parameter parsing does check content type + of the request before consuming the request body.

+ +

Note, that for the POST requests to be parsed correctly, a + SetCharacterEncodingFilter filter must be configured above + this one. See CharacterEncoding page in the FAQ for details.

+ +

The request is rejected with HTTP status code 400 (Bad Request).

+ +
+ +

Filter Class Name

+ +

The filter class name for the Failed Request Filter is + org.apache.catalina.filters.FailedRequestFilter + .

+ +
+ +

Initialisation parameters

+ +

The Failed Request Filter does not support any initialization parameters.

+ +
+ +

HTTP Header Security Filter

+ +

Introduction

+ +

There are a number of HTTP headers that can be added to the response to + improve the security of the connection. This filter provides a mechanism for + adding those headers. Note that security related headers with more complex + requirements, like CORS, are implemented as separate Filters.

+ +
+ +

Filter Class Name

+ +

The filter class name for the HTTP Header Security Filter is + org.apache.catalina.filters.HttpHeaderSecurityFilter + .

+ +
+ +

Initialisation parameters

+ +

The HTTP Header Security Filter supports the following initialization + parameters:

+ +
+ Attribute + + Description +
hstsEnabled +

Will an HTTP Strict Transport Security (HSTS) header + (Strict-Transport-Security) be set on the response for + secure requests. Any HSTS header already present will be replaced. See + RFC 6797 for further + details of HSTS. If not specified, the default value of + true will be used.

+
hstsMaxAgeSeconds +

The max age value that should be used in the HSTS header. Negative + values will be treated as zero. If not specified, the default value of + 0 will be used.

+
hstsIncludeSubDomains +

Should the includeSubDomains parameter be included in the HSTS + header. If not specified, the default value of false will + be used.

+
hstsPreload +

Should the preload parameter be included in the HSTS header. If not + specified, the default value of false will be used. See + https://hstspreload.org for + important information about this parameter.

+
antiClickJackingEnabled +

Should the anti click-jacking header (X-Frame-Options) + be set on the response. Any anti click-jacking header already present + will be replaced. If not specified, the default value of + true will be used.

+
antiClickJackingOption +

What value should be used for the anticlick-jacking header? Must be + one of DENY, SAMEORIGIN, + ALLOW-FROM (case-insensitive). If not specified, the + default value of DENY will be used.

+
antiClickJackingUri +

If ALLOW-FROM is used for antiClickJackingOption, + what URI should be allowed? If not specified, the default value of an + empty string will be used.

+
blockContentTypeSniffingEnabled +

Should the header that blocks content type sniffing + (X-Content-Type-Options) be set on every response. If + already present, the header will be replaced. If not specified, the + default value of true will be used.

+
xssProtectionEnabled +

Should the header that enables the browser's cross-site scripting + filter protection (X-XSS-Protection: 1; mode=block) + be set on every response. If already present, the header + will be replaced. If not specified, the default value of + true will be used.

+
+ +
+ +

Remote Address Filter

+ +

Introduction

+ +

The Remote Address Filter allows you to compare the + IP address of the client that submitted this request against one or more + regular expressions, and either allow the request to continue + or refuse to process the request from this client.

+ +

The syntax for regular expressions is different than that for + 'standard' wildcard matching. Tomcat uses the java.util.regex + package. Please consult the Java documentation for details of the + expressions supported.

+ +

Note: There is a caveat when using this filter with + IPv6 addresses. Format of the IP address that this valve is processing + depends on the API that was used to obtain it. If the address was obtained + from Java socket using Inet6Address class, its format will be + x:x:x:x:x:x:x:x. That is, the IP address for localhost + will be 0:0:0:0:0:0:0:1 instead of the more widely used + ::1. Consult your access logs for the actual value.

+ +

See also: Remote Host Filter.

+
+ +

Filter Class Name

+ +

The filter class name for the Remote Address Filter is + org.apache.catalina.filters.RemoteAddrFilter + .

+ +
+ +

Initialisation parameters

+ +

The Remote Address Filter supports the following + initialisation parameters:

+ +
+ Attribute + + Description +
allow +

A regular expression (using java.util.regex) that the + remote client's IP address is compared to. If this attribute + is specified, the remote address MUST match for this request to be + accepted. If this attribute is not specified, all requests will be + accepted UNLESS the remote address matches a deny + pattern.

+
deny +

A regular expression (using java.util.regex) that the + remote client's IP address is compared to. If this attribute + is specified, the remote address MUST NOT match for this request to be + accepted. If this attribute is not specified, request acceptance is + governed solely by the accept attribute.

+
denyStatus +

HTTP response status code that is used when rejecting denied + request. The default value is 403. For example, + it can be set to the value 404.

+
+ +
+ +

Example

+

To allow access only for the clients connecting from localhost:

+
    <filter>
+      <filter-name>Remote Address Filter</filter-name>
+      <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class>
+      <init-param>
+        <param-name>allow</param-name>
+        <param-value>127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1</param-value>
+      </init-param>
+    </filter>
+    <filter-mapping>
+      <filter-name>Remote Address Filter</filter-name>
+      <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+ +

Remote Host Filter

+ +

Introduction

+ +

The Remote Host Filter allows you to compare the + hostname of the client that submitted this request against one or more + regular expressions, and either allow the request to continue + or refuse to process the request from this client.

+ +

The syntax for regular expressions is different than that for + 'standard' wildcard matching. Tomcat uses the java.util.regex + package. Please consult the Java documentation for details of the + expressions supported.

+ +

Note: This filter processes the value returned by + method ServletRequest.getRemoteHost(). To allow the method + to return proper host names, you have to enable "DNS lookups" feature on + a Connector.

+ +

See also: Remote Address Filter, + HTTP Connector configuration.

+
+ +

Filter Class Name

+ +

The filter class name for the Remote Address Filter is + org.apache.catalina.filters.RemoteHostFilter + .

+ +
+ +

Initialisation parameters

+ +

The Remote Host Filter supports the following + initialisation parameters:

+ +
+ Attribute + + Description +
allow +

A regular expression (using java.util.regex) that the + remote client's hostname is compared to. If this attribute + is specified, the remote hostname MUST match for this request to be + accepted. If this attribute is not specified, all requests will be + accepted UNLESS the remote hostname matches a deny + pattern.

+
deny +

A regular expression (using java.util.regex) that the + remote client's hostname is compared to. If this attribute + is specified, the remote hostname MUST NOT match for this request to be + accepted. If this attribute is not specified, request acceptance is + governed solely by the accept attribute.

+
denyStatus +

HTTP response status code that is used when rejecting denied + request. The default value is 403. For example, + it can be set to the value 404.

+
+ +
+ +

Remote IP Filter

+ +

Introduction

+ +

Tomcat port of + mod_remoteip, + this filter replaces the apparent client remote IP address and hostname for + the request with the IP address list presented by a proxy or a load balancer + via a request headers (e.g. "X-Forwarded-For").

+ +

Another feature of this filter is to replace the apparent scheme + (http/https), server port and request.secure with the scheme presented + by a proxy or a load balancer via a request header + (e.g. "X-Forwarded-Proto").

+ +

If used in conjunction with Remote Address/Host filters then this filter + should be defined first to ensure that the correct client IP address is + presented to the Remote Address/Host filters.

+ +

Note: By default this filter has no effect on the + values that are written into access log. The original values are restored + when request processing leaves the filter and that always happens earlier + than access logging. To pass the remote address, remote host, server port + and protocol values set by this filter to the access log, + they are put into request attributes. Publishing these values here + is enabled by default, but AccessLogValve should be explicitly + configured to use them. See documentation for + requestAttributesEnabled attribute of + AccessLogValve.

+ +

The names of request attributes that are set by this filter + and can be used by access logging are the following:

+ +
    +
  • org.apache.catalina.AccessLog.RemoteAddr
  • +
  • org.apache.catalina.AccessLog.RemoteHost
  • +
  • org.apache.catalina.AccessLog.Protocol
  • +
  • org.apache.catalina.AccessLog.ServerPort
  • +
  • org.apache.tomcat.remoteAddr
  • +
+ +
+ +

Filter Class Name

+ +

The filter class name for the Remote IP Filter is + org.apache.catalina.filters.RemoteIpFilter + .

+ +
+ +

Basic configuration to handle 'x-forwarded-for'

+

+ The filter will process the x-forwarded-for http header. +

+
      <filter>
+        <filter-name>RemoteIpFilter</filter-name>
+        <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
+      </filter>
+
+      <filter-mapping>
+        <filter-name>RemoteIpFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+      </filter-mapping>
+
+ +

Basic configuration to handle 'x-forwarded-for' and 'x-forwarded-proto'

+ +

+ The filter will process x-forwarded-for and + x-forwarded-proto http headers. Expected value for the + x-forwarded-proto header in case of SSL connections is + https (case insensitive).

+
      <filter>
+        <filter-name>RemoteIpFilter</filter-name>
+        <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
+        <init-param>
+          <param-name>protocolHeader</param-name>
+          <param-value>x-forwarded-proto</param-value>
+        </init-param>
+      </filter>
+
+      <filter-mapping>
+        <filter-name>RemoteIpFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+      </filter-mapping>
+
+ +

Advanced configuration with internal proxies

+

RemoteIpFilter configuration:

+
     <filter>
+       <filter-name>RemoteIpFilter</filter-name>
+       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
+       <init-param>
+         <param-name>allowedInternalProxies</param-name>
+         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpHeader</param-name>
+         <param-value>x-forwarded-for</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpProxiesHeader</param-name>
+         <param-value>x-forwarded-by</param-value>
+       </init-param>
+       <init-param>
+         <param-name>protocolHeader</param-name>
+         <param-value>x-forwarded-proto</param-value>
+       </init-param>
+     </filter>
+

Request values:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyValue Before RemoteIpFilterValue After RemoteIpFilter
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, 192.168.0.10 null
request.header['x-forwarded-by'] null null
request.header['x-forwarded-proto'] https https
request.scheme http https
request.secure false true
request.serverPort 80 443
+ +

+ Note : x-forwarded-by header is null because only + internal proxies has been traversed by the request. + x-forwarded-for is null because all the proxies are + trusted or internal. +

+
+ + +

Advanced configuration with trusted proxies

+

RemoteIpFilter configuration:

+
     <filter>
+       <filter-name>RemoteIpFilter</filter-name>
+       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
+       <init-param>
+         <param-name>allowedInternalProxies</param-name>
+         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpHeader</param-name>
+         <param-value>x-forwarded-for</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpProxiesHeader</param-name>
+         <param-value>x-forwarded-by</param-value>
+       </init-param>
+       <init-param>
+         <param-name>trustedProxies</param-name>
+         <param-value>proxy1|proxy2</param-value>
+       </init-param>
+     </filter>
+

Request values:

+ + + + + + + + + + + + + + + + + + + + + +
PropertyValue Before RemoteIpFilterValue After RemoteIpFilter
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, proxy1, proxy2 null
request.header['x-forwarded-by'] null proxy1, proxy2
+ +

+ Note : proxy1 and proxy2 are both trusted proxies that + come in x-forwarded-for header, they both are migrated in + x-forwarded-by header. x-forwarded-for is null + because all the proxies are trusted or internal. +

+
+ +

Advanced configuration with internal and trusted proxies

+

RemoteIpFilter configuration:

+
     <filter>
+       <filter-name>RemoteIpFilter</filter-name>
+       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
+       <init-param>
+         <param-name>allowedInternalProxies</param-name>
+         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpHeader</param-name>
+         <param-value>x-forwarded-for</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpProxiesHeader</param-name>
+         <param-value>x-forwarded-by</param-value>
+       </init-param>
+       <init-param>
+         <param-name>trustedProxies</param-name>
+         <param-value>proxy1|proxy2</param-value>
+       </init-param>
+     </filter>
+

Request values:

+ + + + + + + + + + + + + + + + + + + + + +
PropertyValue Before RemoteIpFilterValue After RemoteIpFilter
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, proxy1, proxy2, 192.168.0.10 null
request.header['x-forwarded-by'] null proxy1, proxy2
+ +

+ Note : proxy1 and proxy2 are both trusted proxies that + come in x-forwarded-for header, they both are migrated in + x-forwarded-by header. As 192.168.0.10 is an internal + proxy, it does not appear in x-forwarded-by. + x-forwarded-for is null because all the proxies are + trusted or internal. +

+
+ +

Advanced configuration with an untrusted proxy

+ +

RemoteIpFilter configuration:

+
     <filter>
+       <filter-name>RemoteIpFilter</filter-name>
+       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
+       <init-param>
+         <param-name>allowedInternalProxies</param-name>
+         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpHeader</param-name>
+         <param-value>x-forwarded-for</param-value>
+       </init-param>
+       <init-param>
+         <param-name>remoteIpProxiesHeader</param-name>
+         <param-value>x-forwarded-by</param-value>
+       </init-param>
+       <init-param>
+         <param-name>trustedProxies</param-name>
+         <param-value>proxy1|proxy2</param-value>
+       </init-param>
+     </filter>
+

Request values:

+ + + + + + + + + + + + + + + + + + + + + +
PropertyValue Before RemoteIpFilterValue After RemoteIpFilter
request.remoteAddr 192.168.0.10 untrusted-proxy
request.header['x-forwarded-for'] 140.211.11.130, untrusted-proxy, proxy1 140.211.11.130
request.header['x-forwarded-by'] null proxy1
+ +

+ Note : x-forwarded-by holds the trusted proxy proxy1. + x-forwarded-by holds 140.211.11.130 because + untrusted-proxy is not trusted and thus, we can not trust that + untrusted-proxy is the actual remote ip. + request.remoteAddr is untrusted-proxy that is an IP + verified by proxy1. +

+
+ +

Initialisation parameters

+ +

The Remote IP Filter supports the + following initialisation parameters:

+ +
+ Attribute + + Description +
remoteIpHeader +

Name of the HTTP Header read by this valve that holds the list of + traversed IP addresses starting from the requesting client. If not + specified, the default of x-forwarded-for is used.

+
internalProxies +

Regular expression (using java.util.regex) that a + proxy's IP address must match to be considered an internal proxy. + Internal proxies that appear in the remoteIpHeader will + be trusted and will not appear in the proxiesHeader + value. If not specified the default value of + 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1 + will be used.

+
proxiesHeader +

Name of the HTTP header created by this valve to hold the list of + proxies that have been processed in the incoming + remoteIpHeader. If not specified, the default of + x-forwarded-by is used.

+
requestAttributesEnabled +

Set to true to set the request attributes used by + AccessLog implementations to override the values returned by the + request for remote address, remote host, server port and protocol. + Request attributes are also used to enable the forwarded remote address + to be displayed on the status page of the Manager web application. + If not set, the default value of true will be used.

+
trustedProxies +

Regular expression (using java.util.regex) that a + proxy's IP address must match to be considered an trusted proxy. + Trusted proxies that appear in the remoteIpHeader will + be trusted and will appear in the proxiesHeader value. + If not specified, no proxies will be trusted.

+
protocolHeader +

Name of the HTTP Header read by this valve that holds the protocol + used by the client to connect to the proxy. If not specified, the + default of null is used.

+
portHeader +

Name of the HTTP Header read by this valve that holds the port + used by the client to connect to the proxy. If not specified, the + default of null is used.

+
protocolHeaderHttpsValue +

Value of the protocolHeader to indicate that it is + an HTTPS request. If not specified, the default of https is + used.

+
httpServerPort +

Value returned by ServletRequest.getServerPort() + when the protocolHeader indicates http + protocol and no portHeader is present. If not + specified, the default of 80 is used.

+
httpsServerPort +

Value returned by ServletRequest.getServerPort() + when the protocolHeader indicates https + protocol and no portHeader is present. If not + specified, the default of 443 is used.

+
changeLocalPort +

If true, the value returned by + ServletRequest.getLocalPort() and + ServletRequest.getServerPort() is modified by the this + filter. If not specified, the default of false is used.

+
+ + +
+ +

Request Dumper Filter

+ +

Introduction

+ +

The Request Dumper Filter logs information from the request and response + objects and is intended to be used for debugging purposes. When using this + Filter, it is recommended that the + org.apache.catalina.filter.RequestDumperFilter logger is + directed to a dedicated file and that the + org.apache.juli.VerbatimFormatter is used.

+ +

WARNING: Using this filter has side-effects. The + output from this filter includes any parameters included with the request. + The parameters will be decoded using the default platform encoding. Any + subsequent calls to request.setCharacterEncoding() within + the web application will have no effect.

+ +
+ +

Filter Class Name

+ +

The filter class name for the Request Dumper Filter is + org.apache.catalina.filters.RequestDumperFilter + .

+ +
+ +

Initialisation parameters

+ +

The Request Dumper Filter does not support any initialization + parameters.

+ +
+ +

Sample Configuration

+ +

The following entries in a web application's web.xml would enable the + Request Dumper filter for all requests for that web application. If the + entries were added to CATALINA_BASE/conf/web.xml, the Request + Dumper Filter would be enabled for all web applications.

+
<filter>
+    <filter-name>requestdumper</filter-name>
+    <filter-class>
+        org.apache.catalina.filters.RequestDumperFilter
+    </filter-class>
+</filter>
+<filter-mapping>
+    <filter-name>requestdumper</filter-name>
+    <url-pattern>*</url-pattern>
+</filter-mapping>
+ +

The following entries in CATALINA_BASE/conf/logging.properties would + create a separate log file for the Request Dumper Filter output.

+
# To this configuration below, 1request-dumper.org.apache.juli.FileHandler
+# also needs to be added to the handlers property near the top of the file
+1request-dumper.org.apache.juli.FileHandler.level = INFO
+1request-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1request-dumper.org.apache.juli.FileHandler.prefix = request-dumper.
+1request-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter
+org.apache.catalina.filters.RequestDumperFilter.level = INFO
+org.apache.catalina.filters.RequestDumperFilter.handlers = \
+  1request-dumper.org.apache.juli.FileHandler
+
+

Session Initializer Filter

+ +

Introduction

+

The Session Initializer Filter initializes the javax.servlet.http.HttpSession + before the Request is processed. This is required for JSR-356 compliant WebSocket implementations, + if the HttpSession is needed during the HandShake phase.

+ +

The Java API for WebSocket does not mandate that an HttpSession would + be initialized upon request, and thus javax.servlet.http.HttpServletRequest's + getSession() returns null if the HttpSession was not + initialized in advance.

+ +

This filter solves that problem by initializing the HttpSession for any HttpServletRequest + that matches its url-pattern.

+
+ +

Filter Class Name

+

The filter class name for the Session Initializer Filter is + org.apache.catalina.filters.SessionInitializerFilter.

+
+ +

Initialisation parameters

+

The Session Initializer Filter does not support any initialization parameters.

+
+ +

Sample Configuration

+

The following entries in the Web Application Deployment Descriptor, web.xml, + would enable the Session Initializer Filter for requests that match the given URL pattern + (in this example, "/ws/*").

+ +
<filter>
+    <filter-name>SessionInitializer</filter-name>
+    <filter-class>org.apache.catalina.filters.SessionInitializerFilter</filter-class>
+</filter>
+<filter-mapping>
+    <filter-name>SessionInitializer</filter-name>
+    <url-pattern>/ws/*</url-pattern>
+</filter-mapping>
+
+

Set Character Encoding Filter

+ +

Introduction

+ +

User agents don't always include character encoding information in + requests. Depending on the how the request is processed, usually the + default encoding of ISO-8859-1 is used. This is not always + desirable. This filter provides options for setting that encoding or + forcing it to a particular value. Essentially this filter calls + ServletRequest.setCharacterEncoding() method.

+ +

Effectively the value set by this filter is used when parsing parameters + in a POST request, if parameter parsing occurs later than this filter. Thus + the order of filter mappings is important. Note that the encoding for GET + requests is not set here, but on a Connector. See + CharacterEncoding page in the FAQ for details.

+ +
+ +

Filter Class Name

+ +

The filter class name for the Set Character Encoding Filter is + org.apache.catalina.filters.SetCharacterEncodingFilter + .

+ +
+ +

Initialisation parameters

+ +

The Set Character Encoding Filter supports the following initialization + parameters:

+ +
+ Attribute + + Description +
encoding +

Name of the character encoding which should be set.

+
ignore +

Determines if any character encoding specified by the user agent is + ignored. If this attribute is true, any value provided by + the user agent is ignored. If false, the encoding is only + set if the user agent did not specify an encoding. The default value + is false.

+
+ +
+ +

WebDAV Fix Filter

+ +

Introduction

+ +

Microsoft operating systems have two WebDAV clients. One is used with + port 80, the other is used for all other ports. The implementation used with + port 80 does not adhere to the WebDAV specification and fails when trying to + communicate with the Tomcat WebDAV Servlet. This Filter provides a fix for + this by forcing the use of the WebDAV implementation that works, even when + connecting via port 80.

+ +
+ +

Filter Class Name

+ +

The filter class name for the WebDAV Fix Filter is + org.apache.catalina.filters.WebdavFixFilter + .

+ +
+ +

Initialisation parameters

+ +

The WebDAV Fix Filter does not support any initialization parameters.

+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/globalresources.html b/test.dockerapp/tomcat/webapps/docs/config/globalresources.html new file mode 100644 index 0000000..68f6454 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/globalresources.html @@ -0,0 +1,258 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The GlobalNamingResources Component

The GlobalNamingResources Component

Table of Contents

Introduction

+ +

The GlobalNamingResources element defines the global + JNDI resources for the Server.

+ +

These resources are listed in the server's global JNDI resource context. + This context is distinct from the per-web-application JNDI contexts + described in + the JNDI Resources HOW-TO. + The resources defined in this element are not visible in + the per-web-application contexts unless you explicitly link them with + <ResourceLink> elements. +

+ +

Attributes

+ +

Nested Components

+ +

Special Features

+ + +

Environment Entries

+ +

You can configure named values that will be made visible to all + web applications as environment entry resources by nesting + <Environment> entries inside this element. For + example, you can create an environment entry like this:

+
<GlobalNamingResources ...>
+  ...
+  <Environment name="maxExemptions" value="10"
+         type="java.lang.Integer" override="false"/>
+  ...
+</GlobalNamingResources>
+ +

This is equivalent to the inclusion of the following element in the + web application deployment descriptor (/WEB-INF/web.xml): +

+
<env-entry>
+  <env-entry-name>maxExemptions</env-entry-name>
+  <env-entry-value>10</env-entry-value>
+  <env-entry-type>java.lang.Integer</env-entry-type>
+</env-entry>
+

but does not require modification of the deployment descriptor + to customize this value.

+ +

The valid attributes for an <Environment> element + are as follows:

+ +
+ Attribute + + Description +
description +

Optional, human-readable description of this environment entry.

+
name +

The name of the environment entry to be created, relative to the + java:comp/env context.

+
override +

Set this to false if you do not want + an <env-entry> for the same environment entry name, + found in the web application deployment descriptor, to override the + value specified here. By default, overrides are allowed.

+
type +

The fully qualified Java class name expected by the web application + for this environment entry. Must be a legal value for + <env-entry-type> in the web application deployment + descriptor.

+
value +

The parameter value that will be presented to the application + when requested from the JNDI context. This value must be convertable + to the Java type defined by the type attribute.

+
+ +
+ + +

Resource Definitions

+ +

You can declare the characteristics of resources + to be returned for JNDI lookups of <resource-ref> and + <resource-env-ref> elements in the web application + deployment descriptor by defining them in this element and then linking + them with <ResourceLink> + elements + in the <Context> element. + + You MUST also define any other needed parameters using + attributes on the Resource element, to configure + the object factory to be used (if not known to Tomcat already), and + the properties used to configure that object factory.

+ +

For example, you can create a resource definition like this:

+
<GlobalNamingResources ...>
+  ...
+  <Resource name="jdbc/EmployeeDB" auth="Container"
+            type="javax.sql.DataSource"
+     description="Employees Database for HR Applications"/>
+  ...
+</GlobalNamingResources>
+ +

This is equivalent to the inclusion of the following element in the + web application deployment descriptor (/WEB-INF/web.xml):

+
<resource-ref>
+  <description>Employees Database for HR Applications</description>
+  <res-ref-name>jdbc/EmployeeDB</res-ref-name>
+  <res-ref-type>javax.sql.DataSource</res-ref-type>
+  <res-auth>Container</res-auth>
+</resource-ref>
+ +

but does not require modification of the deployment + descriptor to customize this value.

+ +

The valid attributes for a <Resource> element + are as follows:

+ +
+ Attribute + + Description +
auth +

Specify whether the web Application code signs on to the + corresponding resource manager programmatically, or whether the + Container will sign on to the resource manager on behalf of the + application. The value of this attribute must be + Application or Container. This + attribute is required if the web application + will use a <resource-ref> element in the web + application deployment descriptor, but is optional if the + application uses a <resource-env-ref> instead.

+
closeMethod +

Name of the zero-argument method to call on a singleton resource when + it is no longer required. This is intended to speed up clean-up of + resources that would otherwise happen as part of garbage collection. + This attribute is ignored if the singleton attribute is + false. If not specified, no default is defined and no close method will + be called.

+

For Apache Commons DBCP and Apache Tomcat JDBC connection pools + you can use closeMethod="close".

+
description +

Optional, human-readable description of this resource.

+
name +

The name of the resource to be created, relative to the + java:comp/env context.

+
scope +

Specify whether connections obtained through this resource + manager can be shared. The value of this attribute must be + Shareable or Unshareable. By default, + connections are assumed to be shareable.

+
singleton +

Specify whether this resource definition is for a singleton resource, + i.e. one where there is only a single instance of the resource. If this + attribute is true, multiple JNDI lookups for this resource + will return the same object. If this attribute is false, + multiple JNDI lookups for this resource will return different objects. + This attribute must be true for + javax.sql.DataSource resources to enable JMX registration + of the DataSource. The value of this attribute must be true + or false. By default, this attribute is true. +

+
type +

The fully qualified Java class name expected by the web + application when it performs a lookup for this resource.

+
+ + +
+ +
+

Use <ResourceLink> + elements to link resources from the global context into + per-web-application contexts. Here is an example of making a custom + factory available to an application, based on the example definition in the + + JNDI Resource HOW-TO: +

+ +
<Context>
+  <ResourceLink
+    name="bean/MyBeanFactory"
+    global="bean/MyBeanFactory"
+    type="com.mycompany.MyBean"
+  />
+</Context>
+ +
+ +

Transaction

+ +

You can declare the characteristics of the UserTransaction + to be returned for JNDI lookup for java:comp/UserTransaction. + You MUST define an object factory class to instantiate + this object as well as the needed resource parameters as attributes of the + Transaction + element, and the properties used to configure that object factory.

+ +

The valid attributes for the <Transaction> element + are as follows:

+ +
+ Attribute + + Description +
factory +

The class name for the JNDI object factory.

+
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/host.html b/test.dockerapp/tomcat/webapps/docs/config/host.html new file mode 100644 index 0000000..9144405 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/host.html @@ -0,0 +1,621 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Host Container

The Host Container

Table of Contents

Introduction

+ +

The Host element represents a virtual host, + which is an association of a network name for a server (such as + "www.mycompany.com") with the particular server on which Tomcat is running. + For clients to be able to connect to a Tomcat server using its network name, + this name must be registered in the Domain Name Service (DNS) server + that manages the Internet domain you belong to - contact your Network + Administrator for more information.

+ +

In many cases, System Administrators wish to associate more than + one network name (such as www.mycompany.com and + company.com) with the same virtual host and applications. + This can be accomplished using the Host + Name Aliases feature discussed below.

+ +

One or more Host elements are nested inside an + Engine element. Inside the Host element, you + can nest Context elements for the web + applications associated with this virtual host. Exactly one of the Hosts + associated with each Engine MUST have a name matching the + defaultHost attribute of that Engine.

+ +

Clients normally use host names to identify the server they wish to connect + to. This host name is also included in the HTTP request headers. Tomcat + extracts the host name from the HTTP headers and looks for a + Host with a matching name. If no match is found, the request + is routed to the default host. The name of the default host does not have to + match a DNS name (although it can) since any request where the DNS name does + not match the name of a Host element will be routed to the + default host.

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Host + support the following attributes:

+ +
+ Attribute + + Description +
appBase +

The Application Base directory for this virtual host. + This is the pathname of a directory that may contain web applications + to be deployed on this virtual host. You may specify an + absolute pathname, or a pathname that is relative to the + $CATALINA_BASE directory. See + Automatic Application + Deployment for more information on automatic recognition and + deployment of web applications. If not specified, the default of + webapps will be used.

+
xmlBase +

The XML Base directory for this virtual host. + This is the pathname of a directory that may contain context XML + descriptors to be deployed on this virtual host. You may specify an + absolute pathname for this directory, or a pathname that is relative + to the $CATALINA_BASE directory. See + Automatic Application + Deployment for more information on automatic recognition and + deployment of web applications. If not specified the default of + conf/<engine_name>/<host_name> will be used.

+
createDirs +

If set to true, Tomcat will attempt to create the directories defined + by the attributes appBase and xmlBase during + the startup phase. The default value is true. If set to + true, and directory creation fails, an error message will be printed out + but will not halt the startup sequence.

+
autoDeploy +

This flag value indicates if Tomcat should check periodically for new + or updated web applications while Tomcat is running. If true, Tomcat + periodically checks the appBase and xmlBase + directories and deploys any new web applications or context XML + descriptors found. Updated web applications or context XML descriptors + will trigger a reload of the web application. The flag's value defaults + to true. See + Automatic Application + Deployment for more information.

+
backgroundProcessorDelay +

This value represents the delay in seconds between the + invocation of the backgroundProcess method on this host and + its child containers, including all contexts. + Child containers will not be invoked if their delay value is not + negative (which would mean they are using their own processing + thread). Setting this to a positive value will cause + a thread to be spawn. After waiting the specified amount of time, + the thread will invoke the backgroundProcess method on this host + and all its child containers. A host will use background processing to + perform live web application deployment related tasks. If not + specified, the default value for this attribute is -1, which means + the host will rely on the background processing thread of its parent + engine.

+
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Host interface. + If not specified, the standard value (defined below) will be used.

+
deployIgnore +

A regular expression defining paths to ignore when + autoDeploy and deployOnStartup are set. This + allows you to keep your configuration in a version control system, for + example, and not deploy a .svn or CVS folder that happens to be in the + appBase.

+

This regular expression is relative to appBase. It is + also anchored, meaning the match is performed against the + entire file/directory name. So, foo matches only a file or + directory named foo but not foo.war, + foobar, or myfooapp. To match anything with + "foo", you could use .*foo.*.

+

See Automatic Application + Deployment for more information.

+
deployOnStartup +

This flag value indicates if web applications from this host should + be automatically deployed when Tomcat starts. The flag's value defaults + to true. See + Automatic Application + Deployment for more information.

+
failCtxIfServletStartFails +

Set to true to have each child contexts fail its startup + if any of its servlet that has load-on-startup >=0 fails its own + startup.

+

Each child context may override this attribute.

+

If not specified, the default value of false is + used.

+
name +

Usually the network name of this virtual host, as registered in your + Domain Name Service server. Regardless of the case used to + specify the host name, Tomcat will convert it to lower case internally. + One of the Hosts nested within an Engine MUST + have a name that matches the defaultHost setting for that + Engine. See Host Name Aliases for + information on how to assign more than one network name to the same + virtual host.

+
startStopThreads +

The number of threads this Host will use to start + child Context elements in parallel. The same + thread pool will be used to deploy new + Contexts if automatic deployment is being + used. The special value of 0 will result in the value of + Runtime.getRuntime().availableProcessors() being used. + Negative values will result in + Runtime.getRuntime().availableProcessors() + value being + used unless this is less than 1 in which case 1 thread will be used. If + not specified, the default value of 1 will be used.

+
undeployOldVersions +

This flag determines if Tomcat, as part of the auto deployment + process, will check for old, unused versions of web applications + deployed using parallel deployment and, if any are found, remove them. + This flag only applies if autoDeploy is true. If not + specified the default value of false will be used.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of Host is + org.apache.catalina.core.StandardHost. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
copyXML +

Set to true if you want a context XML descriptor + embedded inside the application (located at + /META-INF/context.xml) to be copied to xmlBase + when the application is deployed. On subsequent starts, the copied + context XML descriptor will be used in preference to any context XML + descriptor embedded inside the application even if the descriptor + embedded inside the application is more recent. The flag's value + defaults to false. Note if deployXML + is false, this attribute will have no effect.

+
deployXML +

Set to false if you want to disable parsing the context + XML descriptor embedded inside the application (located at + /META-INF/context.xml). Security conscious environments + should set this to false to prevent applications from + interacting with the container's configuration. The administrator will + then be responsible for providing an external context configuration + file, and putting it in the location defined by the + xmlBase attribute. If this flag is false, + a descriptor is located at /META-INF/context.xml and no + descriptor is present in xmlBase then the context will + fail to start in case the descriptor contains necessary configuration + for secure deployment (such as a RemoteAddrValve) which should not be + ignored. The flag's value defaults to true unless a + security manager is enabled when the default is false. + When running under a security manager this may be enabled on a per web + application basis by granting the + org.apache.catalina.security.DeployXmlPermission to the web + application. The Manager and Host Manager applications are granted this + permission by default so that they continue to work when running under a + security manager.

+
errorReportValveClass +

Java class name of the error reporting valve which will be used + by this Host. The responsibility of this valve is to output error + reports. Setting this property allows to customize the look of the + error pages which will be generated by Tomcat. This class must + implement the + org.apache.catalina.Valve interface. If none is specified, + the value org.apache.catalina.valves.ErrorReportValve + will be used by default.

+
unpackWARs +

Set to true if you want web applications that are + placed in the appBase directory as web application + archive (WAR) files to be unpacked into a corresponding disk directory + structure, false to run such web applications directly + from a WAR file. See + Automatic Application + Deployment for more information.

+

Note: If Tomcat expands the WAR file then it will add a file + (/META-INF/war-tracking) to the unpacked directory + structure which it uses to detect changes in the WAR file while Tomcat + is not running. Any such change will trigger the deletion of the + expanded directory and the deployment of the updated WAR file when + Tomcat next starts.

+

Note: Running with this option set to false will incur + a performance penalty. To avoid a significant performance penalty, the + web application should be configured such that class scanning for + Servlet 3.0+ pluggability features is not required. Users may also wish + to consider the ExtractingRoot + Resources implementation.

+
workDir +

Pathname to a scratch directory to be used by applications for + this Host. Each application will have its own sub directory with + temporary read-write use. Configuring a Context workDir will override + use of the Host workDir configuration. This directory will be made + visible to servlets in the web application by a servlet context + attribute (of type java.io.File) named + javax.servlet.context.tempdir as described in the + Servlet Specification. If not specified, a suitable directory + underneath $CATALINA_BASE/work will be provided.

+
+ +
+ + +

Nested Components

+ +

You can nest one or more Context elements + inside this Host element, each representing a different web + application associated with this virtual host.

+ +

You can nest at most one instance of the following utility components + by nesting a corresponding element inside your Host + element:

+
    +
  • Realm - + Configure a realm that will allow its + database of users, and their associated roles, to be shared across all + Contexts nested inside this Host (unless + overridden by a Realm configuration + at a lower level).
  • +
+ +

Special Features

+ + +

Logging

+ +

A host is associated with the + org.apache.catalina.core.ContainerBase.[engine_name].[host_name] + log category. Note that the brackets are part of the name, + don't omit them.

+ +
+ + +

Access Logs

+ +

When you run a web server, one of the output files normally generated + is an access log, which generates one line of information for + each request processed by the server, in a standard format. Catalina + includes an optional Valve implementation that + can create access logs in the same standard format created by web servers, + or in any number of custom formats.

+ +

You can ask Catalina to create an access log for all requests + processed by an Engine, + Host, or Context + by nesting a Valve element like this:

+ +
<Host name="localhost" ...>
+  ...
+  <Valve className="org.apache.catalina.valves.AccessLogValve"
+         prefix="localhost_access_log" suffix=".txt"
+         pattern="common"/>
+  ...
+</Host>
+ +

See Access Logging Valves + for more information on the configuration attributes that are + supported.

+ +
+ + +

Automatic Application Deployment

+ +

If you are using the standard Host implementation with + default settings then applications in the appBase or with context + files in the configBase are automatically deployed when Tomcat + starts (the deployOnStartup property defaults to + true) and reloaded or redeployed (as appropriate) when a change + is detected while Tomcat is running (the autoDeploy attribute + also defaults to true).

+ +

deployOnStartup and autoDeploy trigger + execution of exactly the same code so the behaviour is very similar. + However, there is one key difference. When Tomcat starts it has no knowledge + of which files are the same, which have been changed and which are new. It + therefore treats all files as new. While Tomcat is running, it can + differentiate between unchanged, modified and new files. This leads to some + differences in behaviour between files being modified while Tomcat is + running and files being modified while Tomcat is stopped.

+ +

When you use automatic deployment, related files (a web application may + have a context.xml file, a WAR and a directory) that exist in the + Host's appBase and/or configBase + must conform to the expected naming + convention. In short, this means files for the same web application must + share the same base name.

+ +

The automatic deployment process identifies new and/or modified web + applications using the following search order:

+ +
    +
  1. Web applications with a context.xml file located in the Host's + configBase.
  2. +
  3. Web applications with a WAR file located in the Host's + appBase that have not already been identified during the scan for + context.xml files.
  4. +
  5. Web applications with a directory located in the Host's + appBase that have not already been identified during the scans + for context.xml and/or WAR files.
  6. +
+ +

When autoDeploy is true, the automatic + deployment process will monitor the deployed web applications for changes. + Depending on exactly what changes, the web application will either be + re-deployed or reloaded. Re-deployment involves the creation of a new web + application and, if using the standard session manager, user sessions will + not be retained. Reloading uses the existing web application but re-parses + the web.xml and reloads any classes. If using the standard session manager, + user sessions will be persisted.

+ +

Users may add to the files that the automatic deployment process monitors + for reloading (i.e. any change to one of these files triggers a reload of + the web application) by adding a WatchedResources element to the + context.xml file. See the + Context documentation for + further details.

+ +

When using automatic deployment, the docBase defined by + an XML Context file should be outside of the + appBase directory. If this is not the case, difficulties + may be experienced deploying the web application or the application may + be deployed twice. The deployIgnore attribute can be used + to avoid this situation.

+ +

Note that if you are defining contexts explicitly in server.xml, you + should probably turn off automatic application deployment or specify + deployIgnore carefully. Otherwise, the web applications + will each be deployed twice, and that may cause problems for the + applications.

+ +

There are many possible combinations of settings, new files, changed + files and deleted files. A separate page describes the + expected behaviour of the automatic + deployment process in many of these scenarios.

+ +
+ + +

Host Name Aliases

+ +

In many server environments, Network Administrators have configured + more than one network name (in the Domain Name Service (DNS) + server), that resolve to the IP address of the same server. Normally, + each such network name would be configured as a separate + Host element in conf/server.xml, each + with its own set of web applications.

+ +

However, in some circumstances, it is desirable that two or more + network names should resolve to the same virtual host, + running the same set of applications. A common use case for this + scenario is a corporate web site, where it is desirable that users + be able to utilize either www.mycompany.com or + company.com to access exactly the same content and + applications.

+ +

This is accomplished by utilizing one or more Alias + elements nested inside your Host element. For + example:

+
<Host name="www.mycompany.com" ...>
+  ...
+  <Alias>mycompany.com</Alias>
+  ...
+</Host>
+ +

In order for this strategy to be effective, all of the network names + involved must be registered in your DNS server to resolve to the + same computer that is running this instance of Catalina.

+ +
+ + +

Lifecycle Listeners

+ +

If you have implemented a Java object that needs to know when this + Host is started or stopped, you can declare it by + nesting a Listener element inside this element. The + class name you specify must implement the + org.apache.catalina.LifecycleListener interface, and + it will be notified about the occurrence of the corresponding + lifecycle events. Configuration of such a listener looks like this:

+ +
<Host name="localhost" ...>
+  ...
+  <Listener className="com.mycompany.mypackage.MyListener" ... >
+  ...
+</Host>
+ +

Note that a Listener can have any number of additional properties + that may be configured from this element. Attribute names are matched + to corresponding JavaBean property names using the standard property + method naming patterns.

+ +
+ + +

Request Filters

+ +

You can ask Catalina to check the IP address, or host name, on every + incoming request directed to the surrounding + Engine, Host, or + Context element. The remote address or name + will be checked against configured "accept" and/or "deny" + filters, which are defined using java.util.regex Regular + Expression syntax. Requests that come from locations that are + not accepted will be rejected with an HTTP "Forbidden" error. + Example filter declarations:

+ +
<Host name="localhost" ...>
+  ...
+  <Valve className="org.apache.catalina.valves.RemoteHostValve"
+         allow=".*\.mycompany\.com|www\.yourcompany\.com"/>
+  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
+         deny="192\.168\.1\.\d+"/>
+  ...
+</Host>
+ +

See Remote Address Filter + and Remote Host Filter for + more information about the configuration options that are supported.

+ +
+ + +

Single Sign On

+ +

In many environments, but particularly in portal environments, it + is desirable to have a user challenged to authenticate themselves only + once over a set of web applications deployed on a particular virtual + host. This can be accomplished by nesting an element like this inside + the Host element for this virtual host:

+ +
<Host name="localhost" ...>
+  ...
+  <Valve className="org.apache.catalina.authenticator.SingleSignOn"/>
+  ...
+</Host>
+ +

The Single Sign On facility operates according to the following rules: +

+
    +
  • All web applications configured for this virtual host must share the + same Realm. In practice, that means you can + nest the Realm element inside this Host element (or the surrounding + Engine element), but not inside a + Context element for one of the involved + web applications.
  • +
  • As long as the user accesses only unprotected resources in any of the + web applications on this virtual host, they will not be challenged + to authenticate themselves.
  • +
  • As soon as the user accesses a protected resource in + any web application associated with this virtual + host, the user will be challenged to authenticate himself or herself, + using the login method defined for the web application currently + being accessed.
  • +
  • Once authenticated, the roles associated with this user will be + utilized for access control decisions across all + of the associated web applications, without challenging the user + to authenticate themselves to each application individually.
  • +
  • As soon as the user logs out of one web application (for example, + by invalidating the corresponding session if form + based login is used), the user's sessions in all + web applications will be invalidated. Any subsequent attempt to + access a protected resource in any application will require the + user to authenticate himself or herself again.
  • +
  • The Single Sign On feature utilizes HTTP cookies to transmit a token + that associates each request with the saved user identity, so it can + only be utilized in client environments that support cookies.
  • +
+ +
+ + +

User Web Applications

+ +

Many web servers can automatically map a request URI starting with + a tilde character ("~") and a username to a directory (commonly named + public_html) in that user's home directory on the server. + You can accomplish the same thing in Catalina by using a special + Listener element like this (on a Unix system that + uses the /etc/passwd file to identify valid users):

+ +
<Host name="localhost" ...>
+  ...
+  <Listener className="org.apache.catalina.startup.UserConfig"
+            directoryName="public_html"
+            userClass="org.apache.catalina.startup.PasswdUserDatabase"/>
+  ...
+</Host>
+ +

On a server where /etc/passwd is not in use, you can + request Catalina to consider all directories found in a specified base + directory (such as c:\Homes in this example) to be + considered "user home" directories for the purposes of this directive:

+ +
<Host name="localhost" ...>
+  ...
+  <Listener className="org.apache.catalina.startup.UserConfig"
+            directoryName="public_html"
+            homeBase="c:\Homes"
+            userClass="org.apache.catalina.startup.HomesUserDatabase"/>
+  ...
+</Host>
+ +

If a user home directory has been set up for a user named + craigmcc, then its contents will be visible from a + client browser by making a request to a URL like:

+ +
http://www.mycompany.com:8080/~craigmcc
+ +

Successful use of this feature requires recognition of the following + considerations:

+
    +
  • Each user web application will be deployed with characteristics + established by the global and host level default context settings.
  • +
  • It is legal to include more than one instance of this Listener + element. This would only be useful, however, in circumstances + where you wanted to configure more than one "homeBase" directory.
  • +
  • The operating system username under which Catalina is executed + MUST have read access to each user's web application directory, + and all of its contents.
  • +
+ +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/http.html b/test.dockerapp/tomcat/webapps/docs/config/http.html new file mode 100644 index 0000000..3e50e04 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/http.html @@ -0,0 +1,1370 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The HTTP Connector

The HTTP Connector

Table of Contents

Introduction

+ +

The HTTP Connector element represents a + Connector component that supports the HTTP/1.1 protocol. + It enables Catalina to function as a stand-alone web server, in addition + to its ability to execute servlets and JSP pages. A particular instance + of this component listens for connections on a specific TCP port number + on the server. One or more such Connectors can be + configured as part of a single Service, each + forwarding to the associated Engine to perform + request processing and create the response.

+ +

If you wish to configure the Connector that is used + for connections to web servers using the AJP protocol (such as the + mod_jk 1.2.x connector for Apache 1.3), please refer to the + AJP Connector documentation.

+ +

Each incoming request requires + a thread for the duration of that request. If more simultaneous requests + are received than can be handled by the currently available request + processing threads, additional threads will be created up to the + configured maximum (the value of the maxThreads attribute). + If still more simultaneous requests are received, they are stacked up + inside the server socket created by the Connector, up to + the configured maximum (the value of the acceptCount + attribute). Any further simultaneous requests will receive "connection + refused" errors, until resources are available to process them.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Connector + support the following attributes:

+ +
+ Attribute + + Description +
allowTrace +

A boolean value which can be used to enable or disable the TRACE + HTTP method. If not specified, this attribute is set to false.

+
asyncTimeout +

The default timeout for asynchronous requests in milliseconds. If not + specified, this attribute is set to the Servlet specification default of + 30000 (30 seconds).

+
enableLookups +

Set to true if you want calls to + request.getRemoteHost() to perform DNS lookups in + order to return the actual host name of the remote client. Set + to false to skip the DNS lookup and return the IP + address in String form instead (thereby improving performance). + By default, DNS lookups are disabled.

+
maxHeaderCount +

The maximum number of headers in a request that are allowed by the + container. A request that contains more headers than the specified limit + will be rejected. A value of less than 0 means no limit. + If not specified, a default of 100 is used.

+
maxParameterCount +

The maximum number of parameter and value pairs (GET plus POST) which + will be automatically parsed by the container. Parameter and value pairs + beyond this limit will be ignored. A value of less than 0 means no limit. + If not specified, a default of 10000 is used. Note that + FailedRequestFilter filter can be + used to reject requests that hit the limit.

+
maxPostSize +

The maximum size in bytes of the POST which will be handled by + the container FORM URL parameter parsing. The limit can be disabled by + setting this attribute to a value less than zero. If not specified, this + attribute is set to 2097152 (2 megabytes). Note that the + FailedRequestFilter + can be used to reject requests that exceed this limit.

+
maxSavePostSize +

The maximum size in bytes of the POST which will be saved/buffered by + the container during FORM or CLIENT-CERT authentication. For both types + of authentication, the POST will be saved/buffered before the user is + authenticated. For CLIENT-CERT authentication, the POST is buffered for + the duration of the SSL handshake and the buffer emptied when the request + is processed. For FORM authentication the POST is saved whilst the user + is re-directed to the login form and is retained until the user + successfully authenticates or the session associated with the + authentication request expires. The limit can be disabled by setting this + attribute to -1. Setting the attribute to zero will disable the saving of + POST data during authentication. If not specified, this attribute is set + to 4096 (4 kilobytes).

+
parseBodyMethods +

A comma-separated list of HTTP methods for which request + bodies will be parsed for request parameters identically + to POST. This is useful in RESTful applications that want to + support POST-style semantics for PUT requests. + Note that any setting other than POST causes Tomcat + to behave in a way that goes against the intent of the servlet + specification. + The HTTP method TRACE is specifically forbidden here in accordance + with the HTTP specification. + The default is POST

+
port +

The TCP port number on which this Connector + will create a server socket and await incoming connections. Your + operating system will allow only one server application to listen + to a particular port number on a particular IP address. If the special + value of 0 (zero) is used, then Tomcat will select a free port at random + to use for this connector. This is typically only useful in embedded and + testing applications.

+
protocol +

Sets the protocol to handle incoming traffic. The default value is + HTTP/1.1 which uses an auto-switching mechanism to select + either a non blocking Java NIO based connector or an APR/native based connector. + If the PATH (Windows) or LD_LIBRARY_PATH (on + most unix systems) environment variables contain the Tomcat native + library, the APR/native connector will be used. If the native library + cannot be found, the non blocking Java based connector will be used. Note + that the APR/native connector has different settings for HTTPS than the + Java connectors.
+ To use an explicit protocol rather than rely on the auto-switching + mechanism described above, the following values may be used:
+ org.apache.coyote.http11.Http11Protocol - + blocking Java connector
+ org.apache.coyote.http11.Http11NioProtocol - + non blocking Java NIO connector
+ org.apache.coyote.http11.Http11Nio2Protocol - + non blocking Java NIO2 connector
+ org.apache.coyote.http11.Http11AprProtocol - + the APR/native connector.
+ Custom implementations may also be used.
+ Take a look at our Connector + Comparison chart. The configuration for both Java connectors is + identical, for http and https.
+ For more information on the APR connector and APR specific SSL settings + please visit the APR documentation +

+
proxyName +

If this Connector is being used in a proxy + configuration, configure this attribute to specify the server name + to be returned for calls to request.getServerName(). + See Proxy Support for more + information.

+
proxyPort +

If this Connector is being used in a proxy + configuration, configure this attribute to specify the server port + to be returned for calls to request.getServerPort(). + See Proxy Support for more + information.

+
redirectPort +

If this Connector is supporting non-SSL + requests, and a request is received for which a matching + <security-constraint> requires SSL transport, + Catalina will automatically redirect the request to the port + number specified here.

+
scheme +

Set this attribute to the name of the protocol you wish to have + returned by calls to request.getScheme(). For + example, you would set this attribute to "https" + for an SSL Connector. The default value is "http". +

+
secure +

Set this attribute to true if you wish to have + calls to request.isSecure() to return true + for requests received by this Connector. You would want this on an + SSL Connector or a non SSL connector that is receiving data from a + SSL accelerator, like a crypto card, a SSL appliance or even a webserver. + The default value is false.

+
URIEncoding +

This specifies the character encoding used to decode the URI bytes, + after %xx decoding the URL. If not specified, UTF-8 will be used unless + the org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system property is set to true + in which case ISO-8859-1 will be used.

+
useBodyEncodingForURI +

This specifies if the encoding specified in contentType should be used + for URI query parameters, instead of using the URIEncoding. This + setting is present for compatibility with Tomcat 4.1.x, where the + encoding specified in the contentType, or explicitly set using + Request.setCharacterEncoding method was also used for the parameters from + the URL. The default value is false. +

+

Notes: 1) This setting is applied only to the + query string of a request. Unlike URIEncoding it does not + affect the path portion of a request URI. 2) If request character + encoding is not known (is not provided by a browser and is not set by + SetCharacterEncodingFilter or a similar filter using + Request.setCharacterEncoding method), the default encoding is always + "ISO-8859-1". The URIEncoding setting has no effect on + this default. +

+
useIPVHosts +

Set this attribute to true to cause Tomcat to use + the IP address that the request was received on to determine the Host + to send the request to. The default value is false.

+
xpoweredBy +

Set this attribute to true to cause Tomcat to advertise + support for the Servlet specification using the header recommended in the + specification. The default value is false.

+
+ +
+ +

Standard Implementation

+ +

The standard HTTP connectors (BIO, NIO, NIO2 and APR/native) all support + the following attributes in addition to the common Connector attributes + listed above.

+ +
+ Attribute + + Description +
acceptCount +

The maximum queue length for incoming connection requests when + all possible request processing threads are in use. Any requests + received when the queue is full will be refused. The default + value is 100.

+
acceptorThreadCount +

The number of threads to be used to accept connections. Increase this + value on a multi CPU machine, although you would never really need more + than 2. Also, with a lot of non keep alive connections, you + might want to increase this value as well. Default value is + 1.

+
acceptorThreadPriority +

The priority of the acceptor threads. The threads used to accept + new connections. The default value is 5 (the value of the + java.lang.Thread.NORM_PRIORITY constant). See the JavaDoc + for the java.lang.Thread class for more details on what + this priority means.

+
address +

For servers with more than one IP address, this attribute + specifies which address will be used for listening on the specified + port. By default, this port will be used on all IP addresses + associated with the server.

+
allowHostHeaderMismatch +

By default Tomcat will allow requests that specify a host in the + request line but specify a different host in the host header. This + check can be enabled by setting this attribute to false. If + not specified, the default is true.

+
allowedTrailerHeaders +

By default Tomcat will ignore all trailer headers when processing + chunked input. For a header to be processed, it must be added to this + comma-separated list of header names.

+
bindOnInit +

Controls when the socket used by the connector is bound. By default it + is bound when the connector is initiated and unbound when the connector is + destroyed. If set to false, the socket will be bound when the + connector is started and unbound when it is stopped.

+
compressibleMimeType +

The value is a comma separated list of MIME types for which HTTP + compression may be used. + The default value is + + text/html,text/xml,text/plain,text/css,text/javascript,application/javascript + . +

+
compression +

The Connector may use HTTP/1.1 GZIP compression in + an attempt to save server bandwidth. The acceptable values for the + parameter is "off" (disable compression), "on" (allow compression, which + causes text data to be compressed), "force" (forces compression in all + cases), or a numerical integer value (which is equivalent to "on", but + specifies the minimum amount of data before the output is compressed). If + the content-length is not known and compression is set to "on" or more + aggressive, the output will also be compressed. If not specified, this + attribute is set to "off".

+

Note: There is a tradeoff between using compression (saving + your bandwidth) and using the sendfile feature (saving your CPU cycles). + If the connector supports the sendfile feature, e.g. the NIO connector, + using sendfile will take precedence over compression. The symptoms will + be that static files greater that 48 Kb will be sent uncompressed. + You can turn off sendfile by setting useSendfile attribute + of the connector, as documented below, or change the sendfile usage + threshold in the configuration of the + DefaultServlet in the default + conf/web.xml or in the web.xml of your web + application. +

+
compressionMinSize +

If compression is set to "on" then this attribute + may be used to specify the minimum amount of data before the output is + compressed. If not specified, this attribute is defaults to "2048".

+
connectionLinger +

The number of seconds during which the sockets used by this + Connector will linger when they are closed. The default + value is -1 which disables socket linger.

+
connectionTimeout +

The number of milliseconds this Connector will wait, + after accepting a connection, for the request URI line to be + presented. Use a value of -1 to indicate no (i.e. infinite) timeout. + The default value is 60000 (i.e. 60 seconds) but note that the standard + server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). + Unless disableUploadTimeout is set to false, + this timeout will also be used when reading the request body (if any).

+
connectionUploadTimeout +

Specifies the timeout, in milliseconds, to use while a data upload is + in progress. This only takes effect if + disableUploadTimeout is set to false. +

+
disableUploadTimeout +

This flag allows the servlet container to use a different, usually + longer connection timeout during data upload. If not specified, this + attribute is set to true which disables this longer timeout. +

+
executor +

A reference to the name in an Executor + element. If this attribute is set, and the named executor exists, the + connector will use the executor, and all the other thread attributes will + be ignored. Note that if a shared executor is not specified for a + connector then the connector will use a private, internal executor to + provide the thread pool.

+
executorTerminationTimeoutMillis +

The time that the private internal executor will wait for request + processing threads to terminate before continuing with the process of + stopping the connector. If not set, the default is 0 (zero) + for the BIO connector and 5000 (5 seconds) for the NIO, + NIO2 and APR/native connectors.

+
keepAliveTimeout +

The number of milliseconds this Connector will wait + for another HTTP request before closing the connection. The default value + is to use the value that has been set for the + connectionTimeout attribute. + Use a value of -1 to indicate no (i.e. infinite) timeout.

+
maxConnections +

The maximum number of connections that the server will accept and + process at any given time. When this number has been reached, the server + will accept, but not process, one further connection. This additional + connection be blocked until the number of connections being processed + falls below maxConnections at which point the server will + start accepting and processing new connections again. Note that once the + limit has been reached, the operating system may still accept connections + based on the acceptCount setting. The default value varies by + connector type. For BIO the default is the value of + maxThreads unless an Executor + is used in which case the default will be the value of maxThreads from the + executor. For NIO and NIO2 the default is 10000. + For APR/native, the default is 8192.

+

Note that for APR/native on Windows, the configured value will be + reduced to the highest multiple of 1024 that is less than or equal to + maxConnections. This is done for performance reasons.
+ If set to a value of -1, the maxConnections feature is disabled + and connections are not counted.

+
maxCookieCount +

The maximum number of cookies that are permitted for a request. A value + of less than zero means no limit. If not specified, a default value of 200 + will be used.

+
maxExtensionSize +

Limits the total length of chunk extensions in chunked HTTP requests. + If the value is -1, no limit will be imposed. If not + specified, the default value of 8192 will be used.

+
maxHttpHeaderSize +

The maximum size of the request and response HTTP header, specified + in bytes. If not specified, this attribute is set to 8192 (8 KB).

+
maxKeepAliveRequests +

The maximum number of HTTP requests which can be pipelined until + the connection is closed by the server. Setting this attribute to 1 will + disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and + pipelining. Setting this to -1 will allow an unlimited amount of + pipelined or keep-alive HTTP requests. + If not specified, this attribute is set to 100.

+
maxSwallowSize +

The maximum number of request body bytes (excluding transfer encoding + overhead) that will be swallowed by Tomcat for an aborted upload. An + aborted upload is when Tomcat knows that the request body is going to be + ignored but the client still sends it. If Tomcat does not swallow the body + the client is unlikely to see the response. If not specified the default + of 2097152 (2 megabytes) will be used. A value of less than zero indicates + that no limit should be enforced.

+
maxThreads +

The maximum number of request processing threads to be created + by this Connector, which therefore determines the + maximum number of simultaneous requests that can be handled. If + not specified, this attribute is set to 200. If an executor is associated + with this connector, this attribute is ignored as the connector will + execute tasks using the executor rather than an internal thread pool. Note + that if an executor is configured any value set for this attribute will be + recorded correctly but it will be reported (e.g. via JMX) as + -1 to make clear that it is not used.

+
maxTrailerSize +

Limits the total length of trailing headers in the last chunk of + a chunked HTTP request. If the value is -1, no limit will be + imposed. If not specified, the default value of 8192 will be + used.

+
minSpareThreads +

The minimum number of threads always kept running. This includes both + active and idle threads. If not specified, the default of 10 + is used. If an executor is associated with this connector, this attribute + is ignored as the connector will execute tasks using the executor rather + than an internal thread pool. Note that if an executor is configured any + value set for this attribute will be recorded correctly but it will be + reported (e.g. via JMX) as -1 to make clear that it is not + used.

+
noCompressionUserAgents +

The value is a regular expression (using java.util.regex) + matching the user-agent header of HTTP clients for which + compression should not be used, + because these clients, although they do advertise support for the + feature, have a broken implementation. + The default value is an empty String (regexp matching disabled).

+
processorCache +

The protocol handler caches Processor objects to speed up performance. + This setting dictates how many of these objects get cached. + -1 means unlimited, default is 200. If not using + Servlet 3.0 asynchronous processing, a good default is to use the same as + the maxThreads setting. If using Servlet 3.0 asynchronous processing, a + good default is to use the larger of maxThreads and the maximum number of + expected concurrent requests (synchronous and asynchronous).

+
rejectIllegalHeaderName +

If an HTTP request is received that contains an illegal header name + (i.e. the header name is not a token) this setting determines if the + request will be rejected with a 400 response (true) or if the + illegal header be ignored (false). The default value is + false which will cause the request to be processed but the + illegal header will be ignored.

+
relaxedPathChars +

The HTTP/1.1 + specification requires that certain characters are %nn encoded when + used in URI paths. Unfortunately, many user agents including all the major + browsers are not compliant with this specification and use these + characters in unencoded form. To prevent Tomcat rejecting such requests, + this attribute may be used to specify the additional characters to allow. + If not specified, no addtional characters will be allowed. The value may + be any combination of the following characters: + " < > [ \ ] ^ ` { | } . Any other characters + present in the value will be ignored.

+
relaxedQueryChars +

The HTTP/1.1 + specification requires that certain characters are %nn encoded when + used in URI query strings. Unfortunately, many user agents including all + the major browsers are not compliant with this specification and use these + characters in unencoded form. To prevent Tomcat rejecting such requests, + this attribute may be used to specify the additional characters to allow. + If not specified, no addtional characters will be allowed. The value may + be any combination of the following characters: + " < > [ \ ] ^ ` { | } . Any other characters + present in the value will be ignored.

+
restrictedUserAgents +

The value is a regular expression (using java.util.regex) + matching the user-agent header of HTTP clients for which + HTTP/1.1 or HTTP/1.0 keep alive should not be used, even if the clients + advertise support for these features. + The default value is an empty String (regexp matching disabled).

+
server +

Overrides the Server header for the http response. If set, the value + for this attribute overrides the Tomcat default and any Server header set + by a web application. If not set, any value specified by the application + is used. If the application does not specify a value then + Apache-Coyote/1.1 is used. Unless you are paranoid, you won't + need this feature. +

+
socketBuffer +

The size (in bytes) of the buffer to be provided for socket + output buffering. -1 can be specified to disable the use of a buffer. + By default, a buffers of 9000 bytes will be used.

+
SSLEnabled +

Use this attribute to enable SSL traffic on a connector. + To turn on SSL handshake/encryption/decryption on a connector + set this value to true. + The default value is false. + When turning this value true you will want to set the + scheme and the secure attributes as well + to pass the correct request.getScheme() and + request.isSecure() values to the servlets + See SSL Support for more information. +

+
tcpNoDelay +

If set to true, the TCP_NO_DELAY option will be + set on the server socket, which improves performance under most + circumstances. This is set to true by default.

+
threadPriority +

The priority of the request processing threads within the JVM. + The default value is 5 (the value of the + java.lang.Thread.NORM_PRIORITY constant). See the JavaDoc + for the java.lang.Thread class for more details on what + this priority means. If an executor is associated + with this connector, this attribute is ignored as the connector will + execute tasks using the executor rather than an internal thread pool. Note + that if an executor is configured any value set for this attribute will be + recorded correctly but it will be reported (e.g. via JMX) as + -1 to make clear that it is not used.

+
upgradeAsyncWriteBufferSize +

The default size of the buffer to allocate to for asynchronous writes + that can not be completed in a single operation, specified in bytes. Data that can't be + written immediately will be stored in this buffer until it can be written. + If more data needs to be stored than space is available in the buffer than + the size of the buffer will be increased for the duration of the write. If + not specified the default value of 8192 will be used.

+
+ +
+ +

Java TCP socket attributes

+ +

The BIO, NIO and NIO2 implementation support the following Java TCP + socket attributes in addition to the common Connector and HTTP attributes + listed above.

+ +
+ Attribute + + Description +
socket.rxBufSize +

(int)The socket receive buffer (SO_RCVBUF) size in bytes. JVM default + used if not set.

+
socket.txBufSize +

(int)The socket send buffer (SO_SNDBUF) size in bytes. JVM default + used if not set.

+
socket.tcpNoDelay +

(bool)This is equivalent to standard attribute + tcpNoDelay.

+
socket.soKeepAlive +

(bool)Boolean value for the socket's keep alive setting + (SO_KEEPALIVE). JVM default used if not set.

+
socket.ooBInline +

(bool)Boolean value for the socket OOBINLINE setting. JVM default + used if not set.

+
socket.soReuseAddress +

(bool)Boolean value for the sockets reuse address option + (SO_REUSEADDR). JVM default used if not set.

+
socket.soLingerOn +

(bool)Boolean value for the sockets so linger option (SO_LINGER). + A value for the standard attribute connectionLinger + that is >=0 is equivalent to setting this to true. + A value for the standard attribute connectionLinger + that is <0 is equivalent to setting this to false. + Both this attribute and soLingerTime must be set else the + JVM defaults will be used for both.

+
socket.soLingerTime +

(int)Value in seconds for the sockets so linger option (SO_LINGER). + This is equivalent to standard attribute + connectionLinger. + Both this attribute and soLingerOn must be set else the + JVM defaults will be used for both.

+
socket.soTimeout +

This is equivalent to standard attribute + connectionTimeout.

+
socket.performanceConnectionTime +

(int)The first value for the performance settings. See + Socket Performance Options. + All three performance attributes must be set else the JVM defaults will + be used for all three.

+
socket.performanceLatency +

(int)The second value for the performance settings. See + Socket Performance Options. + All three performance attributes must be set else the JVM defaults will + be used for all three.

+
socket.performanceBandwidth +

(int)The third value for the performance settings. See + Socket Performance Options. + All three performance attributes must be set else the JVM defaults will + be used for all three.

+
socket.unlockTimeout +

(int) The timeout for a socket unlock. When a connector is stopped, it will try to release the acceptor thread by opening a connector to itself. + The default value is 250 and the value is in milliseconds

+
+
+ +

BIO specific configuration

+ +

The following attributes are specific to the BIO connector.

+ +
+ Attribute + + Description +
disableKeepAlivePercentage +

The percentage of processing threads that have to be in use before + HTTP keep-alives are disabled to improve scalability. Values less than + 0 will be changed to 0 and values greater than + 100 will be changed to 100. If not specified, + the default value is 75.

+
+ +
+ +

NIO specific configuration

+ +

The following attributes are specific to the NIO connector.

+ +
+ Attribute + + Description +
pollerThreadCount +

(int)The number of threads to be used to run for the polling events. + Default value is 1 per processor but not more than 2.
+ When accepting a socket, the operating system holds a global lock. So the benefit of + going above 2 threads diminishes rapidly. Having more than one thread is for + system that need to accept connections very rapidly. However usually just + increasing acceptCount will solve that problem. + Increasing this value may also be beneficial when a large amount of send file + operations are going on. +

+
pollerThreadPriority +

(int)The priority of the poller threads. + The default value is 5 (the value of the + java.lang.Thread.NORM_PRIORITY constant). See the JavaDoc + for the java.lang.Thread class for more details on what + this priority means.

+
selectorTimeout +

(int)The time in milliseconds to timeout on a select() for the + poller. This value is important, since connection clean up is done on + the same thread, so do not set this value to an extremely high one. The + default value is 1000 milliseconds.

+
useComet +

(bool)Whether to allow comet servlets or not. Default value is + true.

+
useSendfile +

(bool)Use this attribute to enable or disable sendfile capability. + The default value is true. Note that the use of sendfile + will disable any compression that Tomcat may otherwise have performed on + the response.

+
socket.directBuffer +

(bool)Boolean value, whether to use direct ByteBuffers or java mapped + ByteBuffers. If true then + java.nio.ByteBuffer.allocateDirect() is used to allocate + the buffers, if false then + java.nio.ByteBuffer.allocate() is used. The default value + is false.
+ When you are using direct buffers, make sure you allocate the + appropriate amount of memory for the direct memory space. On Sun's JDK + that would be something like -XX:MaxDirectMemorySize=256m. +

+
socket.directSslBuffer +

(bool)Boolean value, whether to use direct ByteBuffers or java mapped + ByteBuffers for the SSL buffers. If true then + java.nio.ByteBuffer.allocateDirect() is used to allocate + the buffers, if false then + java.nio.ByteBuffer.allocate() is used. The default value + is false.
+ When you are using direct buffers, make sure you allocate the + appropriate amount of memory for the direct memory space. On Oracle's JDK + that would be something like -XX:MaxDirectMemorySize=256m. +

+
socket.appReadBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a read ByteBuffer. This attribute controls the size of this buffer. By + default this read buffer is sized at 8192 bytes. For lower + concurrency, you can increase this to buffer more data. For an extreme + amount of keep alive connections, decrease this number or increase your + heap size.

+
socket.appWriteBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a write ByteBuffer. This attribute controls the size of this buffer. By + default this write buffer is sized at 8192 bytes. For low + concurrency you can increase this to buffer more response data. For an + extreme amount of keep alive connections, decrease this number or + increase your heap size.
+ The default value here is pretty low, you should up it if you are not + dealing with tens of thousands concurrent connections.

+
socket.bufferPool +

(int)The NIO connector uses a class called NioChannel that holds + elements linked to a socket. To reduce garbage collection, the NIO + connector caches these channel objects. This value specifies the size of + this cache. The default value is 500, and represents that + the cache will hold 500 NioChannel objects. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.bufferPoolSize +

(int)The NioChannel pool can also be size based, not used object + based. The size is calculated as follows:
+ NioChannel + buffer size = read buffer size + write buffer size
+ SecureNioChannel buffer size = application read buffer size + + application write buffer size + network read buffer size + + network write buffer size
+ The value is in bytes, the default value is 1024*1024*100 + (100MB).

+
socket.processorCache +

(int)Tomcat will cache SocketProcessor objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.keyCache +

(int)Tomcat will cache KeyAttachment objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.eventCache +

(int)Tomcat will cache PollerEvent objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
selectorPool.maxSelectors +

(int)The max selectors to be used in the pool, to reduce selector + contention. Use this option when the command line + org.apache.tomcat.util.net.NioSelectorShared value is set + to false. Default value is 200.

+
selectorPool.maxSpareSelectors +

(int)The max spare selectors to be used in the pool, to reduce + selector contention. When a selector is returned to the pool, the system + can decide to keep it or let it be GC'd. Use this option when the + command line org.apache.tomcat.util.net.NioSelectorShared + value is set to false. Default value is -1 (unlimited).

+
command-line-options +

The following command line options are available for the NIO + connector:
+ -Dorg.apache.tomcat.util.net.NioSelectorShared=true|false + - default is true. Set this value to false if you wish to + use a selector for each thread. When you set it to false, you can + control the size of the pool of selectors by using the + selectorPool.maxSelectors attribute.

+
oomParachute +

(int)The NIO connector implements an OutOfMemoryError strategy called + parachute. It holds a chunk of data as a byte array. In case of an OOM, + this chunk of data is released and the error is reported. This will give + the VM enough room to clean up. The oomParachute represents + the size in bytes of the parachute(the byte array). The default value is + 1024*1024(1MB). Please note, this only works for OOM errors + regarding the Java Heap space, and there is absolutely no guarantee + that you will be able to recover at all. If you have an OOM outside of + the Java Heap, then this parachute trick will not help. +

+
+
+ +

NIO2 specific configuration

+ +

The following attributes are specific to the NIO2 connector.

+ +
+ Attribute + + Description +
useCaches +

(bool)Use this attribute to enable or disable object caching to + reduce the amount of GC objects produced. + The default value is false.

+
useComet +

(bool)Whether to allow comet servlets or not. Default value is + true.

+
useSendfile +

(bool)Use this attribute to enable or disable sendfile capability. + The default value is true. Note that the use of sendfile + will disable any compression that Tomcat may otherwise have performed on + the response.

+
socket.directBuffer +

(bool)Boolean value, whether to use direct ByteBuffers or java mapped + ByteBuffers. If true then + java.nio.ByteBuffer.allocateDirect() is used to allocate + the buffers, if false then + java.nio.ByteBuffer.allocate() is used. The default value + is false.
+ When you are using direct buffers, make sure you allocate the + appropriate amount of memory for the direct memory space. On Sun's JDK + that would be something like -XX:MaxDirectMemorySize=256m. +

+
socket.directSslBuffer +

(bool)Boolean value, whether to use direct ByteBuffers or java mapped + ByteBuffers for the SSL buffers. If true then + java.nio.ByteBuffer.allocateDirect() is used to allocate + the buffers, if false then + java.nio.ByteBuffer.allocate() is used. The default value + is false.
+ When you are using direct buffers, make sure you allocate the + appropriate amount of memory for the direct memory space. On Oracle's JDK + that would be something like -XX:MaxDirectMemorySize=256m. +

+
socket.appReadBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a read ByteBuffer. This attribute controls the size of this buffer. By + default this read buffer is sized at 8192 bytes. For lower + concurrency, you can increase this to buffer more data. For an extreme + amount of keep alive connections, decrease this number or increase your + heap size.

+
socket.appWriteBufSize +

(int)Each connection that is opened up in Tomcat get associated with + a write ByteBuffer. This attribute controls the size of this buffer. By + default this write buffer is sized at 8192 bytes. For low + concurrency you can increase this to buffer more response data. For an + extreme amount of keep alive connections, decrease this number or + increase your heap size.
+ The default value here is pretty low, you should up it if you are not + dealing with tens of thousands concurrent connections.

+
socket.bufferPoolSize +

(int)The NIO2 connector uses a class called Nio2Channel that holds + elements linked to a socket. To reduce garbage collection, the NIO2 + connector caches these channel objects. This value specifies the size of + this cache. The default value is 500, and represents that + the cache will hold 500 Nio2Channel objects. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.processorCache +

(int)Tomcat will cache SocketProcessor objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
socket.socketWrapperCache +

(int)Tomcat will cache SocketWrapper objects to reduce garbage + collection. The integer value specifies how many objects to keep in the + cache at most. The default is 500. Other values are + -1 for unlimited cache and 0 for no cache.

+
oomParachute +

(int)The NIO2 connector implements an OutOfMemoryError strategy called + parachute. It holds a chunk of data as a byte array. In case of an OOM, + this chunk of data is released and the error is reported. This will give + the VM enough room to clean up. The oomParachute represents + the size in bytes of the parachute(the byte array). The default value is + 1024*1024(1MB). Please note, this only works for OOM errors + regarding the Java Heap space, and there is absolutely no guarantee + that you will be able to recover at all. If you have an OOM outside of + the Java Heap, then this parachute trick will not help. +

+
+
+ +

APR/native specific configuration

+ +

The following attributes are specific to the APR/native connector.

+ +
+ Attribute + + Description +
deferAccept +

Sets the TCP_DEFER_ACCEPT flag on the listening socket + for this connector. The default value is true where + TCP_DEFER_ACCEPT is supported by the operating system, + otherwise it is false.

+
pollerSize +

Amount of sockets that the poller responsible for polling kept alive + connections can hold at a given time. Extra connections will be closed + right away. The default value is 8192, corresponding to 8192 keep-alive + connections. This is a synonym for maxConnections.

+
pollerThreadCount +

Number of threads used to poll kept alive connections. On Windows the + default is chosen so that the sockets managed by each thread is + less than 1024. For Linux the default is 1. Changing the default on + Windows is likely to have a negative performance impact.

+
pollTime +

Duration of a poll call in microseconds. Lowering this value will + slightly decrease latency of connections being kept alive in some cases, + but will use more CPU as more poll calls are being made. The default + value is 2000 (2ms).

+
sendfileSize +

Amount of sockets that the poller responsible for sending static + files asynchronously can hold at a given time. Extra connections will be + closed right away without any data being sent (resulting in a zero + length file on the client side). Note that in most cases, sendfile is a + call that will return right away (being taken care of "synchronously" by + the kernel), and the sendfile poller will not be used, so the amount of + static files which can be sent concurrently is much larger than the + specified amount. The default value is 1024.

+
sendfileThreadCount +

Number of threads used service sendfile sockets. On Windows the + default is chosen so that the sockets managed by each thread is + less than 1024. For Linux the default is 1. Changing the default on + Windows is likely to have a negative performance impact.

+
threadPriority +

(int)The priority of the acceptor and poller threads. + The default value is 5 (the value of the + java.lang.Thread.NORM_PRIORITY constant). See the JavaDoc + for the java.lang.Thread class for more details on what + this priority means.

+
useComet +

(bool)Whether to allow comet servlets or not. Default value is + true.

+
useSendfile +

(bool)Use this attribute to enable or disable sendfile capability. + The default value is true. Note that the use of sendfile + will disable any compression that Tomcat may otherwise have performed on + the response.

+
+ +
+ +

Nested Components

+ +

None at this time.

+ +

Special Features

+ + +

HTTP/1.1 and HTTP/1.0 Support

+ +

This Connector supports all of the required features + of the HTTP/1.1 protocol, as described in RFC 2616, including persistent + connections, pipelining, expectations and chunked encoding. If the client + (typically a browser) supports only HTTP/1.0, the + Connector will gracefully fall back to supporting this + protocol as well. No special configuration is required to enable this + support. The Connector also supports HTTP/1.0 + keep-alive.

+ +

RFC 2616 requires that HTTP servers always begin their responses with + the highest HTTP version that they claim to support. Therefore, this + Connector will always return HTTP/1.1 at + the beginning of its responses.

+ +
+ + +

Proxy Support

+ +

The proxyName and proxyPort attributes can + be used when Tomcat is run behind a proxy server. These attributes + modify the values returned to web applications that call the + request.getServerName() and request.getServerPort() + methods, which are often used to construct absolute URLs for redirects. + Without configuring these attributes, the values returned would reflect + the server name and port on which the connection from the proxy server + was received, rather than the server name and port to whom the client + directed the original request.

+ +

For more information, see the + Proxy Support HOW-TO.

+ +
+ + + +

SSL Support

+ +

You can enable SSL support for a particular instance of this + Connector by setting the SSLEnabled attribute to + true.

+ +

You will also need to set the scheme and secure + attributes to the values https and true + respectively, to pass correct information to the servlets.

+ +

The BIO, NIO and NIO2 connectors use the JSSE SSL whereas the APR/native + connector uses OpenSSL. Therefore, in addition to using different attributes + to configure SSL, the APR/native connector also requires keys and certificates + to be provided in a different format.

+ +

For more information, see the + SSL Configuration HOW-TO.

+ +

SSL Support - BIO, NIO and NIO2

+ +

The BIO, NIO and NIO2 connectors use the following attributes to configure SSL: +

+ +
+ Attribute + + Description +
algorithm +

The certificate encoding algorithm to be used. This defaults to + KeyManagerFactory.getDefaultAlgorithm() which returns + SunX509 for Sun JVMs. IBM JVMs return + IbmX509. For other vendors, consult the JVM + documentation for the default value.

+
allowUnsafeLegacyRenegotiation +

Is unsafe legacy TLS renegotiation allowed which is likely to expose + users to CVE-2009-3555, a man-in-the-middle vulnerability in the TLS + protocol that allows an attacker to inject arbitrary data into the user's + request. If not specified, a default of false is used. This + attribute only has an effect if the JVM does not support RFC 5746 as + indicated by the presence of the pseudo-ciphersuite + TLS_EMPTY_RENEGOTIATION_INFO_SCSV. This is available JRE/JDK 6 update 22 + onwards. Where RFC 5746 is supported the renegotiation - including support + for unsafe legacy renegotiation - is controlled by the JVM configuration. +

+
useServerCipherSuitesOrder +

+ Set to true to enforce the server's cipher order + (from the ciphers setting). Set to false + to choose the first acceptable cipher suite presented by the client. + Use of this feature requires Java 8 or later. + Default is undefined, leaving the choice up to the JSSE + implementation. +

+
ciphers +

If specified and using ',' as a separator, only the ciphers that are + listed and supported by the SSL implementation will be used. + The ciphers are specified using the JSSE cipher naming convention. The + special value of ALL will enable all supported ciphers. This + will include many that are not secure. ALL is intended for + testing purposes only.

+

The list can also use ':' as a separator, in that case + it will use the OpenSSL syntax (see OpenSSL documentation for the list + of ciphers supported and the syntax). The behaviour of this filtering is + kept aligned with the behaviour of the OpenSSL 1.0.2 stable branch.

+

If not specified, a default (using the OpenSSL notation) of + HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA will be used + when running on Java 8 or later. On Java 7, !DHE will be + added to this default when using a JSSE based connector.

+

Note that Java does not treat the order in which ciphers are defined as + an order of preference. See useServerCipherSuitesOrder.

+
clientAuth +

Set to true if you want the SSL stack to require a + valid certificate chain from the client before accepting a connection. + Set to want if you want the SSL stack to request a client + Certificate, but not fail if one isn't presented. A false + value (which is the default) will not require a certificate chain + unless the client requests a resource protected by a security + constraint that uses CLIENT-CERT authentication.

+
clientCertProvider +

When client certificate information is presented in a form other than + instances of java.security.cert.X509Certificate it needs to + be converted before it can be used and this property controls which JSSE + provider is used to perform the conversion. For example it is used with + the AJP connectors, the HTTP APR connector and + with the + org.apache.catalina.valves.SSLValve. If not specified, the default + provider will be used.

+
crlFile +

The certificate revocation list to be used to verify client + certificates. If not defined, client certificates will not be checked + against a certificate revocation list. The file may be specified using a + URL, an absolute path or a relative (to CATALINA_BASE) path.

+
keyAlias +

The alias used for the server key and certificate in the keystore. If + not specified, the first key read from the keystore will be used. The + order in which keys are read from the keystore is implementation + dependent. It may not be the case that keys are read from the keystore in + the same order as they were added. If more than one key is present in the + keystore it is strongly recommended that a keyAlias is configured to + ensure that the correct key is used.

+
keyPass +

The password used to access the server certificate from the + specified keystore file. The default value is "changeit". +

+
keystoreFile +

The pathname of the keystore file where you have stored the + server certificate to be loaded. By default, the pathname is + the file ".keystore" in the operating system home + directory of the user that is running Tomcat. If your + keystoreType doesn't need a file use "" + (empty string) for this parameter. The file may be specified using a + URL, an absolute path or a relative (to CATALINA_BASE) path.

+
keystorePass +

The password used to access the specified keystore file. The default + value is the value of the keyPass attribute. +

+
keystoreProvider +

The name of the keystore provider to be used for the server + certificate. If not specified, the list of registered providers is + traversed in preference order and the first provider that supports the + keystoreType is used. +

+
keystoreType +

The type of keystore file to be used for the server certificate. + If not specified, the default value is "JKS".

+
sessionCacheSize +

The number of SSL sessions to maintain in the session cache. Use 0 to + specify an unlimited cache size. If not specified, a default of 0 is + used.

+
sessionTimeout +

The time, in seconds, after the creation of an SSL session that it will + timeout. Use 0 to specify an unlimited timeout. If not specified, a + default of 86400 (24 hours) is used.

+
sslEnabledProtocols +

The comma separated list of SSL protocols to support for HTTPS + connections. If specified, only the protocols that are listed and + supported by the SSL implementation will be enabled. If not specified, + the JVM default (excluding SSLv2 and SSLv3 if the JVM enables either or + both of them by default) is used. The permitted values may be obtained + from the JVM documentation for the allowed values for + SSLSocket.setEnabledProtocols() e.g. + + Oracle Java 7. Note: There is overlap between this attribute and + sslProtocol.

+
sslImplementationName +

The class name of the SSL implementation to use. If not specified, the + default of org.apache.tomcat.util.net.jsse.JSSEImplementation + will be used which wraps JVM's default JSSE provider. Note that the + JVM can be configured to use a different JSSE provider as the default.

+
sslProtocol +

The SSL protocol(s) to use (a single value may enable multiple + protocols - see the JVM documentation for details). If not specified, the + default is TLS. The permitted values may be obtained from the + JVM documentation for the allowed values for algorithm when creating an + SSLContext instance e.g. + + Oracle Java 7. Note: There is overlap between this attribute and + sslEnabledProtocols.

+
trustManagerClassName +

The name of a custom trust manager class to use to validate client + certificates. The class must have a zero argument constructor and must + also implement javax.net.ssl.X509TrustManager. If this + attribute is set, the trust store attributes may be ignored. +

+
trustMaxCertLength +

The maximum number of intermediate certificates that will be allowed + when validating client certificates. If not specified, the default value + of 5 will be used.

+
truststoreAlgorithm +

The algorithm to use for truststore. If not specified, the default + value returned by + javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm() is + used.

+
truststoreFile +

The trust store file to use to validate client certificates. The + default is the value of the javax.net.ssl.trustStore system + property. If neither this attribute nor the default system property is + set, no trust store will be configured. The file may be specified using a + URL, an absolute path or a relative (to CATALINA_BASE) path.

+
truststorePass +

The password to access the trust store. The default is the value of the + javax.net.ssl.trustStorePassword system property. If that + property is null, no trust store password will be configured. If an + invalid trust store password is specified, a warning will be logged and an + attempt will be made to access the trust store without a password which + will skip validation of the trust store contents.

+
truststoreProvider +

The name of the truststore provider to be used for the server + certificate. The default is the value of the + javax.net.ssl.trustStoreProvider system property. If + that property is null, the value of keystoreProvider is used + as the default. If neither this attribute, the default system property nor + keystoreProvideris set, the list of registered providers is + traversed in preference order and the first provider that supports the + truststoreType is used. +

+
truststoreType +

The type of key store used for the trust store. The default is the + value of the javax.net.ssl.trustStoreType system property. If + that property is null, the value of keystoreType is used as + the default.

+
+ +
+ +

SSL Support - APR/Native

+ +

When APR/native is enabled, the HTTPS connector will use a socket poller + for keep-alive, increasing scalability of the server. It also uses OpenSSL, + which may be more optimized than JSSE depending on the processor being used, + and can be complemented with many commercial accelerator components. Unlike + the HTTP connector, the HTTPS connector cannot use sendfile to optimize static + file processing.

+ +

The HTTPS APR/native connector has the same attributes than the HTTP + APR/native connector, but adds OpenSSL specific ones. For the full details on + using OpenSSL, please refer to OpenSSL documentations and the many books + available for it (see the Official OpenSSL + website). The SSL specific attributes for the APR/native connector are: +

+ +
+ Attribute + + Description +
SSLCACertificateFile +

See + the mod_ssl documentation.

+
SSLCACertificatePath +

See + the mod_ssl documentation.

+
SSLCARevocationFile +

See + the mod_ssl documentation.

+
SSLCARevocationPath +

See + the mod_ssl documentation.

+
SSLCertificateChainFile +

See + the mod_ssl documentation.

+
SSLCACertificateFile +

Name of the file that contains the concatenated certificates for the + trusted certificate authorities. The format is PEM-encoded.

+
SSLCACertificatePath +

Name of the directory that contains the certificates for the trusted + certificate authorities. The format is PEM-encoded.

+
SSLCARevocationFile +

Name of the file that contains the concatenated certificate revocation + lists for the certificate authorities. The format is PEM-encoded.

+
SSLCARevocationPath +

Name of the directory that contains the certificate revocation lists + for the certificate authorities. The format is PEM-encoded.

+
SSLCertificateChainFile +

Name of the file that contains concatenated certifcates for the + certificate authorities which form the certifcate chain for the server + certificate. The format is PEM-encoded.

+
SSLCertificateFile +

Name of the file that contains the server certificate. The format is + PEM-encoded.

+

In addition to the certificate, the file can also contain as optional + elements DH parameters and/or an EC curve name for ephemeral keys, as + generated by openssl dhparam and openssl ecparam, + respectively. The output of the respective OpenSSL command can simply + be concatenated to the certificate file. This feature needs APR/native + version 1.1.34 or later.

+
SSLCertificateKeyFile +

Name of the file that contains the server private key. The format is + PEM-encoded. The default value is the value of "SSLCertificateFile" and in + this case both certificate and private key have to be in this file (NOT + RECOMMENDED).

+
SSLCipherSuite +

Ciphers which may be used for communicating with clients. The default + is HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5. See the OpenSSL + documentation for details of the syntax for this attribute.

+
SSLDisableCompression +

Disables compression if set to true and OpenSSL supports + disabling compression. Default is false which inherits the + default compression setting in OpenSSL.

+
SSLHonorCipherOrder +

Set to true to enforce the server's cipher order + (from the SSLCipherSuite setting) instead of allowing + the client to choose the cipher (which is the default).

+
SSLPassword +

Pass phrase for the encrypted private key. If "SSLPassword" is not + provided, the callback function should prompt for the pass phrase.

+
SSLProtocol +

The names of the protocols to support when communicating with clients. + This should be a list of any combination of the following: +

+
  • SSLv2
  • SSLv3
  • TLSv1
  • +
  • TLSv1.1
  • TLSv1.2
  • all
+

Each token in the list can be prefixed with a plus sign ("+") + or a minus sign ("-"). A plus sign adds the protocol, a minus sign + removes it form the current list. The list is built starting from + an empty list.

+

The token all is an alias for + TLSv1+TLSv1.1+TLSv1.2.

+

If more than one protocol is specified for an OpenSSL + based secure connector it will always support SSLv2Hello. If a + single protocol is specified it will not support + SSLv2Hello.

+

Note that SSLv2 and SSLv3 are inherently + unsafe.

+

If not specified, the default value of all will be + used.

+
SSLVerifyClient +

Ask client for certificate. The default is "none", meaning the client + will not have the opportunity to submit a certificate. Other acceptable + values include "optional", "require" and "optionalNoCA".

+
SSLVerifyDepth +

Maximum verification depth for client certificates. The default is + "10".

+
SSLDisableSessionTickets +

Disables use of TLS session tickets (RFC 5077) if set to + true. Default is false. Note that when TLS + session tickets are in use, the full peer certificate chain will only be + available on the first connection. Subsequent connections (that use a + ticket to estrablish the TLS session) will only have the peer certificate, + not the full chain.

+
+ +
+ +
+

Connector Comparison

+ +

Below is a small chart that shows how the connectors differ.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Java Blocking Connector
BIO
Java Nio Connector
NIO
Java Nio2 Connector
NIO2
APR/native Connector
APR
ClassnameHttp11ProtocolHttp11NioProtocolHttp11Nio2ProtocolHttp11AprProtocol
Tomcat Version3.x onwards6.x onwards8.x onwards5.5.x onwards
Support PollingNOYESYESYES
Polling SizeN/AmaxConnectionsmaxConnectionsmaxConnections
Read Request HeadersBlockingNon BlockingNon BlockingBlocking
Read Request BodyBlockingBlockingBlockingBlocking
Write Response Headers and BodyBlockingBlockingBlockingBlocking
Wait for next RequestBlockingNon BlockingNon BlockingNon Blocking
SSL SupportJava SSLJava SSLJava SSLOpenSSL
SSL HandshakeBlockingNon blockingNon blockingBlocking
Max ConnectionsmaxConnectionsmaxConnectionsmaxConnectionsmaxConnections
+ +
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/index.html b/test.dockerapp/tomcat/webapps/docs/config/index.html new file mode 100644 index 0000000..2d29788 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/index.html @@ -0,0 +1,107 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - Overview

Overview

Overview

+ +

This manual contains reference information about all of the configuration +directives that can be included in a conf/server.xml file to +configure the behavior of the Tomcat Servlet/JSP container. It does not +attempt to describe which configuration directives should be used to perform +specific tasks - for that, see the various HOW-TO documents on the +main index page.

+ +

Tomcat configuration files are formatted as schemaless XML; elements and +attributes are case-sensitive. Apache Ant-style variable substitution +is supported; a system property with the name propname may be +used in a configuration file using the syntax ${propname}. All +system properties are available including those set using the -D +syntax, those automatically made available by the JVM and those configured in +the $CATALINA_BASE/conf/catalina.properties file. +

+ +

The configuration element descriptions are organized into the following +major categories:

+
    +
  • Top Level Elements - <Server> is the + root element of the entire configuration file, while + <Service> represents a group of Connectors that is + associated with an Engine.
  • +
  • Connectors - Represent the interface between external + clients sending requests to (and receiving responses from) a particular + Service.
  • +
  • Containers - Represent components whose function is to + process incoming requests, and create the corresponding responses. + An Engine handles all requests for a Service, a Host handles all requests + for a particular virtual host, and a Context handles all requests for a + specific web application.
  • +
  • Nested Components - Represent elements that can be + nested inside the element for a Container. Some elements can be nested + inside any Container, while others can only be nested inside a + Context.
  • +
+ +

For each element, the corresponding documentation follows this general +outline:

+
    +
  • Introduction - Overall description of this particular + component. There will be a corresponding Java interface (in + the org.apache.catalina package) that is implemented by one + or more standard implementations.
  • +
  • Attributes - The set of attributes that are legal for + this element. Generally, this will be subdivided into Common + attributes that are supported by all implementations of the corresponding + Java interface, and Standard Implementation attributes that are + specific to a particular Java class that implements this interface. + The names of required attributes are bolded.
  • +
  • Nested Components - Enumerates which of the Nested + Components can be legally nested within this element.
  • +
  • Special Features - Describes the configuration of a large + variety of special features (specific to each element type) that are + supported by the standard implementation of this interface.
  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/jar-scan-filter.html b/test.dockerapp/tomcat/webapps/docs/config/jar-scan-filter.html new file mode 100644 index 0000000..e090095 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/jar-scan-filter.html @@ -0,0 +1,183 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Jar Scan Filter Component

The Jar Scan Filter Component

Table of Contents

Introduction

+ +

The Jar Scan Filter element represents the component that + filters results from the Jar Scanner before + they are passed back to the application. It is typically used to skip the + scanning of JARs that are known not to be relevant to some or all types of + scan.

+ +

A Jar Scan Filter element MAY be nested inside a + Jar Scanner component.

+ +

For example you can specify additional jar files when scanning for pluggable + features:

+
<Context>
+  ...
+  <JarScanner>
+    <JarScanFilter
+        pluggabilityScan="${tomcat.util.scan.StandardJarScanFilter.jarsToScan},
+                       my_pluggable_feature.jar"/>
+  </JarScanner>
+  ...
+</Context>
+ +

If a Jar Scan Filter element is not included, a default Jar Scan Filter + configuration will be created automatically, which is sufficient for most + requirements.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Jar Scan Filter + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.tomcat.JarScanFilter interface. + If not specified, the standard value (defined below) will be used.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of Jar Scan Filter is + org.apache.tomcat.util.scan.StandardJarScanFilter. + Additional attributes that it supports (in addition to the common attributes + listed above) are listed in the table.

+ +

The values for pluggabilitySkip, + pluggabilityScan, tldSkip, + tldScan attributes are lists of file name pattern. The + patterns are separated by comma (','). The leading and trailing whitespace + characters in a pattern are ignored. The patterns are matched + case-sensitively. The following two special characters are supported:

+ +
    +
  • '*' - means zero or more characters,
  • +
  • '?' - means one and only one character.
  • +
+ +

Note that excluding a JAR from the pluggability scan will prevent a + ServletContainerInitializer from being loaded from a web application JAR + (i.e. one located in /WEB-INF/lib) but it will not prevent + a ServletContainerInitializer from being loaded from the container (Tomcat). + To prevent a ServletContainerInitializer provided by container from being + loaded, use the containerSciFilter property of the + Context.

+ +
+ Attribute + + Description +
pluggabilitySkip +

The comma separated list of JAR file name patterns + to skip when scanning for pluggable features introduced by Servlet 3.0 + specification. If not specified, the default is obtained from the + tomcat.util.scan.StandardJarScanFilter.jarsToSkip system + property.

+
pluggabilityScan +

The comma separated list of JAR file name patterns + to scan when scanning for pluggable features introduced by Servlet 3.0 + specification. If not specified, the default is obtained from the + tomcat.util.scan.StandardJarScanFilter.jarsToScan system + property.

+
defaultPluggabilityScan +

Controls if JARs are scanned or skipped by default when scanning + for the pluggable features. + If true, a JAR is scanned when its name either matches + none of pluggabilitySkip patterns or + any of pluggabilityScan patterns. + If false, a JAR is scanned when its name matches + any of pluggabilityScan patterns and + none of pluggabilitySkip patterns. + If not specified, the default value is true.

+
tldSkip +

The comma separated list of JAR file name patterns + to skip when scanning for tag libraries (TLDs). + If not specified, the default is obtained + from the tomcat.util.scan.StandardJarScanFilter.jarsToSkip + system property.

+
tldScan +

The comma separated list of JAR file name patterns + to scan when scanning for tag libraries (TLDs). + If not specified, the default is obtained + from the tomcat.util.scan.StandardJarScanFilter.jarsToScan + system property.

+
defaultTldScan +

Controls if JARs are scanned or skipped by default when scanning + for TLDs. + If true, a JAR is scanned when its name either matches + none of tldSkip patterns or + any of tldScan patterns. + If false, a JAR is scanned when its name matches + any of tldScan patterns and + none of tldSkip patterns. + If not specified, the default value is true.

+
+ +
+ + +

Nested Components

+

No components may be nested inside a Jar Scan Filter element. +

+

Special Features

+

No special features are associated with a Jar Scan Filter + element.

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/jar-scanner.html b/test.dockerapp/tomcat/webapps/docs/config/jar-scanner.html new file mode 100644 index 0000000..3309efb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/jar-scanner.html @@ -0,0 +1,141 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Jar Scanner Component

The Jar Scanner Component

Table of Contents

Introduction

+ +

The Jar Scanner element represents the component that is + used to scan the web application for JAR files and directories of class files. + It is typically used during web application start to identify configuration + files such as TLDs or web-fragment.xml files that must be processed as part of + the web application initialisation.

+ +

A Jar Scanner element MAY be nested inside a + Context component.

+ +

For example you can include the bootstrap classpath when scanning for jar + files:

+
<Context>
+  ...
+  <JarScanner scanBootstrapClassPath="true"/>
+  ...
+</Context>
+ +

If a Jar Scanner element is not included, a default Jar Scanner configuration + will be created automatically, which is sufficient for most requirements.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Jar Scanner + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.tomcat.JarScanner interface. + If not specified, the standard value (defined below) will be used.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of Jar Scanner is + org.apache.tomcat.util.scan.StandardJarScanner. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
scanAllDirectories +

If true, any directories found on the classpath will be + checked to see if they are expanded JAR files. + The default is false.

+

Tomcat determines if a directory is an expanded JAR file by looking + for a META-INF sub-directory. Only if the META-INF sub-directory exists, + the directory is assumed to be an expanded JAR file. Note that for scans + for matches to @HandlesTypes annotations, all directories + will be scanned irrespective of the presence or not of a META-INF + sub-directory.

+
scanAllFiles +

If true, any files found on the classpath will be checked + to see if they are Jar files rather than relying on the file extension + being .jar. The default is false.

+
scanClassPath +

If true, the full web application classpath, including + the shared and common classloaders and the system classpath (but not the + bootstrap classpath) will be scanned for Jar files in addition to the web + application. The default is true.

+
scanBootstrapClassPath +

If scanClassPath is true and this is + true the bootstrap classpath will also be scanned for Jar + files. The default is false.

+
scanManifest +

If true, the Manifest files of any JARs found will be + scanned for additional class path entries and those entries will be added + to the URLs to scan. The default is true.

+
+ +
+ + +

Nested Components

+

Only a Jar Scan Filter may be nested + inside a Jar Scanner element.

+

Special Features

+

No special features are associated with a Jar Scanner + element.

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/listeners.html b/test.dockerapp/tomcat/webapps/docs/config/listeners.html new file mode 100644 index 0000000..40243fa --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/listeners.html @@ -0,0 +1,556 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The LifeCycle Listener Component

The LifeCycle Listener Component

Table of Contents

Introduction

+ +

A Listener element defines a component that performs + actions when specific events occur, usually Tomcat starting or Tomcat + stopping.

+ +

Listeners may be nested inside a Server, + Engine, Host or + Context. Some Listeners are only intended to be + nested inside specific elements. These constraints are noted in the + documentation below.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Listener + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.LifecycleListener + interface.

+
+ +
+ +

Nested Components

+ +

No element may be nested inside a Listener.

+ +

Standard Implementations

+ +

Unlike most Catalina components, there are several standard + Listener implementations available. As a result, + the className attribute MUST be used to select the + implementation you wish to use.

+ +

APR Lifecycle Listener - org.apache.catalina.core.AprLifecycleListener

+ +

The APR Lifecycle Listener checks for the presence of + the APR/native library and loads the library if it is present. For more + information see the APR/native guide.

+ +

This listener must only be nested within Server + elements.

+ +

The following additional attributes are supported by the APR + Lifecycle Listener:

+ +
+ Attribute + + Description +
SSLEngine +

Name of the SSLEngine to use. off: do not use SSL, + on: use SSL but no specific ENGINE.

+

The default value is on. This initializes the + native SSL engine, which must be enabled in the APR/native connector by + the use of the SSLEnabled attribute.

+

See the Official OpenSSL website + for more details on supported SSL hardware engines and manufacturers. +

+
SSLRandomSeed +

Entropy source used to seed the SSLEngine's PRNG. The default value + is builtin. On development systems, you may want to set + this to /dev/urandom to allow quicker start times.

+
FIPSMode +

Set to on to request that OpenSSL be in FIPS mode + (if OpenSSL is already in FIPS mode, it will remain in FIPS mode). + Set to enter to force OpenSSL to enter FIPS mode (an error + will occur if OpenSSL is already in FIPS mode). + Set to require to require that OpenSSL already be + in FIPS mode (an error will occur if OpenSSL is not already in FIPS + mode).

+

FIPS mode requires you to have a FIPS-capable OpenSSL library which + you must build yourself. + If this attribute is set to any of the above values, the SSLEngine + must be enabled as well.

+

The default value is off.

+
+ +
+ +

Global Resources Lifecycle Listener - org.apache.catalina.mbeans.GlobalResourcesLifecycleListener

+ +

The Global Resources Lifecycle Listener initializes the + Global JNDI resources defined in server.xml as part of the Global Resources element. Without this + listener, none of the Global Resources will be available.

+ +

This listener must only be nested within Server + elements.

+ +

No additional attributes are supported by the Global Resources + Lifecycle Listener.

+ +
+ +

JRE Memory Leak Prevention Listener - org.apache.catalina.core.JreMemoryLeakPreventionListener

+ +

The JRE Memory Leak Prevention Listener provides + work-arounds for known places where the Java Runtime environment uses + the context class loader to load a singleton as this will cause a memory + leak if a web application class loader happens to be the context class + loader at the time. The work-around is to initialise these singletons when + this listener starts as Tomcat's common class loader is the context class + loader at that time. It also provides work-arounds for known issues that + can result in locked JAR files.

+ +

This listener must only be nested within Server + elements.

+ +

The following additional attributes are supported by the JRE + Memory Leak Prevention Listener:

+ +
+ Attribute + + Description +
appContextProtection +

Enables protection so that calls to + sun.awt.AppContext.getAppContext() triggered by a web + application do not result in a memory leak. Note that enabling this + protection will trigger a requirement for a graphical environment unless + Java is started in head-less mode. The default is false. + This protection is disabled if running on Java 8 onwards since the leak + has been fixed for Java 8 onwards. +

+
AWTThreadProtection +

Enables protection so that calls to + java.awt.Toolkit.getDefaultToolkit() triggered by a web + application do not result in a memory leak. + Defaults to false because an AWT thread is launched. This + protection is disabled if running on Java 9 onwards since the leak has + been fixed for Java 9 onwards.

+
classesToInitialize +

List of comma-separated fully qualified class names to load and initialize + during the startup of this Listener. This allows to pre-load classes that are + known to provoke classloader leaks if they are loaded during a request + processing. Non-JRE classes may be referenced, like + oracle.jdbc.driver.OracleTimeoutThreadPerVM. + The default value is empty, but specific JRE classes are loaded by other leak + protection features managed by other attributes of this Listener.

+
driverManagerProtection +

The first use of java.sql.DriverManager will trigger the + loading of JDBC Driver in the current class loader. The web + application level memory leak protection can take care of this in most + cases but triggering the loading here has fewer side-effects. The + default is true.

+
forkJoinCommonPoolProtection +

Enables protection so the threads created for + ForkJoinPool.commonPool() do not result in a memory leak. + The protection is enabled by setting the + java.util.concurrent.ForkJoinPool.common.threadFactory + system property. If this property is set when Tomcat starts, Tomcat will + not over-ride it even if this protection is explicitly enabled. The + default is true. This protection is only used when running + on Java 8. The common pool does not exist in earlier versions and the + leak has been fixed for Java 9 onwards.

+
gcDaemonProtection +

Enables protection so that calls to + sun.misc.GC.requestLatency(long) triggered by a web + application do not result in a memory leak. Use of RMI is likely to + trigger a call to this method. A side effect of enabling this protection + is the creation of a thread named "GC Daemon". The protection uses + reflection to access internal Sun classes and may generate errors on + startup on non-Sun JVMs. The default is true. This + protection is disabled if running on Java 9 onwards since the leak has + been fixed for Java 9 onwards.

+
ldapPoolProtection +

Enables protection so that the PoolCleaner thread started by + com.sun.jndi.ldap.LdapPoolManager does not result in a + memory leak. The thread is started the first time the + LdapPoolManager class is used if the system property + com.sun.jndi.ldap.connect.pool.timeout is set to a value + greater than 0. Without this protection, if a web application uses this + class the PoolCleaner thread will be configured with the thread's + context class loader set to the web application class loader which in + turn will trigger a memory leak on reload. Defaults to + true. This protection is disabled if running on Java 9 + onwards since the leak has been fixed for Java 9 onwards.

+
securityLoginConfigurationProtection +

Enables protection so that usage of the + javax.security.auth.login.Configuration class by a web + application does not provoke a memory leak. The first access of this + class will trigger the initializer that will retain a static reference + to the context class loader. The protection loads the class with the + system class loader to ensure that the static initializer is not + triggered by a web application. Defaults to true. This + protection is disabled if running on Java 8 onwards since the leak has + been fixed for Java 8 onwards.

+
securityPolicyProtection +

Enables protection so that usage of the deprecated + javax.security.auth.Policy class by a web application does not + result in a memory leak. The first access of this class will trigger the + static initializer that will retain a static reference to the context + class loader. The protection calls the getPolicy() method + of this class to ensure that the static initializer is not triggered by + a web application. Defaults to true.

+

Note: The underlying leak has been fixed in Java 7 update 51 onwards + and Java 8 onwards. This protection is therefor disabled if running on + Java 8 onwards.

+
tokenPollerProtection +

Enables protection so that any token poller thread initialized by + sun.security.pkcs11.SunPKCS11.initToken() does not + result in a memory leak. The thread is started depending on various + conditions as part of the initialization of the Java Cryptography + Architecture. Without the protection this can happen during Webapp + deployment when the MessageDigest for generating session IDs is + initialized. As a result the thread has the Webapp class loader as its + thread context class loader. Enabling the protection initializes JCA + early during Tomcat startup. Defaults to true. This + protection is disabled if running on Java 9 onwards since the leak has + been fixed for Java 9 onwards.

+
urlCacheProtection +

Enables protection so that reading resources from JAR files using + java.net.URLConnections does not result in the JAR file + being locked. Note that enabling this protection disables caching by + default for all resources obtained via + java.net.URLConnections. Caching may be re-enabled on a + case by case basis as required. Defaults to true.

+
xmlParsingProtection +

Enables protection so that parsing XML files within a web application + does not result in a memory leak. Note that memory profilers may not + display the GC root associated with this leak making it particularly + hard to diagnose. Defaults to true. This protection is + disabled if running on Java 9 onwards since the leak has been fixed for + Java 9 onwards.

+
+ +

JreMemoryLeakPreventionListener Examples

+ +

The following is an example of how to configure the + classesToInitialize attribute of this listener.

+ +

If this listener was configured in server.xml as:

+ +
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"
+            classesToInitialize="oracle.jdbc.driver.OracleTimeoutThreadPerVM" />
+ +

then the OracleTimeoutThreadPerVM class would be loaded + and initialized during listener startup instead of during request + processing.

+ +
+ +
+ +

Security Lifecycle Listener - org.apache.catalina.security.SecurityListener

+ +

The Security Lifecycle Listener performs a number of + security checks when Tomcat starts and prevents Tomcat from starting if they + fail. The listener is not enabled by default. To enabled it uncomment the + listener in $CATALINA_BASE/conf/server.xml. If the operating system supports + umask then the line in $CATALINA_HOME/bin/catalina.sh that obtains the umask + also needs to be uncommented.

+ +

This listener must only be nested within Server + elements.

+ +

The following additional attributes are supported by the Security + Lifecycle Listener:

+ +
+ Attribute + + Description +
checkedOsUsers +

A comma separated list of OS users that must not be used to start + Tomcat. If not specified, the default value of root is used. To + disable this check, set the attribute to the empty string. Usernames + are checked in a case-insensitive manner.

+
minimumUmask +

The least restrictive umask that must be configured before Tomcat + will start. If not specified, the default value of 0007 is used. + To disable this check, set the attribute to the empty string. The check + is not performed on Windows platforms.

+
+ +
+ +

StoreConfig Lifecycle Listener - org.apache.catalina.storeconfig.StoreConfigLifecycleListener

+ +

The StoreConfig Lifecycle Listener configures a + StoreConfig MBean that may be used to save the current server configuration + in server.xml or the current configuration for a web application in a + context.xml file.

+ +

This listener must only be nested within Server + elements.

+ +

The following additional attributes are supported by the + StoreConfig Lifecycle Listener:

+ +
+ Attribute + + Description +
storeConfigClass +

The name of the IStoreConfig implementation to use. If + not specified the default of + org.apache.catalina.storeconfig.StoreConfig will be + used.

+
storeRegistry +

The URL of the configuration file that configures how the + IStoreConfig is to save the configuration. If not specified + the built in resource + /org/apache/catalina/storeconfig/server-registry.xml will + be used.

+
+ +
+ +

ThreadLocal Leak Prevention Listener - org.apache.catalina.core.ThreadLocalLeakPreventionListener

+ +

The ThreadLocal Leak Prevention Listener triggers the + renewal of threads in Executor pools when a + Context is being stopped to avoid thread-local + related memory leaks. Active threads will be renewed one by one when they + come back to the pool after executing their task. The renewal happens + only for contexts that have their renewThreadsWhenStoppingContext + attribute set to true.

+ +

This listener must only be nested within Server + elements.

+ +

No additional attributes are supported by the ThreadLocal Leak + Prevention Listener.

+ +
+ +

UserConfig - org.apache.catalina.startup.UserConfig

+ +

The UserConfig provides feature of User Web Applications. + User Web Applications map a request URI starting with a tilde character ("~") + and a username to a directory (commonly named public_html) in that user's + home directory on the server.

+ +

See the User Web Applications + special feature on the Host element for more information.

+ +

The following additional attributes are supported by the + UserConfig:

+ +
+ Attribute + + Description +
directoryName +

The directory name to be searched for within each user home directory. + The default is public_html.

+
userClass +

The class name of the user database class. + There are currently two user database, the + org.apache.catalina.startup.PasswdUserDatabase is used on a + Unix system that uses the /etc/passwd file to identify valid users. + The org.apache.catalina.startup.HomesUserDatabase is used on + a server where /etc/passwd is not in use. HomesUserDatabase deploy all + directories found in a specified base directory.

+
homeBase +

The base directory containing user home directories. This is effective + only when org.apache.catalina.startup.HomesUserDatabase is + used.

+
allow +

A regular expression defining user who deployment is allowed. If this + attribute is specified, the user to deploy must match for this pattern. + If this attribute is not specified, all users will be deployed unless the + user matches a deny pattern.

+
deny +

A regular expression defining user who deployment is denied. If this + attribute is specified, the user to deploy must not match for this + pattern. If this attribute is not specified, deployment of user will be + governed by a allow attribute.

+
+ +
+ +

Version Logging Lifecycle Listener - org.apache.catalina.startup.VersionLoggerListener

+ +

The Version Logging Lifecycle Listener logs Tomcat, Java + and operating system information when Tomcat starts.

+ +

This listener must only be nested within Server + elements and should be the first listener defined.

+ +

The following additional attributes are supported by the Version + Logging Lifecycle Listener:

+ +
+ Attribute + + Description +
logArgs +

If true, the command line arguments passed to Java when + Tomcat started will be logged. If not specified, the default value of + true will be used.

+
logEnv +

If true, the current environment variables when Tomcat + starts will be logged. If not specified, the default value of + false will be used.

+
logProps +

If true, the current Java system properties will be + logged. If not specified, the default value of + false will be used.

+
+ +
+ +

Additional Implementations

+ +

JMX Remote Lifecycle Listener - org.apache.catalina.mbeans.JmxRemoteLifecycleListener

+ +

This listener requires catalina-jmx-remote.jar to be placed + in $CATALINA_HOME/lib. This jar may be found in the extras + directory of the binary download area.

+ +

The JMX Remote Lifecycle Listener fixes the ports used by + the JMX/RMI Server making things much simpler if you need to connect + jconsole or a similar tool to a remote Tomcat instance that is running + behind a firewall. Only these ports are configured via the listener. The + remainder of the configuration is via the standard system properties for + configuring JMX. For further information on configuring JMX see + + Monitoring and Management Using JMX included with the Java SDK + documentation.

+ +

This listener must only be nested within a Server + element.

+ +

The following additional attributes are supported by the JMX Remote + Lifecycle Listener:

+ +
+ Attribute + + Description +
rmiRegistryPortPlatform +

The port to be used by the JMX/RMI registry for the Platform MBeans. + This replaces the use of the + com.sun.management.jmxremote.port system property that + should not be set when using this listener.

+
rmiServerPortPlatform +

The port to be used by the Platform JMX/RMI server.

+
rmiBindAddress +

The address of the interface to be used by JMX/RMI server.

+
useLocalPorts +

Should any clients using these ports be forced to use local ports to + connect to the JMX/RMI server. This is useful when tunnelling + connections over SSH or similar. Defaults to false.

+
+ +

Using file-based Authentication and Authorisation

+ +

If this listener was configured in server.xml as:

+
  <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
+          rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />
+

with the following system properties set (e.g. in setenv.sh):

+
  -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password
+  -Dcom.sun.management.jmxremote.access.file=$CATALINA_BASE/conf/jmxremote.access
+  -Dcom.sun.management.jmxremote.ssl=false
+

$CATALINA_BASE/conf/jmxremote.password containing:

+
admin letmein
+

$CATALINA_BASE/conf/jmxremote.access containing:

+
admin readwrite
+

then opening ports 10001 (RMI Registry) and 10002 (JMX/RMI Server) in your + firewall would enable jconsole to connect to a Tomcat instance running + behind a firewall using a connection string of the form:

+
service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi
+

+ with a user name of admin and a password of + letmein. +

+ +

Using JAAS

+ +

If we use the following system properties instead:

+
  -Dcom.sun.management.jmxremote.login.config=Tomcat
+  -Djava.security.auth.login.config=$CATALINA_BASE/conf/login.config
+  -Dcom.sun.management.jmxremote.access.file=$CATALINA_BASE/conf/jmxremote.access
+  -Dcom.sun.management.jmxremote.ssl=false
+

$CATALINA_BASE/conf/login.config containing your choice of JAAS LoginModule implementation, for example:

+
  Tomcat { /* should match to the com.sun.management.jmxremote.login.config property */
+
+    /* for illustration purposes only */
+    com.sun.security.auth.module.LdapLoginModule REQUIRED
+      userProvider="ldap://ldap-svr/ou=people,dc=example,dc=com"
+      userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))"
+      authzIdentity="admin"
+      debug=true;
+  };
+

$CATALINA_BASE/conf/jmxremote.access containing:

+
admin readwrite
+

+ then we would need to provide LDAP credentials instead. +

+ +

Note that the examples above do not use SSL. JMX access should + be considered equivalent to administrative access and secured accordingly. +

+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/loader.html b/test.dockerapp/tomcat/webapps/docs/config/loader.html new file mode 100644 index 0000000..471d61a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/loader.html @@ -0,0 +1,161 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Loader Component

The Loader Component

Table of Contents

Introduction

+ +

The Loader element represents the web + application class loader that will be used to load Java + classes and resources for your web application. Such + a class loader must follow the requirements of the Servlet + Specification, and load classes from the following locations:

+
    +
  • From the /WEB-INF/classes directory inside your + web application.
  • +
  • From JAR files in the /WEB-INF/lib directory + inside your web application.
  • +
  • From resources made available by Catalina to all web + applications globally.
  • +
+ +

A Loader element MAY be nested inside a Context + component. If it is not included, a default Loader configuration will be + created automatically, which is sufficient for most requirements.

+ +

For a more in-depth description of the class loader hierarchy + that is implemented by Catalina, see the ClassLoader HowTo.

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Loader + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Loader interface. + If not specified, the standard value (defined below) will be used.

+
delegate +

Set to true if you want the class loader to follow + the standard Java2 delegation model, and attempt to load classes from + parent class loaders before looking inside the web + application. Set to false (the default) to have the + class loader look inside the web application first, before asking + parent class loaders to find requested classes or resources.

+
reloadable +

Set to true if you want Catalina to monitor classes in + /WEB-INF/classes/ and /WEB-INF/lib for + changes, and automatically reload the web application if a change + is detected. This feature is very useful during application + development, but it requires significant runtime overhead and is + not recommended for use on deployed production applications. You + can use the Manager web + application, however, to trigger reloads of deployed applications + on demand.

+ +

NOTE - The value for this property will be + inherited from the reloadable attribute you set on + the surrounding Context component, + and any value you explicitly set here will be replaced.

+
+ +
+ + +

Standard Implementation

+ +

The standard implementation of Loader is + org.apache.catalina.loader.WebappLoader. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
loaderClass +

Java class name of the java.lang.ClassLoader + implementation class to use. Custom implementations must extend + org.apache.catalina.loader.WebappClassLoaderBase. +

+ +

If not specified, the default value is + org.apache.catalina.loader.WebappClassLoader. The + default loaderClass is not parallel capable, which + means that loading a class from this classloader is performed by one + thread at a time. A parallel capable loaderClass is + available and can be used by specifying + org.apache.catalina.loader.ParallelWebappClassLoader.

+
+ +
+ +

Nested Components

+ +

No components may be nested inside a Loader element.

+ +

Special Features

+ +

Logging

+ +

A loader is associated with the log category based on its classname.

+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/manager.html b/test.dockerapp/tomcat/webapps/docs/config/manager.html new file mode 100644 index 0000000..bb9c49a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/manager.html @@ -0,0 +1,524 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Manager Component

The Manager Component

Table of Contents

Introduction

+ +

The Manager element represents the session + manager that will be used to create and maintain HTTP sessions + as requested by the associated web application.

+ +

A Manager element MAY be nested inside a + Context component. If it is not included, + a default Manager configuration will be created automatically, which + is sufficient for most requirements, — see + Standard Manager Implementation below for the details + of this configuration.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Manager + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Manager interface. + If not specified, the standard value (defined below) will be used.

+
distributable +

Deprecated: This should be configured via the + Context.

+

Set to true to ask the session manager to enforce + the restrictions described in the Servlet Specification on + distributable applications (primarily, this would mean that all + session attributes must implement java.io.Serializable). + Set to false (the default) to not enforce these + restrictions.

+ +

NOTE - The value for this property is inherited + automatically based on the presence or absence of the + <distributable> element in the web application + deployment descriptor (/WEB-INF/web.xml).

+
maxActiveSessions +

The maximum number of active sessions that will be created by + this Manager, or -1 (the default) for no limit.

+ +

When the limit is reached, any attempt to create a new session + (e.g. with HttpServletRequest.getSession() call) + will fail with an IllegalStateException.

+
maxInactiveInterval +

Deprecated: This should be configured via the + Context.

+

The initial maximum time interval, in seconds, + between client requests before a session is invalidated. A negative value + will result in sessions never timing out. If the attribute is not provided, + a default of 1800 seconds (30 minutes) is used.

+ +

This attribute provides the initial value whenever a + new session is created, but the interval may be dynamically + varied by a servlet via the + setMaxInactiveInterval method of the HttpSession object.

+
sessionIdLength +

The length of session ids created by this Manager, measured in bytes, + excluding subsequent conversion to a hexadecimal string and + excluding any JVM route information used for load balancing. + This attribute is deprecated. Set the length on a nested + SessionIdGenerator element instead.

+
+ +
+ + +

Standard Implementation

+ +

Tomcat provides two standard implementations of Manager + for use — the default one stores active sessions, while the optional one + stores active sessions that have been swapped out (in addition to saving + sessions across a restart of Tomcat) in a storage location that is selected + via the use of an appropriate Store nested element.

+ +

Standard Manager Implementation

+ +

The standard implementation of Manager is + org.apache.catalina.session.StandardManager. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
pathname +

Absolute or relative (to the work directory for this Context) + pathname of the file in which session state will be preserved + across application restarts, if possible. The default is + "SESSIONS.ser".
See + Persistence Across Restarts + for more information. This persistence may be + disabled by setting this attribute to an empty string.

+
processExpiresFrequency +

Frequency of the session expiration, and related manager operations. + Manager operations will be done once for the specified amount of + backgroundProcess calls (i.e., the lower the amount, the more often the + checks will occur). The minimum value is 1, and the default value is 6. +

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate session IDs. + If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the Manager + will use the platform default provider and the default algorithm. If not + specified, the platform default provider will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the Manager + will use the platform default provider and the default algorithm. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
sessionAttributeNameFilter +

A regular expression used to filter which session attributes will be + distributed. An attribute will only be distributed if its name matches + this pattern. If the pattern is zero length or null, all + attributes are eligible for distribution. The pattern is anchored so the + session attribute name must fully match the pattern. As an example, the + value (userName|sessionHistory) will only distribute the + two session attributes named userName and + sessionHistory. If not specified, the default value of + null will be used.

+
sessionAttributeValueClassNameFilter +

A regular expression used to filter which session attributes will be + distributed. An attribute will only be distributed if the implementation + class name of the value matches this pattern. If the pattern is zero + length or null, all attributes are eligible for + distribution. The pattern is anchored so the fully qualified class name + must fully match the pattern. If not specified, the default value of + null will be used unless a SecurityManager is + enabled in which case the default will be + java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

+
warnOnSessionAttributeFilterFailure +

If sessionAttributeNameFilter or + sessionAttributeValueClassNameFilter blocks an + attribute, should this be logged at WARN level? If + WARN level logging is disabled then it will be logged at + DEBUG. The default value of this attribute is + false unless a SecurityManager is enabled in + which case the default will be true.

+
+ +

Persistent Manager Implementation

+ +

NOTE: You must set either the + org.apache.catalina.session.StandardSession.ACTIVITY_CHECK or + org.apache.catalina.STRICT_SERVLET_COMPLIANCE + system properties to true for + the persistent manager to work correctly.

+ +

The persistent implementation of Manager is + org.apache.catalina.session.PersistentManager. In + addition to the usual operations of creating and deleting sessions, a + PersistentManager has the capability to swap active (but + idle) sessions out to a persistent storage mechanism, as well as to save + all sessions across a normal restart of Tomcat. The actual persistent + storage mechanism used is selected by your choice of a + Store element nested inside the Manager + element - this is required for use of PersistentManager.

+ +

This implementation of Manager supports the following attributes in + addition to the Common Attributes + described earlier.

+ +
+ Attribute + + Description +
className +

It has the same meaning as described in the + Common Attributes above. + You must specify + org.apache.catalina.session.PersistentManager to use + this manager implementation.

+
maxIdleBackup +

The time interval (in seconds) since the last access to a session + before it is eligible for being persisted to the session store, or + -1 to disable this feature. By default, this feature is + disabled.

+
maxIdleSwap +

The maximum time a session may be idle before it is eligible to be + swapped to disk due to inactivity. Setting this to -1 means + sessions should not be swapped out just because of inactivity. If this + feature is enabled, the time interval specified here should be equal to + or longer than the value specified for maxIdleBackup. By + default, this feature is disabled.

+
minIdleSwap +

The minimum time in seconds a session must be idle before it is + eligible to be swapped to disk to keep the active session count below + maxActiveSessions. Setting to -1 means sessions will not be + swapped out to keep the active session count down. If specified, this + value should be less than that specified by maxIdleSwap. + By default, this value is set to -1.

+
processExpiresFrequency +

It is the same as described above for the + org.apache.catalina.session.StandardManager class. +

+
saveOnRestart +

Should all sessions be persisted and reloaded when Tomcat is shut + down and restarted (or when this application is reloaded)? By default, + this attribute is set to true.

+
secureRandomClass +

It is the same as described above for the + org.apache.catalina.session.StandardManager class. +

+
secureRandomProvider +

It is the same as described above for the + org.apache.catalina.session.StandardManager class. +

+
secureRandomAlgorithm +

It is the same as described above for the + org.apache.catalina.session.StandardManager class. +

+
sessionAttributeNameFilter +

A regular expression used to filter which session attributes will be + distributed. An attribute will only be distributed if its name matches + this pattern. If the pattern is zero length or null, all + attributes are eligible for distribution. The pattern is anchored so the + session attribute name must fully match the pattern. As an example, the + value (userName|sessionHistory) will only distribute the + two session attributes named userName and + sessionHistory. If not specified, the default value of + null will be used.

+
sessionAttributeValueClassNameFilter +

A regular expression used to filter which session attributes will be + distributed. An attribute will only be distributed if the implementation + class name of the value matches this pattern. If the pattern is zero + length or null, all attributes are eligible for + distribution. The pattern is anchored so the fully qualified class name + must fully match the pattern. If not specified, the default value of + null will be used unless a SecurityManager is + enabled in which case the default will be + java\\.lang\\.(?:Boolean|Integer|Long|Number|String).

+
warnOnSessionAttributeFilterFailure +

If sessionAttributeNameFilter or + sessionAttributeValueClassNameFilter blocks an + attribute, should this be logged at WARN level? If + WARN level logging is disabled then it will be logged at + DEBUG. The default value of this attribute is + false unless a SecurityManager is enabled in + which case the default will be true.

+
+ +

In order to successfully use a PersistentManager, you must nest inside + it a <Store> element, as described below.

+ +
+ + +

Nested Components

+ +

All Manager Implementations

+ +

All Manager implementations allow nesting of a + <SessionIdGenerator> element. It defines + the behavior of session id generation. All implementations + of the SessionIdGenerator allow the + following attributes: +

+ +
+ Attribute + + Description +
sessionIdLength +

The length of the session ID may be changed with the + sessionIdLength attribute. +

+
+ +

Persistent Manager Implementation

+ +

If you are using the Persistent Manager Implementation + as described above, you MUST nest a + <Store> element inside, which defines the + characteristics of the persistent data storage. Two implementations + of the <Store> element are currently available, + with different characteristics, as described below.

+ +
File Based Store
+ +

The File Based Store implementation saves swapped out + sessions in individual files (named based on the session identifier) + in a configurable directory. Therefore, you are likely to encounter + scalability problems as the number of active sessions increases, and + this should primarily be considered a means to easily experiment.

+ +

To configure this, add a <Store> nested inside + your <Manager> element with the following attributes: +

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Store interface. You + must specify + org.apache.catalina.session.FileStore + to use this implementation.

+
directory +

Absolute or relative (to the temporary work directory for this web + application) pathname of the directory into which individual session + files are written. If not specified, the temporary work directory + assigned by the container is utilized.

+
+ + +
JDBC Based Store
+ +

The JDBC Based Store implementation saves swapped out + sessions in individual rows of a preconfigured table in a database + that is accessed via a JDBC driver. With large numbers of swapped out + sessions, this implementation will exhibit improved performance over + the File Based Store described above.

+ +

To configure this, add a <Store> nested inside + your <Manager> element with the following attributes: +

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Store interface. You + must specify + org.apache.catalina.session.JDBCStore + to use this implementation.

+
connectionName +

The user name that will be handed to the configured JDBC driver to + establish a connection to the database containing the session table.

+
connectionPassword +

The password that will be handed to the configured JDBC driver to + establish a connection to the database containing the session table.

+
connectionURL +

The connection URL that will be handed to the configured JDBC + driver to establish a connection to the database containing our + session table.

+
dataSourceName +

Name of the JNDI resource for a JDBC DataSource-factory. If this option + is given and a valid JDBC resource can be found, it will be used and any + direct configuration of a JDBC connection via connectionURL, + connectionName, connectionPassword and + driverName will be ignored. Since this code uses prepared + statements, you might want to configure pooled prepared statements as + shown in the JNDI resources + HOW-TO.

+
driverName +

Java class name of the JDBC driver to be used.

+
localDataSource +

This allows the Store to use a DataSource defined for the Context + rather than a global DataSource. If not specified, the default is + false: use a global DataSource.

+
sessionAppCol +

Name of the database column, contained in the specified session table, + that contains the Engine, Host, and Web Application Context name in the + format /Engine/Host/Context. If not specified the default + value of app will be used.

+
sessionDataCol +

Name of the database column, contained in the specified session table, + that contains the serialized form of all session attributes for a swapped + out session. The column type must accept a binary object (typically called + a BLOB). If not specified the default value of data will be + used.

+
sessionIdCol +

Name of the database column, contained in the specified session table, + that contains the session identifier of the swapped out session. The + column type must accept character string data of at least as many + characters as are contained in session identifiers created by Tomcat + (typically 32). If not specified the default value of id will + be used.

+
sessionLastAccessedCol +

Name of the database column, contained in the specified session table, + that contains the lastAccessedTime property of this session. + The column type must accept a Java long (64 bits). If not + specified the default value of maxinactive will be used.

+
sessionMaxInactiveCol +

Name of the database column, contained in the specified session table, + that contains the maxInactiveInterval property of this + session. The column type must accept a Java integer (32 + bits). If not specified, the default value of maxinactive + will be used.

+
sessionTable +

Name of the database table to be used for storing swapped out sessions. + This table must contain (at least) the database columns that are + configured by the other attributes of this element. If not specified the + default value of tomcat$sessions will be used.

+
sessionValidCol +

Name of the database column, contained in the specified session table, + that contains a flag indicating whether this swapped out session is still + valid or not. The column type must accept a single character. If not + specified the default value of valid will be used.

+
+ +

Before attempting to use the JDBC Based Store for the first time, + you must create the table that will be used to store swapped out sessions. + Detailed SQL commands vary depending on the database you are using, but + a script like this will generally be required:

+ +
create table tomcat_sessions (
+  session_id     varchar(100) not null primary key,
+  valid_session  char(1) not null,
+  max_inactive   int not null,
+  last_access    bigint not null,
+  app_name       varchar(255),
+  session_data   mediumblob,
+  KEY kapp_name(app_name)
+);
+ +

Note: The SQL command above does not use the default names for either the + table or the columns so the JDBC Store would need to be configured to reflect + this.

+ +

In order for the JDBC Based Store to successfully connect to your + database, the JDBC driver you configure must be visible to Tomcat's + internal class loader. Generally, that means you must place the JAR + file containing this driver into the $CATALINA_HOME/lib + directory.

+ +

Special Features

+ + +

Persistence Across Restarts

+ +

Whenever Apache Tomcat is shut down normally and restarted, or when an + application reload is triggered, the standard Manager implementation + will attempt to serialize all currently active sessions to a disk + file located via the pathname attribute. All such saved + sessions will then be deserialized and activated (assuming they have + not expired in the mean time) when the application reload is completed.

+ +

In order to successfully restore the state of session attributes, + all such attributes MUST implement the java.io.Serializable + interface. You MAY cause the Manager to enforce this restriction by + including the <distributable> element in your web + application deployment descriptor (/WEB-INF/web.xml).

+ +

The persistence across restarts provided by the + StandardManager is a simpler implementation than that + provided by the PersistentManager. If robust, production + quality persistence across restarts is required then the + PersistentManager should be used with an appropriate + configuration.

+ +
+ +

Disable Session Persistence

+ +

As documented above, every web application by default has + standard manager implementation configured, and it performs session + persistence across restarts. To disable this persistence feature, create + a Context configuration file for your web + application and add the following element there:

+ +
<Manager pathname="" />
+
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/realm.html b/test.dockerapp/tomcat/webapps/docs/config/realm.html new file mode 100644 index 0000000..1b331df --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/realm.html @@ -0,0 +1,1038 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Realm Component

The Realm Component

Table of Contents

Introduction

+ +

A Realm element represents a "database" of usernames, + passwords, and roles (similar to Unix groups) assigned + to those users. Different implementations of Realm allow Catalina to be + integrated into environments where such authentication information is already + being created and maintained, and then utilize that information to implement + Container Managed Security as described in the Servlet + Specification.

+ +

A Catalina container (Engine, + Host, or Context) may + contain no more than one Realm element (although if supported by the Realm + this one Realm may itself contain multiple nested Realms). In addition, the + Realm associated with an Engine or a Host is automatically inherited by + lower-level containers unless the lower level container explicitly defines its + own Realm. If no Realm is configured for the Engine, an instance of the + Null Realm + will be configured for the Engine automatically.

+ +

For more in-depth information about container managed security in web + applications, as well as more information on configuring and using the + standard realm component implementations, please see the + Container-Managed Security Guide. +

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Realm + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Realm interface.

+
+ +

Unlike most Catalina components, there are several standard + Realm implementations available. As a result, + the className attribute MUST be used to select the + implementation you wish to use.

+ +
+ + +

JDBC Database Realm - org.apache.catalina.realm.JDBCRealm

+ +

The JDBC Database Realm connects Tomcat to + a relational database, accessed through an appropriate JDBC driver, + to perform lookups of usernames, passwords, and their associated + roles. Because the lookup is done each time that it is required, + changes to the database will be immediately reflected in the + information used to authenticate new logins.

+ +

A rich set of additional attributes lets you configure the required + connection to the underlying database, as well as the table and + column names used to retrieve the required information:

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+

When this attribute has the value of authOnly or + strictAuthOnly, the roleNameCol and + userRoleTable attributes become optional. If those two + attributes are omitted, the user's roles will not be loaded by this + Realm.

+
connectionName +

The database username to use when establishing the JDBC + connection.

+
connectionPassword +

The database password to use when establishing the JDBC + connection.

+
connectionURL +

The connection URL to be passed to the JDBC driver when + establishing a database connection.

+
digest +

The name of the MessageDigest algorithm used + to encode user passwords stored in the database. If not specified, + user passwords are assumed to be stored in clear-text.

+

This attribute is deprecated. Set the algorithm on a nested + CredentialHandler element instead.

+
digestEncoding +

The charset for encoding digests. If not specified, the platform + default will be used.

+

This attribute is deprecated. Set the encoding on a nested + CredentialHandler element instead.

+
driverName +

Fully qualified Java class name of the JDBC driver to be + used to connect to the authentication database.

+
roleNameCol +

Name of the column, in the "user roles" table, which contains + a role name assigned to the corresponding user.

+

This attribute is required in majority of + configurations. See allRolesMode attribute for + a rare case when it can be omitted.

+
stripRealmForGss +

When processing users authenticated via the GSS-API, this attribute + controls if any "@..." is removed from the end of the user + name. If not specified, the default is true.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
userCredCol +

Name of the column, in the "users" table, which contains + the user's credentials (i.e. password). If a value for the + digest attribute is specified, this component + will assume that the passwords have been encoded with the + specified algorithm. Otherwise, they will be assumed to be + in clear text.

+
userNameCol +

Name of the column, in the "users" and "user roles" table, + that contains the user's username.

+
userRoleTable +

Name of the "user roles" table, which must contain columns + named by the userNameCol and roleNameCol + attributes.

+

This attribute is required in majority of + configurations. See allRolesMode attribute for + a rare case when it can be omitted.

+
userTable +

Name of the "users" table, which must contain columns named + by the userNameCol and userCredCol + attributes.

+
X509UsernameRetrieverClassName +

When using X509 client certificates, this specifies the class name + that will be used to retrieve the user name from the certificate. + The class must implement the + org.apache.catalina.realm.X509UsernameRetriever + interface. The default is to use the certificate's SubjectDN + as the username.

+
+ +

See the Container-Managed Security Guide for more + information on setting up container managed security using the + JDBC Database Realm component.

+ +
+ + +

DataSource Database Realm - org.apache.catalina.realm.DataSourceRealm

+ +

The DataSource Database Realm connects Tomcat to + a relational database, accessed through a JNDI named JDBC DataSource + to perform lookups of usernames, passwords, and their associated + roles. Because the lookup is done each time that it is required, + changes to the database will be immediately reflected in the + information used to authenticate new logins.

+ +

The JDBC Realm uses a single db connection. This requires that + realm based authentication be synchronized, i.e. only one authentication + can be done at a time. This could be a bottleneck for applications + with high volumes of realm based authentications.

+ +

The DataSource Database Realm supports simultaneous realm based + authentications and allows the underlying JDBC DataSource to + handle optimizations like database connection pooling.

+ +

A rich set of additional attributes lets you configure the name + of the JNDI JDBC DataSource, as well as the table and + column names used to retrieve the required information:

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+

When this attribute has the value of authOnly or + strictAuthOnly, the roleNameCol and + userRoleTable attributes become optional. If those two + attributes are omitted, the user's roles will not be loaded by this + Realm.

+
dataSourceName +

The name of the JNDI JDBC DataSource for this Realm.

+
digest +

The name of the MessageDigest algorithm used + to encode user passwords stored in the database. If not specified, + user passwords are assumed to be stored in clear-text.

+

This attribute is deprecated. Set the algorithm on a nested + CredentialHandler element instead.

+
localDataSource +

When the realm is nested inside a Context element, this allows the + realm to use a DataSource defined for the Context rather than a global + DataSource. If not specified, the default is false: use a + global DataSource.

+
roleNameCol +

Name of the column, in the "user roles" table, which contains + a role name assigned to the corresponding user.

+

This attribute is required in majority of + configurations. See allRolesMode attribute for + a rare case when it can be omitted.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
stripRealmForGss +

When processing users authenticated via the GSS-API, this attribute + controls if any "@..." is removed from the end of the user + name. If not specified, the default is true.

+
userCredCol +

Name of the column, in the "users" table, which contains + the user's credentials (i.e. password). If a value for the + digest attribute is specified, this component + will assume that the passwords have been encoded with the + specified algorithm. Otherwise, they will be assumed to be + in clear text.

+
userNameCol +

Name of the column, in the "users" and "user roles" table, + that contains the user's username.

+
userRoleTable +

Name of the "user roles" table, which must contain columns + named by the userNameCol and roleNameCol + attributes.

+

This attribute is required in majority of + configurations. See allRolesMode attribute for + a rare case when it can be omitted.

+
userTable +

Name of the "users" table, which must contain columns named + by the userNameCol and userCredCol + attributes.

+
X509UsernameRetrieverClassName +

When using X509 client certificates, this specifies the class name + that will be used to retrieve the user name from the certificate. + The class must implement the + org.apache.catalina.realm.X509UsernameRetriever + interface. The default is to use the certificate's SubjectDN + as the username.

+
+ +

See the + DataSource Realm HOW-TO for more information on setting up container + managed security using the DataSource Database Realm component.

+ +
+ + +

JNDI Directory Realm - org.apache.catalina.realm.JNDIRealm

+ +

The JNDI Directory Realm connects Tomcat to + an LDAP Directory, accessed through an appropriate JNDI driver, + that stores usernames, passwords, and their associated + roles. Changes to the directory are immediately reflected in the + information used to authenticate new logins.

+ + +

The directory realm supports a variety of approaches to using + LDAP for authentication:

+ +
    +
  • The realm can either use a pattern to determine the + distinguished name (DN) of the user's directory entry, or search + the directory to locate that entry. +
  • + +
  • The realm can authenticate the user either by binding to the + directory with the DN of the user's entry and the password + presented by the user, or by retrieving the password from the + user's entry and performing a comparison locally. +
  • + +
  • Roles may be represented in the directory as explicit entries + found by a directory search (e.g. group entries of which the user + is a member), as the values of an attribute in the user's entry, + or both. +
  • +
+ +

A rich set of additional attributes lets you configure the + required behaviour as well as the connection to the underlying + directory and the element and attribute names used to retrieve + information from the directory:

+ +
+ Attribute + + Description +
adCompat +

Microsoft Active Directory often returns referrals. + When iterating over NamingEnumerations these lead to + PartialResultExceptions. If you want us to ignore those exceptions, + set this attribute to "true". Unfortunately there's no stable way + to detect, if the Exceptions really come from an AD referral. + The default value is "false".

+
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+
alternateURL +

If a socket connection can not be made to the provider at + the connectionURL an attempt will be made to use the + alternateURL.

+
authentication +

A string specifying the type of authentication to use. + "none", "simple", "strong" or a provider specific definition + can be used. If no value is given the providers default is used.

+
cipherSuites +

Specify which cipher suites are allowed when trying to open + a secured connection using StartTLS. The allowed cipher suites + are specified by a comma separated list. The default is to use the + cipher suites of the JVM.

+
commonRole +

A role name assigned to each successfully authenticated user in + addition to the roles retrieved from LDAP. If not specified, only + the roles retrieved via LDAP are used.

+
connectionName +

The directory username to use when establishing a + connection to the directory for LDAP search operations. If not + specified an anonymous connection is made, which is often + sufficient unless you specify the userPassword + property.

+
connectionPassword +

The directory password to use when establishing a + connection to the directory for LDAP search operations. If not + specified an anonymous connection is made, which is often + sufficient unless you specify the userPassword + property.

+
connectionTimeout +

The timeout in milliseconds to use when establishing the connection + to the LDAP directory. If not specified, a value of 5000 (5 seconds) is + used.

+
connectionURL +

The connection URL to be passed to the JNDI driver when + establishing a connection to the directory.

+
contextFactory +

Fully qualified Java class name of the factory class used + to acquire our JNDI InitialContext. By default, + assumes that the standard JNDI LDAP provider will be utilized.

+
derefAliases +

A string specifying how aliases are to be dereferenced during + search operations. The allowed values are "always", "never", + "finding" and "searching". If not specified, "always" is used.

+
digest +

The digest algorithm to apply to the plaintext password offered + by the user before comparing it with the value retrieved from the + directory. Valid values are those accepted for the algorithm name + by the java.security.MessageDigest class. If not + specified the plaintext password is assumed to be retrieved. Not + required unless userPassword is specified

+

This attribute is deprecated. Set the algorithm on a nested + CredentialHandler element instead.

+
hostnameVerifierClassName +

The name of the class to use for hostname verification when + using StartTLS for securing the connection to the ldap server. + The default constructor will be used to construct an instance of + the verifier class. The default is to accept only those hostnames, + that are valid according to the peer certificate of the ldap + server.

+
protocol +

A string specifying the security protocol to use. If not given + the providers default is used.

+
readTimeout +

The timeout, in milliseconds, to use when trying to read from a + connection to the directory. If not specified, the default of 5000 + (5 seconds) is used.

+
referrals +

How do we handle JNDI referrals? Allowed values are + "ignore", "follow", or "throw" (see javax.naming.Context.REFERRAL + for more information). + Microsoft Active Directory often returns referrals. + If you need to follow them set referrals to "follow". + Caution: if your DNS is not part of AD, the LDAP client lib might try + to resolve your domain name in DNS to find another LDAP server.

+
roleBase +

The base directory entry for performing role searches. If not + specified the top-level element in the directory context will be used. + If specified it may optionally include pattern replacements + "{0}".."{n}" corresponding to the name parts of the + user's distinguished name (as returned by + javax.naming.Name.get()).

+
roleName +

The name of the attribute that contains role names in the + directory entries found by a role search. In addition you can + use the userRoleName property to specify the name + of an attribute, in the user's entry, containing additional + role names.

+

If roleName is not specified a role + search does not take place, and roles are taken only from the + user's entry.

+
roleNested +

Set to true if you want to nest roles into roles. + When a role search is performed and the value of this property is + true, the search will be repeated recursively to find + all the roles that belong to the user either directly or indirectly. + If not specified, the default value of false is used.

+
roleSearch +

The LDAP filter expression used for performing role + searches.

+ +

Use {0} to substitute the distinguished name (DN) + of the user, and/or {1} to substitute the username, + and/or {2} for the value of an attribute from the + user's directory entry, of the authenticated user. + The name of the attribute that provides the value for {2} + is configured by the userRoleAttribute property.

+ +

When roleNested property is true, + this filter expression will be also used to recursively search for + other roles, which indirectly belong to this user. To find the + roles that match the newly found role, the following values + are used: + {0} is substituted by the distinguished name of the newly + found role, and both {1} and {2} are + substituted by the name of the role (see the roleName + property). The userRoleAttribute property is not + applicable to this search.

+ +

If this property is not specified, a role search does not take + place and roles are taken only from the attribute in the user's entry + specified by the userRoleName property.

+
roleSearchAsUser +

When searching for user roles, should the search be performed as the + user currently being authenticated? If false, + connectionName and connectionPassword will be + used if specified, else an anonymous. If not specified, the default + value of false is used. Note that when accessing the + directory using delegated credentials, this attribute is always ignored + and the search is performed using the delegated credentials.

+
roleSubtree +

Set to true if you want to search the entire + subtree of the element specified by the roleBase + property for role entries associated with the user. The + default value of false causes only the top level + to be searched.

+
sizeLimit +

Specifies the maximum number of records to return when using the + userSearch attribute. If not specified, the default of + 0 is used which indicates no limit.

+
spnegoDelegationQop +

When the JNDI Realm is used with the SPNEGO authenticator and + useDelegatedCredential is true this attribute + controls the QOP (Quality of Protection) that should be used for + the connection to the LDAP + server after authentication. This value is used to set the + javax.security.sasl.qop environment property for the LDAP + connection. This attribute should be a comma-separated list of values + selected from auth-conf, auth-int and + auth. See Java documentation for more details.

+

The default value is auth-conf.

+
sslProtocol +

Specifies which ssl protocol should be used, when connecting with + StartTLS. The default is to let the jre decide. If you need even more + control, you can specify the SSLSocketFactory to use.

+
sslSocketFactory +

Specifies which SSLSocketFactory to use when connecting + to the ldap server using StartTLS. An instance of the class will be + constructed using the default constructor. If none class name is given + the default jre SSLSocketFactory will be used.

+
stripRealmForGss +

When processing users authenticated via the GSS-API, this attribute + controls if any "@..." is removed from the end of the user + name. If not specified, the default is true.

+
timeLimit +

Specifies the time (in milliseconds) to wait for records to be + returned when using the userSearch attribute. If not + specified, the default of 0 is used which indicates no + limit.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
useDelegatedCredential +

When the JNDIRealm is used with the SPNEGO authenticator, delegated + credentials for the user may be available. If such credentials are + present, this attribute controls whether or not they are used to + connect to the directory. If not specified, the default value of + true is used.

+
userBase +

The base element for user searches performed using the + userSearch expression. Not used if you are using + the userPattern expression.

+
userPassword +

Name of the attribute in the user's entry containing the + user's password. If you specify this value, JNDIRealm will + bind to the directory using the values specified by + connectionName and + connectionPassword properties, and retrieve the + corresponding attribute for comparison to the value specified + by the user being authenticated. If you do + not specify this value, JNDIRealm will + attempt a simple bind to the directory using the DN of the + user's entry and the password presented by the user, with a + successful bind being interpreted as an authenticated + user.

+
userPattern +

Pattern for the distinguished name (DN) of the user's + directory entry, with {0} marking where the + actual username should be inserted. You can use this property + instead of userSearch, userSubtree + and userBase when the distinguished name contains + the username and is otherwise the same for all users. Note that + when accessing the directory using delegated credentials, this + attribute is always ignored and userSearch, + userSubtree and userBase are always + used instead.

+
userRoleName +

The name of an attribute in the user's directory entry + containing zero or more values for the names of roles assigned + to this user. In addition you can use the + roleName property to specify the name of an + attribute to be retrieved from individual role entries found + by searching the directory. If userRoleName is + not specified all the roles for a user derive from the role + search.

+
userRoleAttribute +

The name of an attribute in the user's directory entry + containing the value that you wish to use when you search for + roles. This is especially useful for RFC 2307 where + the role memberUid can be the uid or the + uidNumber of the user. This value will be + marked as {2} in your role search filter expression. + This value will NOT be available for nested role searches.

+
userSearch +

The LDAP filter expression to use when searching for a + user's directory entry, with {0} marking where + the actual username should be inserted. Use this property + (along with the userBase and + userSubtree properties) instead of + userPattern to search the directory for the + user's entry.

+
userSearchAsUser +

When searching for a user's entry, should the search be performed as + the user currently being authenticated? If false, + connectionName and connectionPassword will be + used if specified, else an anonymous. If not specified, the default + value of false is used. Note that when accessing the + directory using delegated credentials, this attribute is always ignored + and the search is performed using the delegated credentials.

+
userSubtree +

Set to true if you want to search the entire + subtree of the element specified by the userBase + property for the user's entry. The default value of + false causes only the top level to be searched. + Not used if you are using the userPattern + expression.

+
useStartTls +

Set to true if you want to use StartTLS for securing + the connection to the ldap server. The default value is false. +

+
X509UsernameRetrieverClassName +

When using X509 client certificates, this specifies the class name + that will be used to retrieve the user name from the certificate. + The class must implement the + org.apache.catalina.realm.X509UsernameRetriever + interface. The default is to use the certificate's SubjectDN + as the username.

+
+ +

See the Container-Managed Security Guide for more + information on setting up container managed security using the + JNDI Directory Realm component.

+ +
+ + +

UserDatabase Realm - org.apache.catalina.realm.UserDatabaseRealm

+ +

The UserDatabase Realm is a Realm implementation + that is based on a UserDatabase resource made available through the global + JNDI resources configured for this Tomcat instance.

+ +

The UserDatabase Realm implementation supports the following + additional attributes:

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+
resourceName +

The name of the global UserDatabase resource + that this realm will use for user, password and role information.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
X509UsernameRetrieverClassName +

When using X509 client certificates, this specifies the class name + that will be used to retrieve the user name from the certificate. + The class must implement the + org.apache.catalina.realm.X509UsernameRetriever + interface. The default is to use the certificate's SubjectDN + as the username.

+
+ +

See the + Container-Managed Security Guide for more + information on setting up container managed security using the UserDatabase + Realm component and the + JNDI resources how-to for more + information on how to configure a UserDatabase resource.

+ +
+ + +

Memory Based Realm - org.apache.catalina.realm.MemoryRealm

+ +

The Memory Based Realm is a simple Realm implementation + that reads user information from an XML format, and represents it as a + collection of Java objects in memory. This implementation is intended + solely to get up and running with container managed security - it is NOT + intended for production use. As such, there are no mechanisms for + updating the in-memory collection of users when the content of the + underlying data file is changed.

+ +

The Memory Based Realm implementation supports the following + additional attributes:

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+
digest +

The digest algorithm used to store passwords in non-plaintext + formats. Valid values are those accepted for the algorithm name by the + java.security.MessageDigest class. If not specified, + passwords are stored in clear text.

+

This attribute is deprecated. Set the algorithm on a nested + CredentialHandler element instead.

+
pathname +

URL, absolute path or relative path (to $CATALINA_BASE) for the XML + file containing our user information. See below for details on the + XML element format required. If no pathname is specified, the + default value is conf/tomcat-users.xml.

+
stripRealmForGss +

When processing users authenticated via the GSS-API, this attribute + controls if any "@..." is removed from the end of the user + name. If not specified, the default is true.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
X509UsernameRetrieverClassName +

When using X509 client certificates, this specifies the class name + that will be used to retrieve the user name from the certificate. + The class must implement the + org.apache.catalina.realm.X509UsernameRetriever + interface. The default is to use the certificate's SubjectDN + as the username.

+
+ +

The XML document referenced by the pathname attribute must + conform to the following requirements:

+
    +
  • The root (outer) element must be <tomcat-users>. +
  • +
  • Each authorized user must be represented by a single XML element + <user>, nested inside the root element.
  • +
  • Each <user> element must have the following + attributes: +
      +
    • username - Username of this user (must be unique + within this file).
      + For compatibility, it is allowed to use name as an + alternative name for this attribute.
    • +
    • password - Password of this user (in + clear text).
    • +
    • roles - Comma-delimited list of the role names + assigned to this user.
    • +
  • +
+ +

See the Container-Managed Security Guide for more + information on setting up container managed security using the + Memory Based Realm component.

+ +
+ + +

JAAS Realm - org.apache.catalina.realm.JAASRealm

+ +

JAASRealm is an implementation of the Tomcat + Realm interface that authenticates users through the Java + Authentication & Authorization Service (JAAS) framework which is now + provided as part of the standard J2SE API.

+ +

Using JAASRealm gives the developer the ability to combine practically + any conceivable security realm with Tomcat's CMA.

+ +

JAASRealm is prototype for Tomcat of the JAAS-based J2EE authentication + framework for J2EE v1.4, based on the JCP Specification Request + 196 to enhance container-managed security and promote 'pluggable' + authentication mechanisms whose implementations would be + container-independent.

+ +

Based on the JAAS login module and principal + (see javax.security.auth.spi.LoginModule and + javax.security.Principal), you can develop your own security + mechanism or wrap another third-party mechanism for integration with the CMA + as implemented by Tomcat.

+ +

The JAAS Realm implementation supports the following additional + attributes:

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+
appName +

The name of the application as configured in your login configuration + file + (JAAS LoginConfig).

+
userClassNames +

A comma-separated list of the names of the classes that you have made + for your user Principals.

+
configFile +

The name of a JAAS configuration file to use with this Realm. It will + be searched for using ClassLoader#getResource(String) so it + is possible for the configuration to be bundled within a web + application. If not specified, the default JVM global JAAS configuration + will be used.

+
roleClassNames +

A comma-separated list of the names of the classes that you have made + for your role Principals.

+
stripRealmForGss +

When processing users authenticated via the GSS-API, this attribute + controls if any "@..." is removed from the end of the user + name. If not specified, the default is true.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
useContextClassLoader +

Instructs JAASRealm to use the context class loader for loading the + user-specified LoginModule class and associated + Principal classes. The default value is true, + which is backwards-compatible with the way Tomcat 5 works. To load + classes using the container's classloader, specify + false.

+
X509UsernameRetrieverClassName +

When using X509 client certificates, this specifies the class name + that will be used to retrieve the user name from the certificate. + The class must implement the + org.apache.catalina.realm.X509UsernameRetriever + interface. The default is to use the certificate's SubjectDN + as the username.

+
+ +

See the Container-Managed Security + Guide for more information on setting up container managed security + using the JAAS Realm component.

+ +
+ + +

Combined Realm - org.apache.catalina.realm.CombinedRealm

+ +

CombinedRealm is an implementation of the Tomcat + Realm interface that authenticates users through one or more + sub-Realms.

+ +

Using CombinedRealm gives the developer the ability to combine multiple + Realms of the same or different types. This can be used to authenticate + against different sources, provide fall back in case one Realm fails or for + any other purpose that requires multiple Realms.

+ +

Sub-realms are defined by nesting Realm elements inside the + Realm element that defines the CombinedRealm. Authentication + will be attempted against each Realm in the order they are + listed. Authentication against any Realm will be sufficient to authenticate + the user. The authenticated user, and their associated roles, will be taken + from the first Realm that successfully authenticates the user.

+ +

See the Container-Managed Security + Guide for more information on setting up container managed security + using the CombinedRealm component.

+ +

The CombinedRealm implementation supports the following additional + attributes.

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
+
+ + +

LockOut Realm - org.apache.catalina.realm.LockOutRealm

+ +

LockOutRealm is an implementation of the Tomcat + Realm interface that extends the CombinedRealm to provide lock + out functionality to provide a user lock out mechanism if there are too many + failed authentication attempts in a given period of time.

+ +

To ensure correct operation, there is a reasonable degree of + synchronization in this Realm.

+ +

This Realm does not require modification to the underlying Realms or the + associated user storage mechanisms. It achieves this by recording all failed + logins, including those for users that do not exist. To prevent a DOS by + deliberating making requests with invalid users (and hence causing this + cache to grow) the size of the list of users that have failed authentication + is limited.

+ +

Sub-realms are defined by nesting Realm elements inside the + Realm element that defines the LockOutRealm. Authentication + will be attempted against each Realm in the order they are + listed. Authentication against any Realm will be sufficient to authenticate + the user.

+ +

The LockOutRealm implementation supports the following additional + attributes.

+ +
+ Attribute + + Description +
allRolesMode +

This attribute controls how the special role name * is + handled when processing authorization constraints in web.xml. By + default, the specification compliant value of strict is + used which means that the user must be assigned one of the roles defined + in web.xml. The alternative values are authOnly which means + that the user must be authenticated but no check is made for assigned + roles and strictAuthOnly which means that the user must be + authenticated and no check will be made for assigned roles unless roles + are defined in web.xml in which case the user must be assigned at least + one of those roles.

+
cacheRemovalWarningTime +

If a failed user is removed from the cache because the cache is too + big before it has been in the cache for at least this period of time (in + seconds) a warning message will be logged. Defaults to 3600 (1 hour).

+
cacheSize +

Number of users that have failed authentication to keep in cache. Over + time the cache will grow to this size and may not shrink. Defaults to + 1000.

+
failureCount +

The number of times in a row a user has to fail authentication to be + locked out. Defaults to 5.

+
lockOutTime +

The time (in seconds) a user is locked out for after too many + authentication failures. Defaults to 300 (5 minutes). Further + authentication failures during the lock out time will cause the lock out + timer to reset to zero, effectively extending the lock out time. Valid + authentication attempts during the lock out period will not succeed but + will also not reset the lock out time.

+
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
+ +

See the Container-Managed Security + Guide for more information on setting up container managed security + using the LockOutRealm component.

+ +
+ +

Null Realm - org.apache.catalina.realm.NullRealm

+ +

NullRealm is a minimal implementation of the Tomcat + Realm interface that always returns null when an attempt is + made to validate a user name and associated credentials. It is intended to + be used as a default Realm implementation when no other Realm is + specified.

+ +

The NullRealm implementation supports the following additional + attributes.

+ +
+ Attribute + + Description +
transportGuaranteeRedirectStatus +

The HTTP status code to use when the container needs to issue an HTTP + redirect to meet the requirements of a configured transport + guarantee. The provided status code is not validated. If not + specified, the default value of 302 is used.

+
+ +
+ +

Nested Components

+ +

You can nest the following components by nesting the corresponding element + inside your Realm element:

+
    +
  • CombinedRealm Implementation - If you are using the + CombinedRealm Implementation or a Realm + that extends the CombinedRealm, e.g. the LockOutRealm, one or more + <Realm> elements may be nested inside it.
  • +
  • CredentialHandler - + You may nest at most one instance of this element inside a Realm. This + configures the credential handler that will be used to validate provided + credentials with those stored by the Realm. If not specified a default + MessageDigestCredentialHandler will be configured.
  • +
+ +

Special Features

+ +

See Single Sign On for information about + configuring Single Sign On support for a virtual host.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/resources.html b/test.dockerapp/tomcat/webapps/docs/config/resources.html new file mode 100644 index 0000000..4515e8a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/resources.html @@ -0,0 +1,320 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Resources Component

The Resources Component

Table of Contents

Introduction

+ +

The Resources element represents all the resources + available to the web application. This includes classes, JAR files, HTML, JSPs + and any other files that contribute to the web application. Implementations + are provided to use directories, JAR files and WARs as the source of these + resources and the resources implementation may be extended to provide support + for files stored in other forms such as in a database or a versioned + repository.

+ +

Resources are cached by default.

+ +

Note: Running a webapp with non-filesystem based + Resources implementations is only possible when the webapp does not + rely on direct filesystem access to its own resources, and uses the methods + in the ServletContext interface to access them.

+ +

A Resources element MAY be nested inside a + Context component. If it is not included, + a default filesystem based Resources will be created automatically, + which is sufficient for most requirements.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Resources support the following + attributes:

+ +
+ Attribute + + Description +
allowLinking +

If the value of this flag is true, symlinks will be + allowed inside the web application, pointing to resources inside or + outside the web application base path. If not specified, the default + value of the flag is false.

+

NOTE: This flag MUST NOT be set to true on the Windows platform + (or any other OS which does not have a case sensitive filesystem), + as it will disable case sensitivity checks, allowing JSP source code + disclosure, among other security problems.

+
cacheMaxSize +

The maximum size of the static resource cache in kilobytes. + If not specified, the default value is 10240 + (10 megabytes). This value may be changed while the web application is + running (e.g. via JMX). If the cache is using more memory than the new + limit the cache will attempt to reduce in size over time to meet the + new limit. If necessary, cacheObjectMaxSize will be + reduced to ensure that it is no larger than + cacheMaxSize/20.

+
cacheObjectMaxSize +

Maximum size of the static resource that will be placed in the cache. + If not specified, the default value is 512 + (512 kilobytes). If this value is greater than + cacheMaxSize/20 it will be reduced to + cacheMaxSize/20. This value may be changed while the web + application is running (e.g. via JMX).

+
cacheTtl +

The amount of time in milliseconds between the revalidation of cache + entries. If not specified, the default value is 5000 (5 + seconds). This value may be changed while the web application is running + (e.g. via JMX). When a resource is cached it will inherit the TTL in + force at the time it was cached and retain that TTL until the resource + is evicted from the cache regardless of any subsequent changes that may + be made to this attribute.

+
cachingAllowed +

If the value of this flag is true, the cache for static + resources will be used. If not specified, the default value + of the flag is true. This value may be changed while the + web application is running (e.g. via JMX). When the cache is disabled + any resources currently in the cache are cleared from the cache.

+
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.WebResourceRoot + interface. If not specified, the standard value (defined below) will be + used.

+
trackLockedFiles +

Controls whether the track locked files feature is enabled. If + enabled, all calls to methods that return objects that lock a file and + need to be closed to release that lock (e.g. + ServletContext.getResourceAsStream()) will perform a number + of additional tasks.

+
    +
  • The stack trace at the point where the method was called will be + recorded and associated with the returned object.
  • +
  • The returned object will be wrapped so that the point where + close() (or equivalent) is called to release the resources can be + detected. Tracking of the object will cease once the resources have + been released.
  • +
  • All remaining locked resources on web application shutdown will be + logged and then closed.
  • +
+

If not specified, the default value of false will be + used.

+
+ +
+ + +

Standard Implementation

+ +

Standard Root Implementation

+ +

The standard implementation of Resources is + org.apache.catalina.webresources.StandardRoot. It does not + support any additional attributes.

+ +

Extracting Root Implementation

+ +

The extracting implementation of Resources is + org.apache.catalina.webresources.ExtractingRoot. It does not + support any additional attributes.

+ +

When deploying web applications as packed WAR files, the extracting root + will extract any JAR files from /WEB-INF/lib to a + application-jars directory located in the web + application's working directory. These extracted JARs will be removed + when the web application stops.

+ +

Extracting JAR files from a packed WAR may provide a performance + improvement, particularly at web application start when JAR scanning is + required by the application.

+ +
+ +

Nested Components

+ +

A web application's main resources are defined by the + docBase defined for the Context. + Additional resources may be made available to the web application by defining + one or more nested components.

+ +

PreResources

+ +

PreResources are searched before the main resources. They will be searched + in the order they are defined. To configure PreResources, nest a + <PreResources> element inside the <Resources> element with the + following attributes:

+ +
+ Attribute + + Description +
base +

Identifies where the resources to be used are located. This attribute + is required by the org.apache.catalina.WebResourceSet + implementations provided by Tomcat and should specify the absolute path to + the file, directory or JAR where the resources are located. Custom + implementations may not require it.

+
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.WebResourceSet interface. + Tomcat provides three standard implementations: + org.apache.catalina.webresources.DirResourceSet, + org.apache.catalina.webresources.FileResourceSet and + org.apache.catalina.webresources.JarResourceSet. Custom + implementations may also be used. +

+
internalPath +

Identifies the path within the base where the + resources are to be found. This is typically only used with JAR files when + the resources are not located at the root of the JAR as is the case with + resource JARs. This attribute is required by the + org.apache.catalina.WebResourceSet implementations provided + by Tomcat and must start with '/'. Custom implementations may not require + it. If not specified, the default value '/' will be used.

+
readOnly +

If true, resources within this resource set may not be + deleted, created or modified. For instance of + org.apache.catalina.webresources.JarResourceSet, this + attribute is hard-coded to true and may not be changed. For + instances of org.apache.catalina.webresources.DirResourceSet + and org.apache.catalina.webresources.FileResourceSet the + default value of this attribute is false.

+
webAppMount +

Identifies the path within the web application that these resources + will be made available. For the + org.apache.catalina.WebResourceSet implementations provided + by Tomcat, this attribute is required and must start with '/'. Custom + implementations may not require it. If not specified, the default value of + '/' will be used.

+
+ +

JAR resources

+ +

JarResources are searched after the main resources but before the + PostResources. They will be searched in the order they are defined. To + configure JarResources, nest a <JarResources> element inside the + <Resources> element. The configuration attributes are the same as for + PreResources. +

+ +

During web application start, the JAR scanning process checks scanned JARs + for content under /META-INF/resources. Where found, this static + content is added to the JarResources. +

+ +

Post-resources

+ +

PostResources are searched after the resource JARs. They will be searched + in the order they are defined. To configure PostResources, nest a + <PostResources> element inside the <Resources> element. The + configuration attributes are the same as for PreResources. +

+ +

Ordering

+ +

In addition to the sets of resources described above, the standard + implementation also maintains ClassResources which represent the classes + contained in the JAR files mapped to /WEB-INF/classes. This + allows other components to search for classes with a single call rather than + one call to search /WEB-INF/classes followed by another to search + the JARs in /WEB-INF/lib. The ClassResources are populated + from the JARs mapped to /WEB-INF/lib when the web application + starts.

+ +

Therefore, the complete search order is:

+
    +
  • PreResources
  • +
  • MainResources
  • +
  • ClassResources
  • +
  • JarResources
  • +
  • PostResources
  • +
+ +

The population of ClassResources and JarResources at web application start + means that care needs to be taken to add JAR based resources correctly to + obtain the desired behaviour. Consider the following example:

+ +
<Resources>
+  <PostResources base="D:\Projects\external\classes"
+                 className="org.apache.catalina.webresources.DirResourceSet"
+                 webAppMount="/WEB-INF/classes"/>
+  <PostResources base="D:\Projects\lib\library1.jar"
+                 className="org.apache.catalina.webresources.FileResourceSet"
+                 webAppMount="/WEB-INF/lib/library1.jar"/>
+</Resources>
+ +

Since both resources are PostResources, it might be expected that + D:\Projects\external\classes will be searched for classes before + D:\Projects\lib\library1.jar. However, by adding the JAR using a + FileResourceSet, the JAR is mapped to /WEB-INF/lib + and will be processed at application start along with the other JARs in + /WEB-INF/lib. The classes from the JAR file will be added to the + ClassResources which means they will be searched before the classes from + D:\Projects\external\classes. If the desired behaviour is that + D:\Projects\external\classes is searched before + D:\Projects\lib\library1.jar then a slightly different + configuration is required:

+ +
<Resources>
+  <PostResources base="D:\Projects\external\classes"
+                 className="org.apache.catalina.webresources.DirResourceSet"
+                 webAppMount="/WEB-INF/classes"/>
+  <PostResources base="D:\Projects\lib\library1.jar"
+                 className="org.apache.catalina.webresources.JarResourceSet"
+                 webAppMount="/WEB-INF/classes"/>
+</Resources>
+ +

In short, the JAR file should be added as a JarResourceSet + mapped to /WEB-INF/classes rather than using a + FileResourceSet mapped to /WEB-INF/lib. +

+ +

Special Features

+ +

No special features are associated with a Resources + element.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/server.html b/test.dockerapp/tomcat/webapps/docs/config/server.html new file mode 100644 index 0000000..d8cd21c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/server.html @@ -0,0 +1,123 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Server Component

The Server Component

Table of Contents

Introduction

+ +

A Server element represents the entire Catalina + servlet container. Therefore, it must be the single outermost element + in the conf/server.xml configuration file. Its attributes + represent the characteristics of the servlet container as a whole.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Server + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Server interface. + If no class name is specified, the standard implementation will + be used.

+
address +

The TCP/IP address on which this server waits for a shutdown + command. If no address is specified, localhost is used.

+
port +

The TCP/IP port number on which this server waits for a shutdown + command. Set to -1 to disable the shutdown port.

+

Note: Disabling the shutdown port works well when Tomcat is started + using Apache Commons Daemon + (running as a service on Windows or with jsvc on un*xes). It cannot be + used when running Tomcat with the standard shell scripts though, as it + will prevent shutdown.bat|.sh and catalina.bat|.sh from stopping it + gracefully.

+
shutdown +

The command string that must be received via a TCP/IP connection + to the specified port number, in order to shut down Tomcat.

+
+ +
+ +

Standard Implementation

+ +

The standard implementation of Server is + org.apache.catalina.core.StandardServer. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
+ +
+ +

Nested Components

+ +

The following components may be nested inside a Server + element:

+ + +

Special Features

+ +

There are no special features associated with a Server. +

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/service.html b/test.dockerapp/tomcat/webapps/docs/config/service.html new file mode 100644 index 0000000..cdbdce4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/service.html @@ -0,0 +1,110 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Service Component

The Service Component

Table of Contents

Introduction

+ +

A Service element represents the combination of one or + more Connector components that share a single + Engine component for processing incoming + requests. One or more Service elements may be nested + inside a Server element.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of Service + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.Service interface. + If no class name is specified, the standard implementation will + be used.

+
name +

The display name of this Service, which will + be included in log messages if you utilize standard Catalina + components. The name of each Service that is + associated with a particular Server + must be unique.

+
+ +
+ +

Standard Implementation

+ +

The standard implementation of Service is + org.apache.catalina.core.StandardService. + It supports the following additional attributes (in addition to the + common attributes listed above):

+ +
+ Attribute + + Description +
+ +
+ +

Nested Components

+ +

The only components that may be nested inside a Service + element are one or more Connector elements, + followed by exactly one Engine element.

+ +

Special Features

+ +

There are no special features associated with a Service. +

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/sessionidgenerator.html b/test.dockerapp/tomcat/webapps/docs/config/sessionidgenerator.html new file mode 100644 index 0000000..3774887 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/sessionidgenerator.html @@ -0,0 +1,131 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The SessionIdGenerator Component

The SessionIdGenerator Component

Table of Contents

Introduction

+ +

The SessionIdGenerator element represents the session + id generator that will be used to create session ids used by + web application HTTP sessions.

+ +

A SessionIdGenerator element MAY be nested inside a + Manager component. If it is not included, + a default SessionIdGenerator configuration will be created automatically, which + is sufficient for most requirements, — see + Standard SessionIdGenerator Implementation below for the details + of this configuration.

+ +

Attributes

+ +

Common Attributes

+ +

All implementations of SessionIdGenerator + support the following attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.SessionIdGenerator interface. + If not specified, the standard value (defined below) will be used.

+
jvmRoute +

A routing identifier for this Tomcat instance. It will be added + to the session id to allow for stateless stickyness routing by + load balancers. The details on how the jvmRoute + will be included in the id are implementation dependent. + See Standard Implementation + for the default behavior.

+ +

NOTE - The value for this property is inherited + automatically from the jvmRoute attribute of the + Engine element.

+
sessionIdLength +

The length of session ids created by this SessionIdGenerator. + The details on how the sessionIdLength + influences the session id length are implementation dependent. + See Standard Implementation + for the default behavior.

+
+ +
+ + +

Standard Implementation

+ +

Tomcat provides a standard implementations of SessionIdGenerator + for use.

+ +

Standard SessionIdGenerator Implementation

+ +

The standard implementation of SessionIdGenerator is + org.apache.catalina.util.StandardSessionIdGenerator. + It supports the following attributes:

+ +
+ Attribute + + Description +
jvmRoute +

A routing identifier for this Tomcat instance. It will be added + to the end of the session id separated by a ".".

+
sessionIdLength +

The length of session ids created by this SessionIdGenerator. + More precisely the session id length is twice the value of + sessionIdLength plus the length of the trailing + jvmRoute if given. The factor 2 is because + the session id is constructed using sessionIdLength + random bytes, each byte being encoded in two hex characters + in the actual id. The default value is 16.

+
+ +
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/systemprops.html b/test.dockerapp/tomcat/webapps/docs/config/systemprops.html new file mode 100644 index 0000000..caeaaca --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/systemprops.html @@ -0,0 +1,626 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - System Properties

System Properties

Table of Contents

Introduction

+

The following sections list the system properties that may be set to modify + the default Tomcat behaviour.

+

Property replacements

+
+ Property + + Description +
org.apache.tomcat.util.digester. PROPERTY_SOURCE +

Set this to a fully qualified name of a class that implements + org.apache.tomcat.util.IntrospectionUtils.PropertySource. + Required to have a public constructor with no arguments.

+

Use this to add a property source, that will be invoked when ${parameter} + denoted parameters are found in the XML files that Tomcat parses.

+
+ +

Clustering

+
+ Property + + Description +
org.apache.catalina. tribes.dns_lookups +

If true, the clustering module will attempt to use DNS to + resolve any host names provided in the cluster configuration.

+

If not specified, the default value of false will be used.

+
+ +

Expression Language

+
+ Property + + Description +
org.apache.el.BeanELResolver. CACHE_SIZE +

The number of javax.el.BeanELResolver.BeanProperties objects that will + be cached by the EL Parser.

+

If not specified, the default of 1000 will be used.

+
org.apache.el.ExpressionBuilder. CACHE_SIZE +

The number of parsed EL expressions that will be cached by the EL + Parser.

+

If not specified, the default of 5000 will be used.

+
org.apache.el.parser. COERCE_TO_ZERO +

If true, when coercing nulls to objects of + type Number, Character or Boolean the result will be 0 for + Number and Character types and false for Boolean as required + by the EL 2.2 and earlier specifications. If this property is + false the result of the coercion will be null as + required by the EL 3.0 specification.

+

If not specified, the default value of false will be + used.

+
org.apache.el.parser. SKIP_IDENTIFIER_CHECK +

If true, when parsing expressions, identifiers will not be + checked to ensure that they conform to the Java Language Specification for + Java identifiers.

+

If not specified, the default value of false will be used.

+
+

Jasper

+
+ Property + + Description +
org.apache.jasper.compiler. Generator.POOL_TAGS_WITH_EXTENDS +

By default, JSPs that use their own base class via the extends + attribute of the page directive, will have Tag pooling disabled since + Jasper cannot guarantee that the necessary initialisation will have taken + place. This can have a negative impact on performance. Providing the + alternative base class calls _jspInit() from Servlet.init(), setting this + property to true will enable pooling with an alternative base + class. If the alternative base class does not call _jspInit() and this + property is true, NPEs will occur when attempting to use + tags.

+

If not specified, the default value of false will be used. +

+
org.apache.jasper.compiler. Generator.STRICT_GET_PROPERTY +

If true, the requirement to have the object referenced in + jsp:getProperty action to be previously "introduced" + to the JSP processor, as specified in the chapter JSP.5.3 of JSP 2.0 and + later specifications, is enforced.

+

If not specified, the specification compliant default of + true will be used.

+
org.apache.jasper.compiler. Generator.VAR_EXPRESSIONFACTORY +

The name of the variable to use for the expression language expression + factory.

+

If not specified, the default value of _el_expressionfactory + will be used.

+
org.apache.jasper.compiler. Generator.VAR_INSTANCEMANAGER +

The name of the variable to use for the instance manager factory.

+

If not specified, the default value of _jsp_instancemanager + will be used.

+
org.apache.jasper.compiler. Parser.STRICT_QUOTE_ESCAPING +

Deprecated. Configures the default setting for the + strictQuoteEscaping JSP initialisation paramater.

+

If not specified, the specification compliant default of + true will be used.

+
org.apache.jasper.compiler. Parser.STRICT_WHITESPACE +

If false the requirements for whitespace before an + attribute name will be relaxed so that the lack of whitespace will not + cause an error.

+

If not specified, the specification compliant default of + true will be used.

+
org.apache.jasper.runtime. BodyContentImpl.BUFFER_SIZE +

The size (in characters) to use when creating a tag buffer.

+

If not specified, the default value of + org.apache.jasper.Constants.DEFAULT_TAG_BUFFER_SIZE (512) + will be used.

+
org.apache.jasper.runtime. BodyContentImpl.LIMIT_BUFFER +

If true, any tag buffer that expands beyond + org.apache.jasper.runtime.BodyContentImpl.BUFFER_SIZE will be + destroyed and a new buffer created.

+

If not specified, the default value of false will be used.

+
org.apache.jasper.runtime. JspFactoryImpl.USE_POOL +

If true, a ThreadLocal PageContext pool will + be used.

+

If not specified, the default value of true will be used.

+
org.apache.jasper.runtime. JspFactoryImpl.POOL_SIZE +

The size of the ThreadLocal PageContext.

+

If not specified, the default value of 8 will be used.

+
org.apache.jasper.Constants. JSP_SERVLET_BASE +

The base class of the Servlets generated from the JSPs.

+

If not specified, the default value of + org.apache.jasper.runtime.HttpJspBase will be used.

+
org.apache.jasper.Constants. SERVICE_METHOD_NAME +

The name of the service method called by the base class.

+

If not specified, the default value of _jspService + will be used.

+
org.apache.jasper.Constants. SERVLET_CLASSPATH +

The name of the ServletContext attribute that provides the classpath + for the JSP.

+

If not specified, the default value of + org.apache.catalina.jsp_classpath will be used.

+
org.apache.jasper.Constants. JSP_FILE +

The name of the request attribute for <jsp-file> + element of a servlet definition. If present on a request, this overrides + the value returned by request.getServletPath() to select the + JSP page to be executed.

+

If not specified, the default value of + org.apache.catalina.jsp_file will be used.

+

Deprecated: This will be removed in Tomcat 9.0.x + onwards. It is replaced by the use of the jspFile servlet initialisation + parameter

+
org.apache.jasper.Constants. PRECOMPILE +

The name of the query parameter that causes the JSP engine to just + pregenerate the servlet but not invoke it.

+

If not specified, the default value of jsp_precompile + will be used, as defined by JSP specification (JSP.11.4.2).

+
org.apache.jasper.Constants. JSP_PACKAGE_NAME +

The default package name for compiled jsp pages.

+

If not specified, the default value of org.apache.jsp + will be used.

+
org.apache.jasper.Constants. TAG_FILE_PACKAGE_NAME +

The default package name for tag handlers generated from tag files.

+

If not specified, the default value of org.apache.jsp.tag + will be used.

+
org.apache.jasper.Constants. ALT_DD_ATTR +

The servlet context attribute under which the alternate deployment + descriptor for this web application is stored.

+

If not specified, the default value of + org.apache.catalina.deploy.alt_dd will be used.

+
org.apache.jasper.Constants. TEMP_VARIABLE_NAME_PREFIX +

Prefix to use for generated temporary variable names.

+

If not specified, the default value of _jspx_temp + will be used.

+
org.apache.jasper.Constants. USE_INSTANCE_MANAGER_FOR_TAGS +

If true, the instance manager is used to obtain tag + handler instances.

+

If not specified, the default value of false will be used.

+
+ +

Security

+ +
+ Property + + Description +
org.apache.catalina.connector. RECYCLE_FACADES +

If this is true or if a security manager is in use a new + facade object will be created for each request.

+

If not specified, the default value of false will be used.

+
org.apache.catalina.connector. CoyoteAdapter.ALLOW_BACKSLASH +

If this is true the '\' character will be permitted as a + path delimiter.

+

If not specified, the default value of false will be used.

+
org.apache.tomcat.util.buf. UDecoder.ALLOW_ENCODED_SLASH +

If this is true '%2F' and '%5C' will be permitted as path + delimiters.

+

If not specified, the default value of false will be used.

+
+ +

Specifications

+ +
+ Property + + Description +
org.apache.catalina. STRICT_SERVLET_COMPLIANCE +

The default value of this system property is false.

+

If this is true the default values will be changed for:

+
    +
  • org.apache.catalina.core.
    ApplicationContext.GET_RESOURCE_REQUIRE_SLASH
  • +
  • org.apache.catalina.core.
    ApplicationDispatcher.WRAP_SAME_OBJECT
  • +
  • org.apache.catalina.core.
    StandardHostValve.ACCESS_SESSION
  • +
  • org.apache.catalina.session.
    StandardSession.ACTIVITY_CHECK
  • +
  • org.apache.catalina.session.
    StandardSession.LAST_ACCESS_AT_START
  • +
  • org.apache.tomcat.util.http.
    ServerCookie.ALWAYS_ADD_EXPIRES
  • +
  • org.apache.tomcat.util.http.
    ServerCookie.FWD_SLASH_IS_SEPARATOR
  • +
  • org.apache.tomcat.util.http.
    ServerCookie.STRICT_NAMING
  • +
  • The URIEncoding attribute of any + HTTP connector or + AJP connector element.
  • +
  • The resourceOnlyServlets attribute of any + Context element.
  • +
  • The tldValidation attribute of any + Context element.
  • +
  • The useRelativeRedirects attribute of any + Context element.
  • +
  • The xmlNamespaceAware attribute of any + Context element.
  • +
  • The xmlValidation attribute of any + Context element.
  • +
+ +

Note that changing a number of the above defaults is likely to break + the majority of systems as some browsers are unable to correctly handle + the cookie headers that result from a strict adherence to the + specifications. Defaults, regardless of whether or not they have been + changed by setting + org.apache.catalina.STRICT_SERVLET_COMPLIANCE can always be + overridden by explicitly setting the appropriate system property or element + attribute.

+
org.apache.catalina.connector. Response.ENFORCE_ENCODING_IN_GET_WRITER +

If this is true then + a call to Response.getWriter() if no character encoding + has been specified will result in subsequent calls to + Response.getCharacterEncoding() returning + ISO-8859-1 and the Content-Type response header + will include a charset=ISO-8859-1 component. (SRV.15.2.22.1)

+

If not specified, the default specification compliant value of + true will be used.

+
org.apache.catalina.core.ApplicationContext .GET_RESOURCE_REQUIRE_SLASH +

If this is true then the path passed to + ServletContext.getResource() or + ServletContext.getResourceAsStream() must start with + "/". If false, code like + getResource("myfolder/myresource.txt") will work as Tomcat + will prepend "/" to the provided path.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
org.apache.catalina.core. ApplicationDispatcher.WRAP_SAME_OBJECT +

If this is true then any wrapped request or response + object passed to an application dispatcher will be checked to ensure that + it has wrapped the original request or response.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
org.apache.tomcat.websocket. STRICT_SPEC_COMPLIANCE +

The default value of this system property is false.

+

If this is true the default values will be changed for:

+
    +
  • org.apache.tomcat.websocket.server#isEnforceNoAddAfterHandshake + (default changes from false to true)
  • +
+ +
org.apache.tomcat.util.http. ServerCookie.ALLOW_EQUALS_IN_VALUE +

Deprecated. This will be removed in Tomcat 9. Specify the + allowEqualsInValue attribute on the + org.apache.tomcat.util.http.LegacyCookieProcessor + instead.

+

This sets the default value for allowEqualsInValue + attribute on the + org.apache.tomcat.util.http.LegacyCookieProcessor. + If this is true Tomcat will allow '=' + characters when parsing unquoted cookie values. If false, + cookie values containing '=' will be terminated when the + '=' is encountered and the remainder of the cookie value will + be dropped.

+

If not specified, the default specification compliant value of + false will be used.

+
org.apache.tomcat.util.http. ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0 +

Deprecated. This will be removed in Tomcat 9. Specify the + allowHttpSepsInV0 attribute on the + org.apache.tomcat.util.http.LegacyCookieProcessor + instead.

+

This sets the default value for allowHttpSepsInV0 + attribute on the + org.apache.tomcat.util.http.LegacyCookieProcessor. + If this is true Tomcat will allow HTTP separators in + cookie names and values.

+

If not specified, the default specification compliant value of + false will be used.

+
org.apache.tomcat.util.http. ServerCookie.ALLOW_NAME_ONLY +

Deprecated. This will be removed in Tomcat 9. Specify the + allowNameOnly attribute on the + org.apache.tomcat.util.http.LegacyCookieProcessor + instead.

+

If this is false then the requirements of the cookie specifications + that cookies must have values will be enforced and cookies consisting only + of a name but no value will be ignored.

+

If not specified, the default specification compliant value of + false will be used.

+
org.apache.tomcat.util.http. ServerCookie.ALWAYS_ADD_EXPIRES +

If this is true Tomcat will always add an expires + parameter to a SetCookie header even for cookies with version greater than + zero. This is to work around a known IE6 and IE7 bug that causes IE to + ignore the Max-Age parameter in a SetCookie header.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be false, + else the default value will be true.

+
org.apache.tomcat.util.http. ServerCookie.FWD_SLASH_IS_SEPARATOR +

If this is true then the / (forward slash) character will + be treated as a separator. Note that this character is frequently used in + cookie path attributes and some browsers will fail to process a cookie if + the path attribute is quoted as is required by a strict adherence to the + specifications. This is highly likely to break session tracking using + cookies.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
org.apache.tomcat.util.http. ServerCookie.PRESERVE_COOKIE_HEADER +

Deprecated. This attribute is no longer used. From Tomcat 8.0.31, + Tomcat will always preserve the cookie header returned by + HttpServletRequest.getHeader(). This will be removed in + Tomcat 9.

+
org.apache.tomcat.util.http. ServerCookie.STRICT_NAMING +

If this is true then the requirements of the Servlet specification + that Cookie names must adhere to RFC2109 (no use of separators) will be + enforced.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
+ +

Sessions

+ +
+ Property + + Description +
org.apache.catalina.authenticator. Constants.SSO_SESSION_COOKIE_NAME +

An alternative name for the single sign on session cookie. Defaults to + JSESSIONIDSSO.

+
org.apache.catalina.core. StandardHostValve.ACCESS_SESSION +

If this is true, every request that is associated with a + session will cause the session's last accessed time to be updated + regardless of whether or not the request explicitly accesses the session.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
org.apache.catalina.session. StandardSession.ACTIVITY_CHECK +

If this is true, Tomcat will track the number of active + requests for each session. When determining if a session is valid, any + session with at least one active request will always be considered valid.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
org.apache.catalina.session. StandardSession.LAST_ACCESS_AT_START +

If this is true, the last accessed time for sessions will + be calculated from the beginning of the previous request. If + false, the last accessed time for sessions will be calculated + from the end of the previous request. This also affects how the idle time + is calculated.

+

If org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to + true, the default of this setting will be true, + else the default value will be false.

+
+ +

Logging

+ +
+ Property + + Description +
org.apache.juli.formatter +

If no logging configuration file is specified and no logging configuration class is specified + using the java.util.logging.config.class and java.util.logging.config.file + properties the default logging framework org.apache.juli will use the default + java.util.logging.SimpleFormatter for all console output. + To simply override the console output formatter, one can use the described property. Example: + -Dorg.apache.juli.formatter=org.apache.juli.OneLineFormatter

+
org.apache.juli. AsyncOverflowDropType +

When the memory limit of records has been reached the system needs to determine what action to take. + Currently there are three actions that can be taken: +

+
    +
  • int OVERFLOW_DROP_LAST = 1 - the record that caused the overflow will be dropped and not logged
  • +
  • int OVERFLOW_DROP_FIRST = 2 - the record that is next in line to be logged will be dropped to make room for the latest record on the queue
  • +
  • int OVERFLOW_DROP_FLUSH = 3 - suspend the thread while the queue empties out and flushes the entries to the write buffer
  • +
  • int OVERFLOW_DROP_CURRENT = 4 - drop the current log entry
  • +
+

The default value is 1 (OVERFLOW_DROP_LAST).

+
org.apache.juli. AsyncMaxRecordCount +

The max number of log records that the async logger will keep in memory. When this limit is reached and a new record is being logged by the + JULI framework the system will take an action based on the org.apache.juli.AsyncOverflowDropType setting.

+

The default value is 10000 records. + This number represents the global number of records, not on a per handler basis. +

+
org.apache.juli. AsyncLoggerPollInterval +

The poll interval in milliseconds for the asynchronous logger thread in milliseconds. + If the log queue is empty, the async thread will issue a poll(poll interval) + in order to not wake up too often.

+

The default value is 1000 milliseconds.

+
org.apache.juli.logging. UserDataHelper.CONFIG +

The type of logging to use for errors generated by invalid input data. + The options are: DEBUG_ALL, INFO_THEN_DEBUG, + INFO_ALL and NONE. When + INFO_THEN_DEBUG is used, the period for which errors are + logged at DEBUG rather than INFO is controlled by the system property + org.apache.juli.logging.UserDataHelper.SUPPRESSION_TIME. +

+

The default value is INFO_THEN_DEBUG.

+

The errors currently logged using this system are:

+
    +
  • invalid cookies;
  • +
  • invalid parameters;
  • +
  • too many headers, too many parameters (hitting + maxHeaderCount or maxParameterCount limits + of a connector).
  • +
  • invalid host names
  • +
+

Other errors triggered by invalid input data may be added to this + system in later versions.

+
org.apache.juli.logging. UserDataHelper.SUPPRESSION_TIME +

When using INFO_THEN_DEBUG for + org.apache.juli.logging.UserDataHelper.CONFIG this system + property controls how long messages are logged at DEBUG after a message + has been logged at INFO. Once this period has elapsed, the next message + will be logged at INFO followed by a new suppression period where + messages are logged at DEBUG and so on. The value is measured + in seconds.

+

A value of 0 is equivalent to using INFO_ALL + for org.apache.juli.logging.UserDataHelper.CONFIG.

+

A negative value means an infinite suppression period.

+

The default value is 86400 (24 hours).

+
+ +

JAR Scanning

+ +
+ Property + + Description +
tomcat.util.scan. StandardJarScanFilter.jarsToSkip +

A list of comma-separated file name patters that is used as the default + value for pluggabilitySkip and tldSkip + attributes of the standard + JarScanFilter implementation.

+

The coded default empty, however the system property is set in + a default Tomcat installation via the + $CATALINA_BASE/conf/catalina.properties file.

+
tomcat.util.scan. StandardJarScanFilter.jarsToScan +

A list of comma-separated file name patters that is used as the default + value for pluggabilityScan and tldScan + attributes of the standard + JarScanFilter implementation.

+

The coded default empty, however the system property is set in + a default Tomcat installation via the + $CATALINA_BASE/conf/catalina.properties file.

+
+ +

Websockets

+ +
+ Property + + Description +
org.apache.tomcat .websocket.ALLOW_UNSUPPORTED_EXTENSIONS +

If true, allow unknown extensions to be declared by + the user.

+

The default value is false.

+
org.apache.tomcat. websocket.DEFAULT_ORIGIN_HEADER_VALUE +

Default value of the origin header that will be sent by the client + during the upgrade handshake.

+

The default is null so that no origin header is sent.

+
org.apache.tomcat. websocket.DEFAULT_PROCESS_PERIOD +

The number of periodic ticks between periodic processing which + involves in particular session expiration checks.

+

The default value is 10 which corresponds to 10 + seconds.

+
org.apache.tomcat. websocket.DISABLE_BUILTIN_EXTENSIONS +

If true, disable all built-in extensions provided by the + server, such as message compression.

+

The default value is false.

+
org.apache.tomcat. websocket.STREAMS_DROP_EMPTY_MESSAGES +

If true, streams provided to the user (writer and output + stream) will not send an empty message when flushing and there is no + data to flush, or when it is closed without having been used (for + example if an error occurs).

+

The default value is false.

+
+ +

Other

+ +
+ Property + + Description +
org.apache.coyote. USE_CUSTOM_STATUS_MSG_IN_HEADER

If this is + true, custom HTTP status messages will be used within HTTP + headers. If a custom message is specified that is not valid for use in an + HTTP header (as defined by RFC2616) then the custom message will be + ignored and the default message used.

+

If not specified, the default value of false will be used.

+
catalina.useNaming +

If this is false it will override the + useNaming attribute for all + Context elements.

+
javax.sql.DataSource.Factory +

The class name of the factory to use to create resources of type + javax.sql.DataSource. If not specified the default of + org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory is used + which is a package renamed (to avoid conflicts) copy of + Apache Commons DBCP.

+
javax.mail.Session.Factory +

The class name of the factory to use to create resources of type + javax.mail.Session. If not specified the default of + org.apache.naming.factory.MailSessionFactory is used.

+
jvmRoute +

Provides a default value for the jvmRoute attribute of the + Engine element. It does not override the value + configured on the Engine element.

+
catalina.config +

The URL for the catalina.properties configuration file.

+
tomcat.util.buf.StringCache.byte.enabled +

If true, the String cache is enabled for + ByteChunk.

+

If not specified, the default value of false will be used.

+
tomcat.util.buf.StringCache.char.enabled +

If true, the String cache is enabled for + CharChunk.

+

If not specified, the default value of false will be used.

+
tomcat.util.buf.StringCache.trainThreshold +

The number of times toString() must be called before the + cache is activated.

+

If not specified, the default value of 20000 will be used.

+
tomcat.util.buf.StringCache.cacheSize +

The size of the String cache.

+

If not specified, the default value of 200 will be used.

+
org.apache.tomcat.util.buf.UriUtil. WAR_SEPARATOR +

The character to use to separate the WAR file and WAR content parts of + a WAR URL using the custom WAR scheme provided by Tomcat. This is + equivalent to how ! is used in JAR URLs.

+

If not specified, the default value of * will be used.

+
tomcat.util.buf.StringCache.maxStringSize +

The maximum length of String that will be cached.

+

If not specified, the default value of 128 will be used.

+
org.apache.tomcat.util. http.FastHttpDateFormat.CACHE_SIZE +

The size of the cache to use parsed and formatted date value.

+

If not specified, the default value of 1000 will be used.

+
org.apache.tomcat.util. net.NioSelectorShared +

If true, use a shared selector for servlet write/read.

+

If not specified, the default value of true will be used.

+
org.apache.catalina.startup. EXIT_ON_INIT_FAILURE +

If true, the server will exit if an exception happens + during the server initialization phase.

+

If not specified, the default value of false will be used.

+
org.apache.catalina.startup. RealmRuleSet.MAX_NESTED_REALM_LEVELS +

The CombinedRealm allows nested Realms. This property controls the + maximum permitted number of levels of nesting.

+

If not specified, the default value of 3 will be used.

+
org.apache.catalina.startup. CredentialHandlerRuleSet.MAX_NESTED_LEVELS +

The NestedCredentialHandler allows nested CredentialHandlers. This + property controls the maximum permitted number of levels of nesting.

+

If not specified, the default value of 3 will be used.

+
tomcat.util.http.parser.HttpParser. requestTargetAllow +

This system property is deprecated. Use the + relaxedPathChars and relaxedQueryChars + attributes of the Connector instead. These attributes permit a wider range + of characters to be configured as valid.

+

A string comprised of characters the server should allow even when they are not encoded. + These characters would normally result in a 400 status.

+

The acceptable characters for this property are: |, { + , and }

+

WARNING: Use of this option may expose the server to CVE-2016-6816. +

+

If not specified, the default value of null will be used.

+
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/config/valve.html b/test.dockerapp/tomcat/webapps/docs/config/valve.html new file mode 100644 index 0000000..fbfeb4b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/config/valve.html @@ -0,0 +1,1592 @@ + +Apache Tomcat 8 Configuration Reference (8.0.53) - The Valve Component

The Valve Component

Table of Contents

Introduction

+ +

A Valve element represents a component that will be + inserted into the request processing pipeline for the associated + Catalina container (Engine, + Host, or Context). + Individual Valves have distinct processing capabilities, and are + described individually below.

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

Access Logging

+ +

Access logging is performed by valves that implement +org.apache.catalina.AccessLog interface.

+ +

Access Log Valve

+ +

Introduction

+ +

The Access Log Valve creates log files in the + same format as those created by standard web servers. These logs + can later be analyzed by standard log analysis tools to track page + hit counts, user session activity, and so on. This Valve + uses self-contained logic to write its log files, which can be + automatically rolled over at midnight each day. (The essential + requirement for access logging is to handle a large continuous + stream of data with low overhead. This Valve does not + use Apache Commons Logging, thus avoiding additional overhead and + potentially complex configuration).

+ +

This Valve may be associated with any Catalina container + (Context, Host, or Engine), and + will record ALL requests processed by that container.

+ +

Some requests may be handled by Tomcat before they are passed to a + container. These include redirects from /foo to /foo/ and the rejection of + invalid requests. Where Tomcat can identify the Context that + would have handled the request, the request/response will be logged in the + AccessLog(s) associated Context, Host + and Engine. Where Tomcat cannot identify the + Context that would have handled the request, e.g. in cases + where the URL is invalid, Tomcat will look first in the Engine, + then the default Host for the Engine and finally + the ROOT (or default) Context for the default Host + for an AccessLog implementation. Tomcat will use the first + AccessLog implementation found to log those requests that are + rejected before they are passed to a container.

+ +

The output file will be placed in the directory given by the + directory attribute. The name of the file is composed + by concatenation of the configured prefix, timestamp and + suffix. The format of the timestamp in the file name can be + set using the fileDateFormat attribute. This timestamp will + be omitted if the file rotation is switched off by setting + rotatable to false.

+ +

Warning: If multiple AccessLogValve instances + are used, they should be configured to use different output files.

+ +

If sendfile is used, the response bytes will be written asynchronously + in a separate thread and the access log valve will not know how many bytes + were actually written. In this case, the number of bytes that was passed to + the sendfile thread for writing will be recorded in the access log valve. +

+
+ +

Attributes

+ +

The Access Log Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.AccessLogValve to use the + default access log valve.

+
directory +

Absolute or relative pathname of a directory in which log files + created by this valve will be placed. If a relative path is + specified, it is interpreted as relative to $CATALINA_BASE. If + no directory attribute is specified, the default value is "logs" + (relative to $CATALINA_BASE).

+
prefix +

The prefix added to the start of each log file's name. If not + specified, the default value is "access_log".

+
suffix +

The suffix added to the end of each log file's name. If not + specified, the default value is "" (a zero-length string), + meaning that no suffix will be added.

+
fileDateFormat +

Allows a customized timestamp in the access log file name. + The file is rotated whenever the formatted timestamp changes. + The default value is .yyyy-MM-dd. + If you wish to rotate every hour, then set this value + to .yyyy-MM-dd.HH. + The date format will always be localized + using the locale en_US. +

+
rotatable +

Flag to determine if log rotation should occur. + If set to false, then this file is never rotated and + fileDateFormat is ignored. + Default value: true +

+
renameOnRotate +

By default for a rotatable log the active access log file name + will contain the current timestamp in fileDateFormat. + During rotation the file is closed and a new file with the next + timestamp in the name is created and used. When setting + renameOnRotate to true, the timestamp + is no longer part of the active log file name. Only during rotation + the file is closed and then renamed to include the timestamp. + This is similar to the behavior of most log frameworks when + doing time based rotation. + Default value: false +

+
pattern +

A formatting layout identifying the various information fields + from the request and response to be logged, or the word + common or combined to select a + standard format. See below for more information on configuring + this attribute.

+
encoding +

Character set used to write the log file. An empty string means + to use the system default character set. Default value: use the + system default character set. +

+
locale +

The locale used to format timestamps in the access log + lines. Any timestamps configured using an + explicit SimpleDateFormat pattern (%{xxx}t) + are formatted in this locale. By default the + default locale of the Java process is used. Switching the + locale after the AccessLogValve is initialized is not supported. + Any timestamps using the common log format + (CLF) are always formatted in the locale + en_US. +

+
requestAttributesEnabled +

Set to true to check for the existence of request + attributes (typically set by the RemoteIpValve and similar) that should + be used to override the values returned by the request for remote + address, remote host, server port and protocol. If the attributes are + not set, or this attribute is set to false then the values + from the request will be used. If not set, the default value of + false will be used.

+
conditionIf +

Turns on conditional logging. If set, requests will be + logged only if ServletRequest.getAttribute() is + not null. For example, if this value is set to + important, then a particular request will only be logged + if ServletRequest.getAttribute("important") != null. + The use of Filters is an easy way to set/unset the attribute + in the ServletRequest on many different requests. +

+
conditionUnless +

Turns on conditional logging. If set, requests will be + logged only if ServletRequest.getAttribute() is + null. For example, if this value is set to + junk, then a particular request will only be logged + if ServletRequest.getAttribute("junk") == null. + The use of Filters is an easy way to set/unset the attribute + in the ServletRequest on many different requests. +

+
condition +

The same as conditionUnless. This attribute is + provided for backwards compatibility. +

+
buffered +

Flag to determine if logging will be buffered. + If set to false, then access logging will be written after each + request. Default value: true +

+
maxLogMessageBufferSize +

Log message buffers are usually recycled and re-used. To prevent + excessive memory usage, if a buffer grows beyond this size it will be + discarded. The default is 256 characters. This should be + set to larger than the typical access log message size.

+
resolveHosts +

This attribute is no longer supported. Use the connector + attribute enableLookups instead.

+

If you have enableLookups on the connector set to + true and want to ignore it, use %a instead of + %h in the value of pattern.

+
+ +

Values for the pattern attribute are made up of literal + text strings, combined with pattern identifiers prefixed by the "%" + character to cause replacement by the corresponding variable value from + the current request and response. The following pattern codes are + supported:

+
    +
  • %a - Remote IP address
  • +
  • %A - Local IP address
  • +
  • %b - Bytes sent, excluding HTTP headers, or '-' if zero
  • +
  • %B - Bytes sent, excluding HTTP headers
  • +
  • %h - Remote host name (or IP address if + enableLookups for the connector is false)
  • +
  • %H - Request protocol
  • +
  • %l - Remote logical username from identd (always returns + '-')
  • +
  • %m - Request method (GET, POST, etc.)
  • +
  • %p - Local port on which this request was received. + See also %{xxx}p below.
  • +
  • %q - Query string (prepended with a '?' if it exists)
  • +
  • %r - First line of the request (method and request URI)
  • +
  • %s - HTTP status code of the response
  • +
  • %S - User session ID
  • +
  • %t - Date and time, in Common Log Format
  • +
  • %u - Remote user that was authenticated (if any), else '-'
  • +
  • %U - Requested URL path
  • +
  • %v - Local server name
  • +
  • %D - Time taken to process the request, in millis
  • +
  • %T - Time taken to process the request, in seconds
  • +
  • %F - Time taken to commit the response, in millis
  • +
  • %I - Current request thread name (can compare later with stacktraces)
  • +
+ +

+ There is also support to write information incoming or outgoing + headers, cookies, session or request attributes and special + timestamp formats. + It is modeled after the + Apache HTTP Server log configuration + syntax. Each of them can be used multiple times with different xxx keys: +

+
    +
  • %{xxx}i write value of incoming header with name xxx
  • +
  • %{xxx}o write value of outgoing header with name xxx
  • +
  • %{xxx}c write value of cookie with name xxx
  • +
  • %{xxx}r write value of ServletRequest attribute with name xxx
  • +
  • %{xxx}s write value of HttpSession attribute with name xxx
  • +
  • %{xxx}p write local (server) port (xxx==local) or + remote (client) port (xxx=remote)
  • +
  • %{xxx}t write timestamp at the end of the request formatted using the + enhanced SimpleDateFormat pattern xxx
  • +
+ +

All formats supported by SimpleDateFormat are allowed in %{xxx}t. + In addition the following extensions have been added:

+
    +
  • sec - number of seconds since the epoch
  • +
  • msec - number of milliseconds since the epoch
  • +
  • msec_frac - millisecond fraction
  • +
+

These formats can not be mixed with SimpleDateFormat formats in the same format + token.

+ +

Furthermore one can define whether to log the timestamp for the request start + time or the response finish time:

+
    +
  • begin or prefix begin: chooses + the request start time
  • +
  • end or prefix end: chooses + the response finish time
  • +
+

By adding multiple %{xxx}t tokens to the pattern, one can + also log both timestamps.

+ +

The shorthand pattern pattern="common" + corresponds to the Common Log Format defined by + '%h %l %u %t "%r" %s %b'.

+ +

The shorthand pattern pattern="combined" + appends the values of the Referer and User-Agent + headers, each in double quotes, to the common pattern.

+ +

When Tomcat is operating behind a reverse proxy, the client information + logged by the Access Log Valve may represent the reverse proxy, the browser + or some combination of the two depending on the configuration of Tomcat and + the reverse proxy. For Tomcat configuration options see + Proxies Support and the + Proxy How-To. For reverse proxies that + use mod_jk, see the generic + proxy documentation. For other reverse proxies, consult their + documentation.

+
+ +
+ + +

Extended Access Log Valve

+ +

Introduction

+ +

The Extended Access Log Valve extends the + Access Log Valve class, and so + uses the same self-contained logging logic. This means it + implements many of the same file handling attributes. The main + difference to the standard AccessLogValve is that + ExtendedAccessLogValve creates log files which + conform to the Working Draft for the + Extended Log File Format + defined by the W3C.

+ +
+ +

Attributes

+ +

The Extended Access Log Valve supports all + configuration attributes of the standard + Access Log Valve. Only the + values used for className and pattern differ.

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.ExtendedAccessLogValve to + use the extended access log valve.

+
pattern +

A formatting layout identifying the various information fields + from the request and response to be logged. + See below for more information on configuring this attribute.

+
+ +

Values for the pattern attribute are made up of + format tokens. Some of the tokens need an additional prefix. Possible + prefixes are c for "client", s for "server", + cs for "client to server", sc for + "server to client" or x for "application specific". + Furthermore some tokens are completed by an additional selector. + See the W3C specification + for more information about the format.

+ +

The following format tokens are supported:

+
    +
  • bytes - Bytes sent, excluding HTTP headers, or '-' if zero
  • +
  • c-dns - Remote host name (or IP address if + enableLookups for the connector is false)
  • +
  • c-ip - Remote IP address
  • +
  • cs-method - Request method (GET, POST, etc.)
  • +
  • cs-uri - Request URI
  • +
  • cs-uri-query - Query string (prepended with a '?' if it exists)
  • +
  • cs-uri-stem - Requested URL path
  • +
  • date - The date in yyyy-mm-dd format for GMT
  • +
  • s-dns - Local host name
  • +
  • s-ip - Local IP address
  • +
  • sc-status - HTTP status code of the response
  • +
  • time - Time the request was served in HH:mm:ss format for GMT
  • +
  • time-taken - Time (in seconds as floating point) taken to serve the request
  • +
  • x-threadname - Current request thread name (can compare later with stacktraces)
  • +
+ +

For any of the x-H(XXX) the following method will be called from the + HttpServletRequest object:

+
    +
  • x-H(authType): getAuthType
  • +
  • x-H(characterEncoding): getCharacterEncoding
  • +
  • x-H(contentLength): getContentLength
  • +
  • x-H(locale): getLocale
  • +
  • x-H(protocol): getProtocol
  • +
  • x-H(remoteUser): getRemoteUser
  • +
  • x-H(requestedSessionId): getRequestedSessionId
  • +
  • x-H(requestedSessionIdFromCookie): + isRequestedSessionIdFromCookie
  • +
  • x-H(requestedSessionIdValid): + isRequestedSessionIdValid
  • +
  • x-H(scheme): getScheme
  • +
  • x-H(secure): isSecure
  • +
+ +

+ There is also support to write information about headers + cookies, context, request or session attributes and request + parameters. +

+
    +
  • cs(XXX) for incoming request headers with name XXX
  • +
  • sc(XXX) for outgoing response headers with name XXX
  • +
  • x-A(XXX) for the servlet context attribute with name XXX
  • +
  • x-C(XXX) for the first cookie with name XXX
  • +
  • x-O(XXX) for a concatenation of all outgoing response headers with name XXX
  • +
  • x-P(XXX) for the URL encoded (using UTF-8) request parameter with name XXX
  • +
  • x-R(XXX) for the request attribute with name XXX
  • +
  • x-S(XXX) for the session attribute with name XXX
  • +
+ +
+ +
+ +

Access Control

+ + +

Remote Address Filter

+ +

Introduction

+ +

The Remote Address Filter allows you to compare the + IP address of the client that submitted this request against one or more + regular expressions, and either allow the request to continue + or refuse to process the request from this client. A Remote Address + Filter can be associated with any Catalina container + (Engine, Host, or + Context), and must accept any request + presented to this container for processing before it will be passed on.

+ +

The syntax for regular expressions is different than that for + 'standard' wildcard matching. Tomcat uses the java.util.regex + package. Please consult the Java documentation for details of the + expressions supported.

+ +

Optionally one can append the server connector port separated with a + semicolon (";") to allow different expressions for each connector.

+ +

The behavior when a request is refused can be changed + to not deny but instead set an invalid authentication + header. This is useful in combination with the context attribute + preemptiveAuthentication="true".

+ +

Note: There is a caveat when using this valve with + IPv6 addresses. Format of the IP address that this valve is processing + depends on the API that was used to obtain it. If the address was obtained + from Java socket using Inet6Address class, its format will be + x:x:x:x:x:x:x:x. That is, the IP address for localhost + will be 0:0:0:0:0:0:0:1 instead of the more widely used + ::1. Consult your access logs for the actual value.

+ +

See also: Remote Host Filter, + Remote IP Valve.

+
+ +

Attributes

+ +

The Remote Address Filter supports the following + configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.RemoteAddrValve.

+
allow +

A regular expression (using java.util.regex) that the + remote client's IP address is compared to. If this attribute + is specified, the remote address MUST match for this request to be + accepted. If this attribute is not specified, all requests will be + accepted UNLESS the remote address matches a deny + pattern.

+
deny +

A regular expression (using java.util.regex) that the + remote client's IP address is compared to. If this attribute + is specified, the remote address MUST NOT match for this request to be + accepted. If this attribute is not specified, request acceptance is + governed solely by the allow attribute.

+
denyStatus +

HTTP response status code that is used when rejecting denied + request. The default value is 403. For example, + it can be set to the value 404.

+
addConnectorPort +

Append the server connector port to the client IP address separated + with a semicolon (";"). If this is set to true, the + expressions configured with allow and + deny is compared against ADDRESS;PORT + where ADDRESS is the client IP address and + PORT is the Tomcat connector port which received the + request. The default value is false.

+
invalidAuthenticationWhenDeny +

When a request should be denied, do not deny but instead + set an invalid authentication header. This only works + if the context has the attribute preemptiveAuthentication="true" + set. An already existing authentication header will not be + overwritten. In effect this will trigger authentication instead of deny + even if the application does not have a security constraint configured.

+

This can be combined with addConnectorPort to trigger authentication + depending on the client and the connector that is used to access an application.

+
+ +
+ +

Example 1

+

To allow access only for the clients connecting from localhost:

+
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
+   allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"/>
+
+ +

Example 2

+

To allow unrestricted access for the clients connecting from localhost + but for all other clients only to port 8443:

+
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
+   addConnectorPort="true"
+   allow="127\.\d+\.\d+\.\d+;\d*|::1;\d*|0:0:0:0:0:0:0:1;\d*|.*;8443"/>
+
+ +

Example 3

+

To allow unrestricted access to port 8009, but trigger basic + authentication if the application is accessed on another port:

+
<Context>
+  ...
+  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
+         addConnectorPort="true"
+         invalidAuthenticationWhenDeny="true"
+         allow=".*;8009"/>
+  <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" />
+  ...
+</Context>
+
+ +
+ + +

Remote Host Filter

+ +

Introduction

+ +

The Remote Host Filter allows you to compare the + hostname of the client that submitted this request against one or more + regular expressions, and either allow the request to continue + or refuse to process the request from this client. A Remote Host + Filter can be associated with any Catalina container + (Engine, Host, or + Context), and must accept any request + presented to this container for processing before it will be passed on.

+ +

The syntax for regular expressions is different than that for + 'standard' wildcard matching. Tomcat uses the java.util.regex + package. Please consult the Java documentation for details of the + expressions supported.

+ +

Optionally one can append the server connector port separated with a + semicolon (";") to allow different expressions for each connector.

+ +

The behavior when a request is refused can be changed + to not deny but instead set an invalid authentication + header. This is useful in combination with the context attribute + preemptiveAuthentication="true".

+ +

Note: This filter processes the value returned by + method ServletRequest.getRemoteHost(). To allow the method + to return proper host names, you have to enable "DNS lookups" feature on + a Connector.

+ +

See also: Remote Address Filter, + HTTP Connector configuration.

+
+ +

Attributes

+ +

The Remote Host Filter supports the following + configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.RemoteHostValve.

+
allow +

A regular expression (using java.util.regex) that the + remote client's hostname is compared to. If this attribute + is specified, the remote hostname MUST match for this request to be + accepted. If this attribute is not specified, all requests will be + accepted UNLESS the remote hostname matches a deny + pattern.

+
deny +

A regular expression (using java.util.regex) that the + remote client's hostname is compared to. If this attribute + is specified, the remote hostname MUST NOT match for this request to be + accepted. If this attribute is not specified, request acceptance is + governed solely by the allow attribute.

+
denyStatus +

HTTP response status code that is used when rejecting denied + request. The default value is 403. For example, + it can be set to the value 404.

+
addConnectorPort +

Append the server connector port to the client hostname separated + with a semicolon (";"). If this is set to true, the + expressions configured with allow and + deny is compared against HOSTNAME;PORT + where HOSTNAME is the client hostname and + PORT is the Tomcat connector port which received the + request. The default value is false.

+
invalidAuthenticationWhenDeny +

When a request should be denied, do not deny but instead + set an invalid authentication header. This only works + if the context has the attribute preemptiveAuthentication="true" + set. An already existing authentication header will not be + overwritten. In effect this will trigger authentication instead of deny + even if the application does not have a security constraint configured.

+

This can be combined with addConnectorPort to trigger authentication + depending on the client and the connector that is used to access an application.

+
+ +
+ +
+ + +

Proxies Support

+ +

Remote IP Valve

+ +

Introduction

+ +

Tomcat port of + mod_remoteip, + this valve replaces the apparent client remote IP address and hostname for + the request with the IP address list presented by a proxy or a load balancer + via a request headers (e.g. "X-Forwarded-For").

+ +

Another feature of this valve is to replace the apparent scheme + (http/https), server port and request.secure with the scheme presented + by a proxy or a load balancer via a request header + (e.g. "X-Forwarded-Proto").

+ +

This Valve may be used at the Engine, Host or + Context level as required. Normally, this Valve would be used + at the Engine level.

+ +

If used in conjunction with Remote Address/Host valves then this valve + should be defined first to ensure that the correct client IP address is + presented to the Remote Address/Host valves.

+ +

Note: By default this valve has no effect on the + values that are written into access log. The original values are restored + when request processing leaves the valve and that always happens earlier + than access logging. To pass the remote address, remote host, server port + and protocol values set by this valve to the access log, + they are put into request attributes. Publishing these values here + is enabled by default, but AccessLogValve should be explicitly + configured to use them. See documentation for + requestAttributesEnabled attribute of + AccessLogValve.

+ +

The names of request attributes that are set by this valve + and can be used by access logging are the following:

+ +
    +
  • org.apache.catalina.AccessLog.RemoteAddr
  • +
  • org.apache.catalina.AccessLog.RemoteHost
  • +
  • org.apache.catalina.AccessLog.Protocol
  • +
  • org.apache.catalina.AccessLog.ServerPort
  • +
  • org.apache.tomcat.remoteAddr
  • +
+ +
+ +

Attributes

+ +

The Remote IP Valve supports the + following configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.RemoteIpValve.

+
remoteIpHeader +

Name of the HTTP Header read by this valve that holds the list of + traversed IP addresses starting from the requesting client. If not + specified, the default of x-forwarded-for is used.

+
internalProxies +

Regular expression (using java.util.regex) that a + proxy's IP address must match to be considered an internal proxy. + Internal proxies that appear in the remoteIpHeader will + be trusted and will not appear in the proxiesHeader + value. If not specified the default value of + 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1 + will be used.

+
proxiesHeader +

Name of the HTTP header created by this valve to hold the list of + proxies that have been processed in the incoming + remoteIpHeader. If not specified, the default of + x-forwarded-by is used.

+
requestAttributesEnabled +

Set to true to set the request attributes used by + AccessLog implementations to override the values returned by the + request for remote address, remote host, server port and protocol. + Request attributes are also used to enable the forwarded remote address + to be displayed on the status page of the Manager web application. + If not set, the default value of true will be used.

+
trustedProxies +

Regular expression (using java.util.regex) that a + proxy's IP address must match to be considered an trusted proxy. + Trusted proxies that appear in the remoteIpHeader will + be trusted and will appear in the proxiesHeader value. + If not specified, no proxies will be trusted.

+
protocolHeader +

Name of the HTTP Header read by this valve that holds the protocol + used by the client to connect to the proxy. If not specified, the + default of null is used.

+
portHeader +

Name of the HTTP Header read by this valve that holds the port + used by the client to connect to the proxy. If not specified, the + default of null is used.

+
protocolHeaderHttpsValue +

Value of the protocolHeader to indicate that it is + an HTTPS request. If not specified, the default of https is + used.

+
httpServerPort +

Value returned by ServletRequest.getServerPort() + when the protocolHeader indicates http + protocol and no portHeader is present. If not + specified, the default of 80 is used.

+
httpsServerPort +

Value returned by ServletRequest.getServerPort() + when the protocolHeader indicates https + protocol and no portHeader is present. If not + specified, the default of 443 is used.

+
changeLocalPort +

If true, the value returned by + ServletRequest.getLocalPort() and + ServletRequest.getServerPort() is modified by the this + valve. If not specified, the default of false is used.

+
+ +
+ +
+ + +

SSL Valve

+ +

Introduction

+ +

When using mod_proxy_http, the client SSL information is not included in + the protocol (unlike mod_jk and mod_proxy_ajp). To make the client SSL + information available to Tomcat, some additional configuration is required. + In httpd, mod_headers is used to add the SSL information as HTTP headers. In + Tomcat, this valve is used to read the information from the HTTP headers and + insert it into the request.

+ +

Note: Ensure that the headers are always set by httpd for all requests to + prevent a client spoofing SSL information by sending fake headers.

+ +

To configure httpd to set the necessary headers, add the following:

+
<IfModule ssl_module>
+  RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
+  RequestHeader set SSL_CIPHER "%{SSL_CIPHER}s"
+  RequestHeader set SSL_SESSION_ID "%{SSL_SESSION_ID}s"
+  RequestHeader set SSL_CIPHER_USEKEYSIZE "%{SSL_CIPHER_USEKEYSIZE}s"
+</IfModule>
+ +
+ +

Attributes

+ +

The SSL Valve supports the following configuration + attribute:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.SSLValve. +

+
sslClientCertHeader +

Allows setting a custom name for the ssl_client_cert header. + If not specified, the default of ssl_client_cert is + used.

+
sslCipherHeader +

Allows setting a custom name for the ssl_cipher header. + If not specified, the default of ssl_cipher is + used.

+
sslSessionIdHeader +

Allows setting a custom name for the ssl_session_id header. + If not specified, the default of ssl_session_id is + used.

+
sslCipherUserKeySizeHeader +

Allows setting a custom name for the ssl_cipher_usekeysize header. + If not specified, the default of ssl_cipher_usekeysize is + used.

+
+ +
+ +
+ + +

Single Sign On Valve

+ +

Introduction

+ +

The Single Sign On Valve is utilized when you wish to give users + the ability to sign on to any one of the web applications associated with + your virtual host, and then have their identity recognized by all other + web applications on the same virtual host.

+ +

See the Single Sign On special + feature on the Host element for more information.

+ +
+ + +

Attributes

+ +

The Single Sign On Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.authenticator.SingleSignOn.

+
requireReauthentication +

Default false. Flag to determine whether each request needs to be + reauthenticated to the security Realm. If "true", this + Valve uses cached security credentials (username and password) to + reauthenticate to the Realm each request associated + with an SSO session. If "false", the Valve can itself authenticate + requests based on the presence of a valid SSO cookie, without + rechecking with the Realm.

+
cookieDomain +

Sets the host domain to be used for sso cookies.

+
+ +
+ + +

Authentication

+ +

The valves in this section implement +org.apache.catalina.Authenticator interface.

+ +

Basic Authenticator Valve

+ +

Introduction

+ +

The Basic Authenticator Valve is automatically added to + any Context that is configured to use BASIC + authentication.

+ +

If any non-default settings are required, the valve may be configured + within Context element with the required + values.

+ +
+ +

Attributes

+ +

The Basic Authenticator Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
alwaysUseSession +

Should a session always be used once a user is authenticated? This + may offer some performance benefits since the session can then be used + to cache the authenticated Principal, hence removing the need to + authenticate the user via the Realm on every request. This may be of + help for combinations such as BASIC authentication used with the + JNDIRealm or DataSourceRealms. However there will also be the + performance cost of creating and GC'ing the session. If not set, the + default value of false will be used.

+
cache +

Should we cache authenticated Principals if the request is part of an + HTTP session? If not specified, the default value of true + will be used.

+
changeSessionIdOnAuthentication +

Controls if the session ID is changed if a session exists at the + point where users are authenticated. This is to prevent session fixation + attacks. If not set, the default value of true will be + used.

+
charset +

Controls if the WWW-Authenticate HTTP header includes a + charset authentication parameter as per RFC 7617. The only + permitted options are null, the empty string and + UTF-8. If UTF-8 is specified then the + charset authentication parameter will be sent with that + value and the provided user name and optional password will be converted + from bytes to characters using UTF-8. Otherwise, no charset + authentication parameter will be sent and the provided user name and + optional password will be converted from bytes to characters using + ISO-8859-1. The default value is null

+
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.authenticator.BasicAuthenticator.

+
disableProxyCaching +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers but will also cause secured pages to be + cached by proxies which will almost certainly be a security issue. + securePagesWithPragma offers an alternative, secure, + workaround for browser caching issues. If not set, the default value of + true will be used.

+
securePagesWithPragma +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers by using + Cache-Control: private rather than the default of + Pragma: No-cache and Cache-control: No-cache. + If not set, the default value of false will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the platform + default provider and the default algorithm will be used. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate SSO session + IDs. If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate SSO + session IDs. If an invalid algorithm and/or provider is specified, the + platform default provider and the default algorithm will be used. If not + specified, the platform default provider will be used.

+
+ +
+ +
+ + +

Digest Authenticator Valve

+ +

Introduction

+ +

The Digest Authenticator Valve is automatically added to + any Context that is configured to use DIGEST + authentication.

+ +

If any non-default settings are required, the valve may be configured + within Context element with the required + values.

+ +
+ +

Attributes

+ +

The Digest Authenticator Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
alwaysUseSession +

Should a session always be used once a user is authenticated? This + may offer some performance benefits since the session can then be used + to cache the authenticated Principal, hence removing the need to + authenticate the user via the Realm on every request. This may be of + help for combinations such as BASIC authentication used with the + JNDIRealm or DataSourceRealms. However there will also be the + performance cost of creating and GC'ing the session. If not set, the + default value of false will be used.

+
cache +

Should we cache authenticated Principals if the request is part of an + HTTP session? If not specified, the default value of false + will be used.

+
changeSessionIdOnAuthentication +

Controls if the session ID is changed if a session exists at the + point where users are authenticated. This is to prevent session fixation + attacks. If not set, the default value of true will be + used.

+
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.authenticator.DigestAuthenticator.

+
disableProxyCaching +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers but will also cause secured pages to be + cached by proxies which will almost certainly be a security issue. + securePagesWithPragma offers an alternative, secure, + workaround for browser caching issues. If not set, the default value of + true will be used.

+
key +

The secret key used by digest authentication. If not set, a secure + random value is generated. This should normally only be set when it is + necessary to keep key values constant either across server restarts + and/or across a cluster.

+
nonceCacheSize +

To protect against replay attacks, the DIGEST authenticator tracks + server nonce and nonce count values. This attribute controls the size + of that cache. If not specified, the default value of 1000 is used.

+
nonceCountWindowSize +

Client requests may be processed out of order which in turn means + that the nonce count values may be processed out of order. To prevent + authentication failures when nonce counts are presented out of order + the authenticator tracks a window of nonce count values. This attribute + controls how big that window is. If not specified, the default value of + 100 is used.

+
nonceValidity +

The time, in milliseconds, that a server generated nonce will be + considered valid for use in authentication. If not specified, the + default value of 300000 (5 minutes) will be used.

+
opaque +

The opaque server string used by digest authentication. If not set, a + random value is generated. This should normally only be set when it is + necessary to keep opaque values constant either across server restarts + and/or across a cluster.

+
securePagesWithPragma +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers by using + Cache-Control: private rather than the default of + Pragma: No-cache and Cache-control: No-cache. + If not set, the default value of false will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the platform + default provider and the default algorithm will be used. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate SSO session + IDs. If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate SSO + session IDs. If an invalid algorithm and/or provider is specified, the + platform default provider and the default algorithm will be used. If not + specified, the platform default provider will be used.

+
validateUri +

Should the URI be validated as required by RFC2617? If not specified, + the default value of true will be used. This should + normally only be set when Tomcat is located behind a reverse proxy and + the proxy is modifying the URI passed to Tomcat such that DIGEST + authentication always fails.

+
+ +
+ +
+ + +

Form Authenticator Valve

+ +

Introduction

+ +

The Form Authenticator Valve is automatically added to + any Context that is configured to use FORM + authentication.

+ +

If any non-default settings are required, the valve may be configured + within Context element with the required + values.

+ +
+ +

Attributes

+ +

The Form Authenticator Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
changeSessionIdOnAuthentication +

Controls if the session ID is changed if a session exists at the + point where users are authenticated. This is to prevent session fixation + attacks. If not set, the default value of true will be + used.

+
characterEncoding +

Character encoding to use to read the username and password parameters + from the request. If not set, the encoding of the request body will be + used.

+
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.authenticator.FormAuthenticator.

+
disableProxyCaching +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers but will also cause secured pages to be + cached by proxies which will almost certainly be a security issue. + securePagesWithPragma offers an alternative, secure, + workaround for browser caching issues. If not set, the default value of + true will be used.

+
landingPage +

Controls the behavior of the FORM authentication process if the + process is misused, for example by directly requesting the login page + or delaying logging in for so long that the session expires. If this + attribute is set, rather than returning an error response code, Tomcat + will redirect the user to the specified landing page if the login form + is submitted with valid credentials. For the login to be processed, the + landing page must be a protected resource (i.e. one that requires + authentication). If the landing page does not require authentication + then the user will not be logged in and will be prompted for their + credentials again when they access a protected page.

+
securePagesWithPragma +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers by using + Cache-Control: private rather than the default of + Pragma: No-cache and Cache-control: No-cache. + If not set, the default value of false will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the platform + default provider and the default algorithm will be used. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate SSO session + IDs. If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate SSO + session IDs. If an invalid algorithm and/or provider is specified, the + platform default provider and the default algorithm will be used. If not + specified, the platform default provider will be used.

+
+ +
+ +
+ + +

SSL Authenticator Valve

+ +

Introduction

+ +

The SSL Authenticator Valve is automatically added to + any Context that is configured to use SSL + authentication.

+ +

If any non-default settings are required, the valve may be configured + within Context element with the required + values.

+ +
+ +

Attributes

+ +

The SSL Authenticator Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
cache +

Should we cache authenticated Principals if the request is part of an + HTTP session? If not specified, the default value of true + will be used.

+
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.authenticator.SSLAuthenticator.

+
changeSessionIdOnAuthentication +

Controls if the session ID is changed if a session exists at the + point where users are authenticated. This is to prevent session fixation + attacks. If not set, the default value of true will be + used.

+
disableProxyCaching +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers but will also cause secured pages to be + cached by proxies which will almost certainly be a security issue. + securePagesWithPragma offers an alternative, secure, + workaround for browser caching issues. If not set, the default value of + true will be used.

+
securePagesWithPragma +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers by using + Cache-Control: private rather than the default of + Pragma: No-cache and Cache-control: No-cache. + If not set, the default value of false will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the platform + default provider and the default algorithm will be used. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate SSO session + IDs. If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate SSO + session IDs. If an invalid algorithm and/or provider is specified, the + platform default provider and the default algorithm will be used. If not + specified, the platform default provider will be used.

+
+ +
+ +
+ + +

SPNEGO Valve

+ +

Introduction

+ +

The SPNEGO Authenticator Valve is automatically added to + any Context that is configured to use SPNEGO + authentication.

+ +

If any non-default settings are required, the valve may be configured + within Context element with the required + values.

+ +
+ +

Attributes

+ +

The SPNEGO Authenticator Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
applyJava8u40Fix +

A fix introduced in Java 8 update 40 ( + JDK-8048194) + onwards broke SPNEGO authentication for IE with Tomcat running on + Windows 2008 R2 servers. This option enables a work-around that allows + SPNEGO authentication to continue working. The work-around should not + impact other configurations so it is enabled by default. If necessary, + the workaround can be disabled by setting this attribute to + false.

+
alwaysUseSession +

Should a session always be used once a user is authenticated? This + may offer some performance benefits since the session can then be used + to cache the authenticated Principal, hence removing the need to + authenticate the user on every request. This will also help with clients + that assume that the server will cache the authenticated user. However + there will also be the performance cost of creating and GC'ing the + session. For an alternative solution see + noKeepAliveUserAgents. If not set, the default value of + false will be used.

+
cache +

Should we cache authenticated Principals if the request is part of an + HTTP session? If not specified, the default value of true + will be used.

+
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.authenticator.SpnegoAuthenticator. +

+
changeSessionIdOnAuthentication +

Controls if the session ID is changed if a session exists at the + point where users are authenticated. This is to prevent session fixation + attacks. If not set, the default value of true will be + used.

+
disableProxyCaching +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers but will also cause secured pages to be + cached by proxies which will almost certainly be a security issue. + securePagesWithPragma offers an alternative, secure, + workaround for browser caching issues. If not set, the default value of + true will be used.

+
loginConfigName +

The name of the JAAS login configuration to be used to login as the + service. If not specified, the default of + com.sun.security.jgss.krb5.accept is used.

+
noKeepAliveUserAgents +

Some clients (not most browsers) expect the server to cache the + authenticated user information for a connection and do not resend the + credentials with every request. Tomcat will not do this unless an HTTP + session is available. A session will be available if either the + application creates one or if alwaysUseSession is enabled + for this Authenticator.

+

As an alternative to creating a session, this attribute may be used + to define the user agents for which HTTP keep-alive is disabled. This + means that a connection will only used for a single request and hence + there is no ability to cache authenticated user information per + connection. There will be a performance cost in disabling HTTP + keep-alive.

+

The attribute should be a regular expression that matches the entire + user-agent string, e.g. .*Chrome.*. If not specified, no + regular expression will be defined and no user agents will have HTTP + keep-alive disabled.

+
securePagesWithPragma +

Controls the caching of pages that are protected by security + constraints. Setting this to false may help work around + caching issues in some browsers by using + Cache-Control: private rather than the default of + Pragma: No-cache and Cache-control: No-cache. + If not set, the default value of false will be used.

+
secureRandomAlgorithm +

Name of the algorithm to use to create the + java.security.SecureRandom instances that generate session + IDs. If an invalid algorithm and/or provider is specified, the platform + default provider and the default algorithm will be used. If not + specified, the default algorithm of SHA1PRNG will be used. If the + default algorithm is not supported, the platform default will be used. + To specify that the platform default should be used, do not set the + secureRandomProvider attribute and set this attribute to the empty + string.

+
secureRandomClass +

Name of the Java class that extends + java.security.SecureRandom to use to generate SSO session + IDs. If not specified, the default value is + java.security.SecureRandom.

+
secureRandomProvider +

Name of the provider to use to create the + java.security.SecureRandom instances that generate SSO + session IDs. If an invalid algorithm and/or provider is specified, the + platform default provider and the default algorithm will be used. If not + specified, the platform default provider will be used.

+
storeDelegatedCredential +

Controls if the user' delegated credential will be stored in + the user Principal. If available, the delegated credential will be + available to applications (e.g. for onward authentication to external + services) via the org.apache.catalina.realm.GSS_CREDENTIAL + request attribute. If not set, the default value of true + will be used.

+
+ +
+ +
+ + +

Error Report Valve

+ +

Introduction

+ +

The Error Report Valve is a simple error handler + for HTTP status codes that will generate and return HTML error pages.

+ +

NOTE: Disabling both showServerInfo and showReport will + only return the HTTP status code and remove all CSS.

+ +
+ +

Attributes

+ +

The Error Report Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.ErrorReportValve to use the + default error report valve.

+
showReport +

Flag to determine if the error report is presented when an error + occurs. If set to false, then the error report is not in + the HTML response. + Default value: true +

+
showServerInfo +

Flag to determine if server information is presented when an error + occurs. If set to false, then the server version is not + returned in the HTML response. + Default value: true +

+
+ +
+ +

Crawler Session Manager Valve

+ +

Introduction

+ +

Web crawlers can trigger the creation of many thousands of sessions as + they crawl a site which may result in significant memory consumption. This + Valve ensures that crawlers are associated with a single session - just like + normal users - regardless of whether or not they provide a session token + with their requests.

+ +

This Valve may be used at the Engine, Host or + Context level as required. Normally, this Valve would be used + at the Engine level.

+ +

If used in conjunction with Remote IP valve then the Remote IP valve + should be defined before this valve to ensure that the correct client IP + address is presented to this valve.

+ +
+ +

Attributes

+ +

The Crawler Session Manager Valve supports the + following configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.CrawlerSessionManagerValve. +

+
contextAware +

Flag to use the context name together with the client IP to + identify the session to re-use. Can be combined with hostAware. + Default value: true +

+
crawlerIps +

Regular expression (using java.util.regex) that client + IP is matched against to determine if a request is from a web crawler. + By default such regular expression is not set.

+
crawlerUserAgents +

Regular expression (using java.util.regex) that the user + agent HTTP request header is matched against to determine if a request + is from a web crawler. If not set, the default of + .*[bB]ot.*|.*Yahoo! Slurp.*|.*Feedfetcher-Google.* is used.

+
hostAware +

Flag to use the configured host together with the client IP to + identify the session to re-use. Can be combined with contextAware. + Default value: true +

+
sessionInactiveInterval +

The minimum time in seconds that the Crawler Session Manager Valve + should keep the mapping of client IP to session ID in memory without any + activity from the client. The client IP / session cache will be + periodically purged of mappings that have been inactive for longer than + this interval. If not specified the default value of 60 + will be used.

+
+ +
+ +

Stuck Thread Detection Valve

+ +

Introduction

+ +

This valve allows to detect requests that take a long time to process, + which might indicate that the thread that is processing it is stuck. + Additionally it can optionally interrupt such threads to try and unblock + them.

+

When such a request is detected, the current stack trace of its thread is + written to Tomcat log with a WARN level.

+

The IDs and names of the stuck threads are available through JMX in the + stuckThreadIds and stuckThreadNames attributes. + The IDs can be used with the standard Threading JVM MBean + (java.lang:type=Threading) to retrieve other information + about each stuck thread.

+ +
+ +

Attributes

+ +

The Stuck Thread Detection Valve supports the + following configuration attributes:

+ +
+ Attribute + + Description +
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.StuckThreadDetectionValve. +

+
threshold +

Minimum duration in seconds after which a thread is considered stuck. + Default is 600 seconds. If set to 0, the detection is disabled.

+

Note: since the detection (and optional interruption) is done in the + background thread of the Container (Engine, Host or Context) declaring + this Valve, the threshold should be higher than the + backgroundProcessorDelay of this Container.

+
interruptThreadThreshold +

Minimum duration in seconds after which a stuck thread should be + interrupted to attempt to "free" it.

+

Note that there's no guarantee that the thread will get unstuck. + This usually works well for threads stuck on I/O or locks, but is + probably useless in case of infinite loops.

+

Default is -1 which disables the feature. To enable it, the value + must be greater or equal to threshold.

+
+ +
+ +

Semaphore Valve

+ +

Introduction

+ +

The Semaphore Valve is able to limit the number of + concurrent request processing threads.

+

org.apache.catalina.valves.SemaphoreValve provides + methods which may be overridden by a subclass to customize behavior:

+
    +
  • controlConcurrency may be overridden to add + conditions;
  • +
  • permitDenied may be overridden to add error handling + when a permit isn't granted.
  • +
+ +
+ +

Attributes

+ +

The Semaphore Valve supports the following + configuration attributes:

+ +
+ Attribute + + Description +
block +

Flag to determine if a thread is blocked until a permit is available. + The default value is true.

+
className +

Java class name of the implementation to use. This MUST be set to + org.apache.catalina.valves.SemaphoreValve.

+
concurrency +

Concurrency level of the semaphore. The default value is + 10.

+
fairness +

Fairness of the semaphore. The default value is + false.

+
interruptible +

Flag to determine if a thread may be interrupted until a permit is + available. The default value is false.

+
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/connectors.html b/test.dockerapp/tomcat/webapps/docs/connectors.html new file mode 100644 index 0000000..3c6b1b3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/connectors.html @@ -0,0 +1,86 @@ + +Apache Tomcat 8 (8.0.53) - Connectors How To

Connectors How To

Table of Contents

Introduction

+ +

Choosing a connector to use with Tomcat can be difficult. This page will +list the connectors which are supported with this Tomcat release, and will +hopefully help you make the right choice according to your needs.

+ +

HTTP

+ +

The HTTP connector is setup by default with Tomcat, and is ready to use. This +connector features the lowest latency and best overall performance.

+ +

For clustering, a HTTP load balancer with support for web sessions stickiness +must be installed to direct the traffic to the Tomcat servers. Tomcat supports mod_proxy +(on Apache HTTP Server 2.x, and included by default in Apache HTTP Server 2.2) as the load balancer. +It should be noted that the performance of HTTP proxying is usually lower than the +performance of AJP, so AJP clustering is often preferable.

+ +

AJP

+ +

When using a single server, the performance when using a native webserver in +front of the Tomcat instance is most of the time significantly worse than a +standalone Tomcat with its default HTTP connector, even if a large part of the web +application is made of static files. If integration with the native webserver is +needed for any reason, an AJP connector will provide faster performance than +proxied HTTP. AJP clustering is the most efficient from the Tomcat perspective. +It is otherwise functionally equivalent to HTTP clustering.

+ +

The native connectors supported with this Tomcat release are:

+
    +
  • JK 1.2.x with any of the supported servers
  • +
  • mod_proxy on Apache HTTP Server 2.x (included by default in Apache HTTP Server 2.2), +with AJP enabled
  • +
+ +

Other native connectors supporting AJP may work, but are no longer supported.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/default-servlet.html b/test.dockerapp/tomcat/webapps/docs/default-servlet.html new file mode 100644 index 0000000..78df378 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/default-servlet.html @@ -0,0 +1,292 @@ + +Apache Tomcat 8 (8.0.53) - Default Servlet Reference

Default Servlet Reference

Table of Contents

What is the DefaultServlet

+

+The default servlet is the servlet which serves static resources as well +as serves the directory listings (if directory listings are enabled). +

+

Where is it declared?

+

+It is declared globally in $CATALINA_BASE/conf/web.xml. +By default here is it's declaration: +

+
    <servlet>
+        <servlet-name>default</servlet-name>
+        <servlet-class>
+          org.apache.catalina.servlets.DefaultServlet
+        </servlet-class>
+        <init-param>
+            <param-name>debug</param-name>
+            <param-value>0</param-value>
+        </init-param>
+        <init-param>
+            <param-name>listings</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+...
+
+    <servlet-mapping>
+        <servlet-name>default</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+ +So by default, the default servlet is loaded at webapp startup and +directory listings are disabled and debugging is turned off. +

What can I change?

+

+ The DefaultServlet allows the following initParamters: +

+ +
+ Property + + Description +
debug + Debugging level. It is not very useful unless you are a tomcat + developer. As + of this writing, useful values are 0, 1, 11, 1000. [0] +
listings + If no welcome file is present, can a directory listing be + shown? + value may be true or false [false] +
+ Welcome files are part of the servlet api. +
+ WARNING: Listings of directories containing many entries are + expensive. Multiple requests for large directory listings can consume + significant proportions of server resources. +
gzip + If a gzipped version of a file exists (a file with .gz + appended to the file name located alongside the original file), Tomcat + will serve the gzipped file if the user agent supports gzip and this + option is enabled. [false] +
+ The file with the .gz extension will be accessible if + requested directly so if the original resource is protected with a + security constraint, the gzipped version must be similarly protected. +
readmeFile + If a directory listing is presented, a readme file may also + be presented with the listing. This file is inserted as is + so it may contain HTML. +
globalXsltFile + If you wish to customize your directory listing, you + can use an XSL transformation. This value is a relative file name (to + either $CATALINA_BASE/conf/ or $CATALINA_HOME/conf/) which will be used + for all directory listings. This can be overridden per context and/or + per directory. See contextXsltFile and + localXsltFile below. The format of the xml is shown + below. +
contextXsltFile + You may also customize your directory listing by context by + configuring contextXsltFile. This must be a context + relative path (e.g.: /path/to/context.xslt) to a file with + a .xsl or .xslt extension. This overrides + globalXsltFile. If this value is present but a file does + not exist, then globalXsltFile will be used. If + globalXsltFile does not exist, then the default + directory listing will be shown. +
localXsltFile + You may also customize your directory listing by directory by + configuring localXsltFile. This must be a file in the + directory where the listing will take place to with a + .xsl or .xslt extension. This overrides + globalXsltFile and contextXsltFile. If this + value is present but a file does not exist, then + contextXsltFile will be used. If + contextXsltFile does not exist, then + globalXsltFile will be used. If + globalXsltFile does not exist, then the default + directory listing will be shown. +
input + Input buffer size (in bytes) when reading + resources to be served. [2048] +
output + Output buffer size (in bytes) when writing + resources to be served. [2048] +
readonly + Is this context "read only", so HTTP commands like PUT and + DELETE are rejected? [true] +
fileEncoding + File encoding to be used when reading static resources. + [platform default] +
sendfileSize + If the connector used supports sendfile, this represents the minimal + file size in KB for which sendfile will be used. Use a negative value + to always disable sendfile. [48] +
useAcceptRanges + If true, the Accept-Ranges header will be set when appropriate for the + response. [true] +
showServerInfo + Should server information be presented in the response sent to clients + when directory listing is enabled. [true] +
+

How do I customize directory listings?

+

You can override DefaultServlet with you own implementation and use that +in your web.xml declaration. If you +can understand what was just said, we will assume you can read the code +to DefaultServlet servlet and make the appropriate adjustments. (If not, +then that method isn't for you) +

+

+You can use either localXsltFile or +globalXsltFile and DefaultServlet will create +an xml document and run it through an xsl transformation based +on the values provided in localXsltFile and +globalXsltFile. localXsltFile is first +checked, followed by globalXsltFile, then default +behaviors takes place. +

+ +

+Format: +

+
    <listing>
+     <entries>
+      <entry type='file|dir' urlPath='aPath' size='###' date='gmt date'>
+        fileName1
+      </entry>
+      <entry type='file|dir' urlPath='aPath' size='###' date='gmt date'>
+        fileName2
+      </entry>
+      ...
+     </entries>
+     <readme></readme>
+    </listing>
+
    +
  • size will be missing if type='dir'
  • +
  • Readme is a CDATA entry
  • +
+ +

+ The following is a sample xsl file which mimics the default tomcat behavior: +

+
<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  version="3.0">
+
+  <xsl:output method="html" html-version="5.0"
+    encoding="UTF-8" indent="no"
+    doctype-system="about:legacy-compat"/>
+
+  <xsl:template match="listing">
+   <html>
+    <head>
+      <title>
+        Sample Directory Listing For
+        <xsl:value-of select="@directory"/>
+      </title>
+      <style>
+        h1 {color : white;background-color : #0086b2;}
+        h3 {color : white;background-color : #0086b2;}
+        body {font-family : sans-serif,Arial,Tahoma;
+             color : black;background-color : white;}
+        b {color : white;background-color : #0086b2;}
+        a {color : black;} HR{color : #0086b2;}
+        table td { padding: 5px; }
+      </style>
+    </head>
+    <body>
+      <h1>Sample Directory Listing For
+            <xsl:value-of select="@directory"/>
+      </h1>
+      <hr style="height: 1px;" />
+      <table style="width: 100%;">
+        <tr>
+          <th style="text-align: left;">Filename</th>
+          <th style="text-align: center;">Size</th>
+          <th style="text-align: right;">Last Modified</th>
+        </tr>
+        <xsl:apply-templates select="entries"/>
+        </table>
+      <xsl:apply-templates select="readme"/>
+      <hr style="height: 1px;" />
+      <h3>Apache Tomcat/<version-major-minor/></h3>
+    </body>
+   </html>
+  </xsl:template>
+
+
+  <xsl:template match="entries">
+    <xsl:apply-templates select="entry"/>
+  </xsl:template>
+
+  <xsl:template match="readme">
+    <hr style="height: 1px;" />
+    <pre><xsl:apply-templates/></pre>
+  </xsl:template>
+
+  <xsl:template match="entry">
+    <tr>
+      <td style="text-align: left;">
+        <xsl:variable name="urlPath" select="@urlPath"/>
+        <a href="{$urlPath}">
+          <pre><xsl:apply-templates/></pre>
+        </a>
+      </td>
+      <td style="text-align: right;">
+        <pre><xsl:value-of select="@size"/></pre>
+      </td>
+      <td style="text-align: right;">
+        <pre><xsl:value-of select="@date"/></pre>
+      </td>
+    </tr>
+  </xsl:template>
+
+</xsl:stylesheet>
+ +

How do I secure directory listings?

+Use web.xml in each individual webapp. See the security section of the +Servlet specification. + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/deployer-howto.html b/test.dockerapp/tomcat/webapps/docs/deployer-howto.html new file mode 100644 index 0000000..ca00d6a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/deployer-howto.html @@ -0,0 +1,351 @@ + +Apache Tomcat 8 (8.0.53) - Tomcat Web Application Deployment

Tomcat Web Application Deployment

Table of Contents

Introduction

+

+ Deployment is the term used for the process of installing a web + application (either a 3rd party WAR or your own custom web application) + into the Tomcat server. +

+

+ Web application deployment may be accomplished in a number of ways + within the Tomcat server. +

+
    +
  • Statically; the web application is setup before Tomcat is started
  • +
  • + Dynamically; by directly manipulating already deployed web + applications (relying on auto-deployment + feature) or remotely by using the Tomcat Manager web + application +
  • +
+

+ The Tomcat Manager is a web + application that can be used interactively (via HTML GUI) or + programmatically (via URL-based API) to deploy and manage web + applications. +

+

+ There are a number of ways to perform deployment that rely on + the Manager web application. Apache Tomcat provides tasks + for Apache Ant build tool. + Apache Tomcat Maven Plugin + project provides integration with Apache Maven. + There is also a tool called the Client Deployer, which can be + used from a command line and provides additional functionality + such as compiling and validating web applications as well as + packaging web application into web application resource (WAR) + files. +

+

Installation

+

+ There is no installation required for static deployment of web + applications as this is provided out of the box by Tomcat. Nor is any + installation required for deployment functions with the Tomcat Manager, + although some configuration is required as detailed in the + Tomcat Manager manual. + An installation is however required if you wish + to use the Tomcat Client Deployer (TCD). +

+

+ The TCD is not packaged with the Tomcat core + distribution, and must therefore be downloaded separately from + the Downloads area. The download is usually labelled + apache-tomcat-8.0.x-deployer. +

+

+ TCD has prerequisites of Apache Ant 1.6.2+ and a Java installation. + Your environment should define an ANT_HOME environment value pointing to + the root of your Ant installation, and a JAVA_HOME value pointing to + your Java installation. Additionally, you should ensure Ant's ant + command, and the Java javac compiler command run from the command shell + that your operating system provides. +

+
    +
  1. Download the TCD distribution
  2. +
  3. + The TCD package need not be extracted into any existing Tomcat + installation, it can be extracted to any location. +
  4. +
  5. Read Using the + Tomcat Client Deployer
  6. +
+

A word on Contexts

+

+ In talking about deployment of web applications, the concept of a + Context is required to be understood. A Context is what Tomcat + calls a web application. +

+

+ In order to configure a Context within Tomcat a Context Descriptor + is required. A Context Descriptor is simply an XML file that contains + Tomcat related configuration for a Context, e.g naming resources or + session manager configuration. In earlier versions of + Tomcat the content of a Context Descriptor configuration was often stored within + Tomcat's primary configuration file server.xml but this is now + discouraged (although it currently still works). +

+

+ Context Descriptors not only help Tomcat to know how to configure + Contexts but other tools such as the Tomcat Manager and TCD often use + these Context Descriptors to perform their roles properly. +

+

+ The locations for Context Descriptors are: +

+
    +
  1. $CATALINA_BASE/conf/[enginename]/[hostname]/[webappname].xml
  2. +
  3. $CATALINA_BASE/webapps/[webappname]/META-INF/context.xml
  4. +
+

+ Files in (1) are named [webappname].xml but files in (2) are named + context.xml. If a Context Descriptor is not provided for a Context, + Tomcat configures the Context using default values. +

+

Deployment on Tomcat startup

+

+ If you are not interested in using the Tomcat Manager, or TCD, + then you'll need to deploy your web applications + statically to Tomcat, followed by a Tomcat startup. The location you + deploy web applications to for this type of deployment is called the + appBase which is specified per Host. You either copy a + so-called exploded web application, i.e non-compressed, to this + location, or a compressed web application resource .WAR file. +

+

+ The web applications present in the location specified by the Host's + (default Host is "localhost") appBase attribute (default + appBase is "$CATALINA_BASE/webapps") will be deployed on Tomcat startup + only if the Host's deployOnStartup attribute is "true". +

+

+ The following deployment sequence will occur on Tomcat startup in that + case: +

+
    +
  1. Any Context Descriptors will be deployed first.
  2. +
  3. + Exploded web applications not referenced by any Context + Descriptor will then be deployed. If they have an associated + .WAR file in the appBase and it is newer than the exploded web application, + the exploded directory will be removed and the webapp will be + redeployed from the .WAR +
  4. +
  5. .WAR files will be deployed
  6. +
+

Deploying on a running Tomcat server

+

+ It is possible to deploy web applications to a running Tomcat server. +

+

+ If the Host autoDeploy attribute is "true", the Host will + attempt to deploy and update web applications dynamically, as needed, + for example if a new .WAR is dropped into the appBase. + For this to work, the Host needs to have background processing + enabled which is the default configuration. +

+ +

+ autoDeploy set to "true" and a running Tomcat allows for: +

+
    +
  • Deployment of .WAR files copied into the Host appBase.
  • +
  • + Deployment of exploded web applications which are + copied into the Host appBase. +
  • +
  • + Re-deployment of a web application which has already been deployed from + a .WAR when the new .WAR is provided. In this case the exploded + web application is removed, and the .WAR is expanded again. + Note that the explosion will not occur if the Host is configured + so that .WARs are not exploded with a unpackWARs + attribute set to "false", in which case the web application + will be simply redeployed as a compressed archive. +
  • +
  • + Re-loading of a web application if the /WEB-INF/web.xml file (or + any other resource defined as a WatchedResource) is updated. +
  • +
  • + Re-deployment of a web application if the Context Descriptor + file from which the web application has been deployed is + updated. +
  • +
  • + Re-deployment of dependent web applications if the global or + per-host Context Descriptor file used by the web application is + updated. +
  • +
  • + Re-deployment of a web application if a Context Descriptor file (with a + filename corresponding to the Context path of the previously deployed + web application) is added to the + $CATALINA_BASE/conf/[enginename]/[hostname]/ + directory. +
  • +
  • + Undeployment of a web application if its document base (docBase) + is deleted. Note that on Windows, this assumes that anti-locking + features (see Context configuration) are enabled, otherwise it is not + possible to delete the resources of a running web application. +
  • +
+

+ Note that web application reloading can also be configured in the loader, in which + case loaded classes will be tracked for changes. +

+

Deploying using the Tomcat Manager

+

+ The Tomcat Manager is covered in its own manual page. +

+

Deploying using the Client Deployer Package

+

+ Finally, deployment of web application may be achieved using the + Tomcat Client Deployer. This is a package which can be used to + validate, compile, compress to .WAR, and deploy web applications to + production or development Tomcat servers. It should be noted that this feature + uses the Tomcat Manager and as such the target Tomcat server should be + running. +

+ +

+ It is assumed the user will be familiar with Apache Ant for using the TCD. + Apache Ant is a scripted build tool. The TCD comes pre-packaged with a + build script to use. Only a modest understanding of Apache Ant is + required (installation as listed earlier in this page, and familiarity + with using the operating system command shell and configuring + environment variables). +

+ +

+ The TCD includes Ant tasks, the Jasper page compiler for JSP compilation + before deployment, as well as a task which + validates the web application Context Descriptor. The validator task (class + org.apache.catalina.ant.ValidatorTask) allows only one parameter: + the base path of an exploded web application. +

+ +

+ The TCD uses an exploded web application as input (see the list of the + properties used below). A web application that is programmatically + deployed with the deployer may include a Context Descriptor in + /META-INF/context.xml. +

+ +

+ The TCD includes a ready-to-use Ant script, with the following targets: +

+
    +
  • + compile (default): Compile and validate the web + application. This can be used standalone, and does not need a running + Tomcat server. The compiled application will only run on the associated + Tomcat X.Y.Z server release, and is not guaranteed to work + on another Tomcat release, as the code generated by Jasper depends on its runtime + component. It should also be noted that this target will also compile + automatically any Java source file located in the + /WEB-INF/classes folder of the web application.
  • +
  • + deploy: Deploy a web application (compiled or not) to + a Tomcat server. +
  • +
  • undeploy: Undeploy a web application
  • +
  • start: Start web application
  • +
  • reload: Reload web application
  • +
  • stop: Stop web application
  • +
+ +

+ In order for the deployment to be configured, create a file + called deployer.properties in the TCD installation + directory root. In this file, add the following name=value pairs per + line: +

+ +

+ Additionally, you will need to ensure that a user has been + setup for the target Tomcat Manager (which TCD uses) otherwise the TCD + will not authenticate with the Tomcat Manager and the deployment will + fail. To do this, see the Tomcat Manager page. +

+ +
    +
  • + build: The build folder used will be, by default, + ${build}/webapp/${path} (${build}, by + default, points to ${basedir}/build). After the end + of the execution of the compile target, the web + application .WAR will be located at + ${build}/webapp/${path}.war. +
  • +
  • + webapp: The directory containing the exploded web application + which will be compiled and validated. By default, the folder is + myapp. +
  • +
  • + path: Deployed context path of the web application, + by default /myapp. +
  • +
  • + url: Absolute URL to the Tomcat Manager web application of a + running Tomcat server, which will be used to deploy and undeploy the + web application. By default, the deployer will attempt to access + a Tomcat instance running on localhost, at + http://localhost:8080/manager/text. +
  • +
  • + username: Tomcat Manager username (user should have a role of + manager-script) +
  • +
  • password: Tomcat Manager password.
  • +
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/developers.html b/test.dockerapp/tomcat/webapps/docs/developers.html new file mode 100644 index 0000000..c183b65 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/developers.html @@ -0,0 +1,89 @@ + +Apache Tomcat 8 (8.0.53) - Tomcat Developers

Tomcat Developers

Active Developers

+ +

+ The list indicates the developers' main areas of interest. Feel free to + add to the list :) The developers email addresses are + [login]@apache.org. Please do not contact + developers directly for any support issues (please post to the + tomcat-users mailing list instead, or one of the other support + resources; some organizations and individual consultants also offer + for pay Tomcat support, as listed on the + support and + training page on the Tomcat Wiki). +

+ +
    +
  • Bill Barker (billbarker): Connectors
  • +
  • Costin Manolache (costin): Catalina, Connectors
  • +
  • Filip Hanik (fhanik): Clustering, Release Manager
  • +
  • Jean-Frederic Clere (jfclere): Connectors
  • +
  • Jim Jagielski (jim): Connectors
  • +
  • Konstantin Kolinko (kkolinko): Catalina
  • +
  • Mark Thomas (markt): CGI, SSI, WebDAV, bug fixing
  • +
  • Mladen Turk (mturk): Connectors
  • +
  • Peter Rossbach (pero): Catalina, Clustering, JMX
  • +
  • Rainer Jung (rjung): Catalina, Clustering, Connectors
  • +
  • Remy Maucherat (remm): Catalina, Connectors, Docs
  • +
  • Tim Funk (funkman): Catalina, Docs
  • +
  • Tim Whittington (timw): Connectors
  • +
+ +

Retired Developers

+ +
    +
  • Amy Roh (amyroh): Catalina
  • +
  • Glenn Nielsen (glenn): Catalina, Connectors
  • +
  • Henri Gomez (hgomez): Connectors
  • +
  • Jan Luehe (luehe): Jasper
  • +
  • Jean-Francois Arcand (jfarcand): Catalina
  • +
  • Kin-Man Chung (kinman): Jasper
  • +
  • Yoav Shapira (yoavs): Docs, JMX, Catalina, balancer
  • +
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/elapi/index.html b/test.dockerapp/tomcat/webapps/docs/elapi/index.html new file mode 100644 index 0000000..5fa2049 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/elapi/index.html @@ -0,0 +1,34 @@ + + + + + + API docs + + + + +The EL Javadoc is not installed by default. Download and install +the "fulldocs" package to get it. + +You can also access the javadoc online in the Tomcat + +documentation bundle. + + + diff --git a/test.dockerapp/tomcat/webapps/docs/extras.html b/test.dockerapp/tomcat/webapps/docs/extras.html new file mode 100644 index 0000000..e86b87e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/extras.html @@ -0,0 +1,128 @@ + +Apache Tomcat 8 (8.0.53) - Additional Components

Additional Components

Table of Contents

Introduction

+

+ A number of additional components may be used with Apache Tomcat. These + components may be built by users should they need them or they can be + downloaded from one of the mirrors. +

+ +

Downloading

+

+ To download the extras components open the + Tomcat download page + and select "Browse" from the Quick Navigation Links. The extras components + can be found in bin/extras. +

+

Building

+ +

+ The additional components are built using the extras target + of the standard Tomcat Ant script which is present in the source bundle of + Tomcat. +

+ +

The build process is the following:

+ +
    +
  • Follow the build instructions to build a + Tomcat binary from the source bundle (note: it will be used by the build + process of the additional components, but does not need to be actually + used later on)
  • +
  • Execute the command ant extras to run the build + script
  • +
  • The additional components JARs will be placed in the + output/extras folder
  • +
  • Refer to the documentation below about the usage of these JARs
  • +
+ +

Components list

+ +

Full commons-logging implementation

+ +

+ Tomcat uses a package renamed commons-logging API implementation which is + hardcoded to use the java.util.logging API. The commons-logging additional + component builds a full fledged package renamed commons-logging + implementation which can be used to replace the implementation provided with + Tomcat. See the logging page for usage + instructions. +

+ +
+ +

Web Services support (JSR 109)

+ +

+ Tomcat provides factories for JSR 109 which may be used to resolve web + services references. Place the generated catalina-ws.jar as well as + jaxrpc.jar and wsdl4j.jar (or another implementation of JSR 109) in the + Tomcat lib folder. +

+ +

+ Users should be aware that wsdl4j.jar is licensed under CPL 1.0 and not the + Apache License version 2.0. +

+ +
+ +

JMX Remote Lifecycle Listener

+ +

+ The JMX protocol requires the JMX server (Tomcat in this instance) to listen + on two network ports. One of these ports can be fixed via configuration but + the second is selected randomly. This makes it difficult to use JMX through + a firewall. The JMX Remote Lifecycle Listener allows both ports to be fixed, + simplifying the process of connecting to JMX through a firewall. See the listeners page for usage instructions. +

+ +
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-apps.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-apps.html new file mode 100644 index 0000000..e62a31a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-apps.html @@ -0,0 +1,299 @@ + +Catalina Functional Specifications (8.0.53) - Administrative Apps - Overall Requirements

Administrative Apps - Overall Requirements

Table of Contents

Overview

+ + +

Introduction

+ +

The purpose of this specification is to define high level requirements + for administrative applications that can be used to manage the operation + of a running Tomcat container. A variety of Access Methods + to the supported administrative functionality shall be supported, to + meet varying requirements:

+
    +
  • As A Scriptable Web Application - The existing + Manager web application provides a simple HTTP-based + interface for managing Tomcat through commands that are expressed + entirely through a request URI. This is useful in environments + where you wish to script administrative commands with tools that + can generate HTTP transactions.
  • +
  • As An HTML-Based Web Application - Use an HTML presentation + to provide a GUI-like user interface for humans to interact with the + administrative capabilities.
  • +
  • As SOAP-Based Web Services - The operational commands to + administer Tomcat are made available as web services that utilize + SOAP message formats.
  • +
  • As Java Management Extensions (JMX) Commands - The operational + commands to administer Tomcat are made available through JMX APIs, + for integration into management consoles that utilize them.
  • +
  • Other Remote Access APIs - Other remote access APIs, such + as JINI, RMI, and CORBA can also be utilized to access administrative + capabilities.
  • +
+ +

Underlying all of the access methods described above, it is assumed + that the actual operations are performed either directly on the + corresponding Catalina components (such as calling the + Deployer.deploy() method to deploy a new web application), + or through a "business logic" layer that can be shared across all of the + access methods. This approach minimizes the cost of adding new + administrative capabilities later -- it is only necessary to add the + corresponding business logic function, and then write adapters to it for + all desired access methods.

+ +

The current status of this functional specification is + PROPOSED. It has not yet been discussed and + agreed to on the TOMCAT-DEV mailing list.

+ +
+ + +

External Specifications

+ +

The implementation of this functionality depends on the following + external specifications:

+ + +
+ + +

Implementation Requirements

+ +

The implementation of this functionality shall conform to the + following requirements:

+
    +
  • To the maximum extent feasible, all administrative functions, + and the access methods that support them, shall run portably + on all platforms where Tomcat itself runs.
  • +
  • In a default Tomcat distribution, all administrative capabilities + shall be disabled. It shall be necessary for a system + administrator to specifically enable the desired access methods + (such as by adding a username/password with a specific role to + the Tomcat user's database.
  • +
  • Administrative functions shall be realized as direct calls to + corresponding Catalina APIs, or through a business logic layer + that is independent of the access method used to initiate it.
  • +
  • The common business logic components shall be implemented in + package org.apache.catalina.admin.
  • +
  • The common business logic components shall be built as part of the + standard Catalina build process, and made visible in the + Catalina class loader.
  • +
  • The Java components required for each access method shall be + implemented in subpackages of org.apache.catalina.admin. +
  • +
  • The build scripts should treat each access method as optional, + so that it will be built only if the corresponding required + APIs are present at build time.
  • +
  • It shall be possible to save the configured state of the running + Tomcat container such that this state can be reproduced when the + container is shut down and restarted.
  • +
  • Administrative commands to start up and shut down the overall + Tomcat container are out of scope for the + purposes of these applications. It is assumed that other + (usually platform-specific) mechanisms will be used for container + startup and shutdown.
  • +
+ +
+ + +

Dependencies

+ + +

Environmental Dependencies

+ +

The following environmental dependencies must be met in order for + administrative applications to operate correctly:

+
    +
  • For access methods that require creation of server sockets, the + appropriate ports must be configured and available.
  • +
+ +
+ + +

Container Dependencies

+ +

Correct operation of administrative applications depends on the + following specific features of the surrounding container:

+
    +
  • To the maximum extent feasible, Catalina components that offer + direct administrative APIs and property setters shall support + "live" changes to their operation, without requiring a container + restart.
  • +
+ +
+ + +

External Technologies

+ +

The availability of the following technologies can be assumed + for the implementation and operation of the various access methods + and the corresponding administrative business logic:
+ FIXME - This list below is totally outdated, but nobody + cares about the administrative app anymore. It is removed and unsupported + since Tomcat 6.0.

+ + +
+ + +

Functionality

+ + +

Properties of Administered Objects

+ +

Functional requirements for administrative applications are specified + in terms of Administered Objects, whose definitions and detailed + properties are listed here. In general, + Administered Objects correspond to components in the Catalina architecture, + but these objects are defined separately here for the following reasons:

+
    +
  • It is possible that the administrative applications do not expose + every possible configurable facet of the underlying components.
  • +
  • In some cases, an Administered Object (from the perspective of an + administrative operation) is realized by more than one Catalina + component, at a finer-grained level of detail.
  • +
  • It is necessary to represent the configuration information for a + component separately from the component itself (for instance, in + order to store that configuration information for later use).
  • +
  • It is necessary to represent configuration information (such as + a Default Context) when there is no corresponding component instance. +
  • +
  • Administered Objects, when realized as Java classes, will include + methods for administrative operations that have no correspondence + to operations performed by the corresponding actual components.
  • +
+ +

It is assumed that the reader is familiar with the overall component + architecture of Catalina. For further information, see the corresponding + Developer Documentation. To distinguish names that are used as both + Administered Objects and Components, different + font presentations are utilized. Default values for many properties + are listed in [square brackets].

+ +
+ + +

Supported Administrative Operations

+ +

The administrative operations that are available are described in terms + of the corresponding Administered Objects (as defined above), in a manner + that is independent of the access method by which these operations are + requested. In general, such operations are relevant only in the context + of a particular Administered Object (and will most likely be realized as + method calls on the corresponding Administered Object classes), so they + are organized based on the currently "focused" administered object. + The available Supported Operations are documented + here.

+ +
+ + +

Access Method Specific Requirements

+ +
Scriptable Web Application
+ +

An appropriate subset of the administrative operations described above + shall be implemented as commands that can be performed by the "Manager" + web application. FIXME - Enumerate them.

+ +

In addition, this web application shall conform to the following + requirements:

+
    +
  • All request URIs shall be protected by security constraints that + require a security role to be assigned for processing.
  • +
  • The default user database shall not contain any + user that has been assigned a security role.
  • +
+ +
HTML-Based Web Application
+ +

The entire suite of administrative operations described above shall be + made available through a web application designed for human interaction. + In addition, this web application shall conform to the following + requirements:

+
    +
  • Must be implemented using servlet, JSP, and MVC framework technologies + described under "External Technologies", above.
  • +
  • Prompts and error messages must be internationalizable to multiple + languages.
  • +
  • Rendered HTML must be compatible with Netscape Navigator (version 4.7 + or later) and Internet Explorer (version 5.0 or later).
  • +
+ +
+ + +

Testable Assertions

+ +

FIXME - Complete this section.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-objects.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-objects.html new file mode 100644 index 0000000..97132cb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-objects.html @@ -0,0 +1,453 @@ + +Catalina Functional Specifications (8.0.53) - Administrative Apps - Administered Objects

Administrative Apps - Administered Objects

Table of Contents

Administered Objects Overview

+ +

This document defines the Administered Objects that represent +the internal architectural components of the Catalina servlet container. +Associated with each is a set of Supported +Operations that can be performed when the administrative application is +"focused" on a particular configurable object.

+ +

The following Administered Objects are defined:

+ + +

Access Logger

+ +

An Access Logger is an optional Valve that can + create request access logs in the same formats as those provided by + web servers. Such access logs are useful input to hit count and user + access tracking analysis programs. An Access Logger can be attached to + an Engine, a Host, a Context, or a Default + Context.

+ +

The standard component implementing an Access Logger is + org.apache.catalina.valves.AccessLogValve. It supports the + following configurable properties:

+
    +
  • debug - Debugging detail level. [0]
  • +
  • directory - Absolute or relative (to $CATALINA_BASE) path + of the directory into which access log files are created. + [logs].
  • +
  • pattern - Pattern string defining the fields to be + included in the access log output, or "common" for the standard + access log pattern. See + org.apache.catalina.valves.AccessLogValve for more + information. [common]
  • +
  • prefix - Prefix added to the beginning of each log file + name created by this access logger.
  • +
  • resolveHosts - Should IP addresses be resolved to host + names in the log? [false]
  • +
  • suffix - Suffix added to the end of each log file name + created by this access logger.
  • +
+ +

Connector

+ +

A Connector is the representation of a communications endpoint + by which requests are received from (and responses returned to) a Tomcat + client. The administrative applications shall support those connectors + that are commonly utilized in Tomcat installations, as described in detail + below.

+ +

For standalone use, the standard connector supporting the HTTP/1.1 + protocol is org.apache.catalina.connectors.http.HttpConnector. + It supports the following configurable properties:

+
    +
  • acceptCount - The maximum queue length of incoming + connections that have not yet been accepted. [10]
  • +
  • address - For servers with more than one IP address, the + address upon which this connector should listen. [All Addresses]
  • +
  • bufferSize - Default input buffer size (in bytes) for + requests created by this Connector. [2048]
  • +
  • debug - Debugging detail level. [0]
  • +
  • enableLookups - Should we perform DNS lookups on remote + IP addresses when request.getRemoteHost() is called? + [false]
  • +
  • maxProcessors - The maximum number of processor threads + supported by this connector. [20]
  • +
  • minProcessors - The minimum number of processor threads + to be created at container startup. [5]
  • +
  • port - TCP/IP port number on which this Connector should + listen for incoming requests. [8080]
  • +
  • proxyName - Host name to be returned when an application + calls request.getServerName(). [Value of Host: header]
  • +
  • proxyPort - Port number to be returned when an application + calls request.getServerPort(). [Same as port] +
  • +
+ +

Context

+ +

A Context is the representation of an individual web application, + which is associated with a corresponding Host. Note that the + administrable properties of a Context do not + include any settings from inside the web application deployment descriptor + for that application.

+ +

The standard component implementing a Context is + org.apache.catalina.core.StandardContext. It supports the + following configurable properties:

+
    +
  • cookies - Should be use cookies for session identifier + communication? [true]
  • +
  • crossContext - Should calls to + ServletContext.getServletContext() return the actual + context responsible for the specified path? [false]
  • +
  • debug - Debugging detail level. [0]
  • +
  • docBase - The absolute or relative (to the + appBase of our owning Host) pathname of a + directory containing an unpacked web application, or of a web + application archive (WAR) file.
  • +
  • override - Should settings in this Context + override corresponding settings in the Default Context? + [false]
  • +
  • path - Context path for this web application, or an empty + string for the root application of a Host. [Inferred from + directory or WAR file name]
  • +
  • reloadable - Should Tomcat monitor classes in the + /WEB-INF/classes directory for changes, and reload the + application if they occur? [false]
  • +
  • useNaming - Should Tomcat provide a JNDI naming context, + containing preconfigured entries and resources, corresponding to the + requirements of the Java2 Enterprise Edition specification? [true]
  • +
  • workDir - Absolute pathname of a scratch directory that is + provided to this web application. [Automatically assigned relative to + $CATALINA_BASE/work]
  • +
+ +

Each Context is owned by a parent Host, and is + associated with:

+
    +
  • An optional Access Logger that logs all requests processed + by this web application.
  • +
  • Zero or more Environment Entries representing environment + entries for the JNDI naming context associated with a web + application.
  • +
  • Zero or more JDBC Resources representing database connection + pools associated with a web application.
  • +
  • A Loader representing the web application class loader used + by this web application.
  • +
  • A Manager representing the session manager used by this + web application.
  • +
  • An optional Realm used to provide authentication and access + control information for this web application.
  • +
  • Zero or more Request Filters used to limit access to this + web application based on remote host name or IP address.
  • +
+ +

Default Context

+ +

A Default Context represents a subset of the configurable + properties of a Context, and is used to set defaults for those + properties when web applications are automatically deployed. A Default + Context object can be associated with an Engine or a + Host. The following configurable properties are supported:

+
    +
  • cookies - Should be use cookies for session identifier + communication? [true]
  • +
  • crossContext - Should calls to + ServletContext.getServletContext() return the actual + context responsible for the specified path? [false]
  • +
  • reloadable - Should Tomcat monitor classes in the + /WEB-INF/classes directory for changes, and reload the + application if they occur? [false]
  • +
  • useNaming - Should Tomcat provide a JNDI naming context, + containing preconfigured entries and resources, corresponding to the + requirements of the Java2 Enterprise Edition specification? [true]
  • +
+ +

Each Default Context is owned by a parent Engine or + Host, and is associated with:

+
    +
  • Zero or more Environment Entries representing environment + entries for the JNDI naming context associated with a web + application.
  • +
  • Zero or more JDBC Resources representing database connection + pools associated with a web application.
  • +
  • An optional Loader representing default configuration + properties for the Loader component of deployed web applications.
  • +
  • An optional Manager representing default configuration + properties for the Manager component of deployed web applications.
  • +
+ +

Default Deployment Descriptor

+ +

Default web application characteristics are configured in a special + deployment descriptor named $CATALINA_BASE/conf/web.xml. This + section describes the configurable components that may be stored there.

+ +

FIXME - Complete the description of default servlets, + default mappings, default MIME types, and so on.

+ +

Engine

+ +

An Engine is the representation of the entire Catalina + servlet container, and processes all requests for all of the associated + virtual hosts and web applications.

+ +

The standard component implementing an Engine is + org.apache.catalina.core.StandardEngine. It supports the + following configurable properties:

+
    +
  • debug - Debugging detail level. [0]
  • +
  • defaultHost - Name of the Host to which requests + will be directed if the requested host is unknown. [localhost]
  • +
  • name - Logical name of this engine. [Tomcat Stand-Alone] +
  • +
+ +

Each Engine is owned by a parent Service, and is + associated with:

+
    +
  • An optional Access Logger that logs all requests processed + by the entire container.
  • +
  • A Default Context, representing default properties of a + Context for automatically deployed applications for all + associated Hosts (unless overridden by a subordinate + component).
  • +
  • One or more Hosts representing individual virtual hosts + supported by this container.
  • +
  • A Realm used to provide authentication and access control + information for all virtual hosts and web applications (unless + overridden by a subordinate component).
  • +
  • Zero or more Request Filters used to limit access to the + entire container based on remote host name or IP address.
  • +
+ +

Environment Entry

+ +

An Environment Entry is the representation of a + <env-entry> element from a web application deployment + descriptor. It will cause the creation of a corresponding entry in the + JNDI naming context provided to the corresponding Context. The + following configurable properties are supported:

+
    +
  • description - Description of this environment entry.
  • +
  • name - Environment entry name (relative to the + java:comp/env context)
  • +
  • type - Environment entry type (must be one of the fully + qualified Java classes listed in the servlet spec).
  • +
  • value - Environment entry value (must be convertible from + String to the specified type.
  • +
+ +

Host

+ +

A Host is the representation of an individual virtual host, + which has a unique set of associated web applications.

+ +

The standard component implementing a Host is + org.apache.catalina.core.StandardHost. It supports the + following configurable properties:

+
    +
  • aliases - Zero or more DNS names that are also associated + with this host (for example, a particular host might be named + www.mycompany.com with an alias company.com). +
  • +
  • appBase - Absolute or relative (to $CATALINA_BASE) path + to a directory from which web applications will be automatically + deployed.
  • +
  • debug - Debugging detail level. [0]
  • +
  • name - DNS Name of the virtual host represented by this + object.
  • +
  • unpackWARs - Should web application archive files + deployed by this virtual host be unpacked first? [true]
  • +
+ +

Each Host is owned by a parent Engine, and is + associated with:

+
    +
  • An optional Access Logger that logs all requests processed + by this virtual host.
  • +
  • One or more Contexts representing the web applications + operating on this Host.
  • +
  • A Default Context representing default Context + properties for web applications that are automatically deployed + by this Host.
  • +
  • A optional Realm used to provide authentication and access + control information for all web applications associated with this + virtual host (unless overridden by a subordinate component).
  • +
+ +

FIXME - Should we support configuration of the + User Web Applications functionality?

+ +

JDBC Resource

+ +

A JDBC Resources represents a database connection pool (i.e. + an implementation of javax.sql.DataSource that will be + configured and made available in the JNDI naming context associated with + a web application.

+ +

FIXME - properties of this administered object

+ +

Loader

+ +

A Loader represents a web application class loader that will + be utilized to provide class loading services for a particular + Context.

+ +

The standard component implementing a Loader is + org.apache.catalina.loader.WebappLoader. It supports + the following configurable properties:

+
    +
  • reloadable - Should this class loader check for modified + classes and initiate automatic reloads? [Set automatically from the + reloadable property of the corresponding Context] +
  • +
+ +

Each Loader is owned by a parent Context.

+ +

Manager

+ +

A Manager represents a session manager that will be associated + with a particular web application. FIXME - Add support + for advanced session managers and their associated Stores.

+ +

The standard component implementing a Manager is + org.apache.catalina.session.StandardManager. It supports + the following configurable properties:

+
    +
  • maxActiveSessions - The maximum number of active sessions + that are allowed, or -1 for no limit. [-1]
  • +
+ +

Each Manager is owned by a parent Context.

+ +

Realm

+ +

A Realm represents a "database" of information about authorized + users, their passwords, and the security roles assigned to them. This will + be used by the container in the implementation of container-managed security + in accordance with the Servlet Specification. Several alternative + implementations are supported.

+ +

org.apache.catalina.realm.MemoryRealm initializes its user + information from a simple XML file at startup time. If changes are made + to the information in this file, the corresponding web applications using + it must be restarted for the changes to take effect. It supports the + following configurable properties:

+
    +
  • debug - Debugging detail level. [0]
  • +
  • pathname - Absolute or relative (to $CATALINA_BASE) path to + the XML file containing our user information. [conf/tomcat-users.xml] +
  • +
+ +

org.apache.catalina.realm.JDBCRealm uses a relational + database (accessed via JDBC APIs) to contain the user information. Changes + in the contents of this database take effect immediately; however, the roles + assigned to a particular user are calculated only when the user initially + logs on (and not per request). The following configurable properties + are supported:

+
    +
  • connectionName - Database username to use when establishing + a JDBC connection.
  • +
  • connectionPassword - Database password to use when + establishing a JDBC connection.
  • +
  • connectionURL - Connection URL to use when establishing + a JDBC connection.
  • +
  • digest - Name of the MessageDigest algorithm + used to encode passwords in the database, or a zero-length string for + no encoding. [Zero-length String]
  • +
  • driverName - Fully qualified Java class name of the JDBC + driver to be utilized.
  • +
  • roleNameCol - Name of the column, in the User Roles table, + which contains the role name.
  • +
  • userCredCol - Name of the column, in the Users table, + which contains the password (encrypted or unencrypted).
  • +
  • userNameCol - Name of the column, in both the Users and + User Roles tables, that contains the username.
  • +
  • userRoleTable - Name of the User Roles table, which contains + one row per security role assigned to a particular user. This table must + contain the columns specified by the userNameCol and + roleNameCol properties.
  • +
  • userTable - Name of the Users table, which contains one row + per authorized user. This table must contain the columns specified by + the userNameCol and userCredCol properties. +
  • +
+ +

FIXME - Should we provide mechanisms to edit the contents + of a "tomcat-users.xml" file through the admin applications?

+ +

Each Realm is owned by a parent Engine, Host, + or Context.

+ +

Request Filter

+ +

FIXME - complete this entry

+ +

Server

+ +

FIXME - complete this entry

+ +

Service

+ +

FIXME - complete this entry

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-opers.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-opers.html new file mode 100644 index 0000000..0df31e8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-admin-opers.html @@ -0,0 +1,309 @@ + +Catalina Functional Specifications (8.0.53) - Administrative Apps - Supported Operations

Administrative Apps - Supported Operations

Table of Contents

Supported Operations Overview

+ +

This document defines the Supported Operations that may +be performed against the Administered +Objects that are supported by Tomcat administrative applications. +Not all operations are required to be available through every administrative +application that is implemented. However, if a given operation is available, +it should operate consistently with the descriptions found here.

+ +

Supported Operations are described for the following Administered +Objects:

+ + +

Access Logger

+ +

From the perspective of a particular Access Logger, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Engine, Host, or + Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Connector

+ +

From the perspective of a particular Connector, it shall be + possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Service.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Context

+ +

From the perspective of a particular Context, it shall be + possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Host.
  • +
  • Edit the configurable properties of this object.
  • +
  • Create and configure a new Access Logger associated + with this object.
  • +
  • Edit the configurable properties of the associated Access + Logger.
  • +
  • Remove the associated Access Logger.
  • +
  • Create and configure a new Environment Entry associated + with this object.
  • +
  • Select and edit the configurable properties of an associated + Environment Entry.
  • +
  • Remove an associated Environment Entry.
  • +
  • Create and configure a new JDBC Resource associated + with this object.
  • +
  • Select and edit the configurable properties of an associated + JDBC Resource.
  • +
  • Remove an associated JDBC Resource.
  • +
  • Create and configure a new Loader associated with + this object.
  • +
  • Edit the configurable properties of the associated Loader.
  • +
  • Remove the associated Loader.
  • +
  • Create and configure a new Manager associated with + this object.
  • +
  • Edit the configurable properties of the associated Manager.
  • +
  • Remove the associated Manager.
  • +
  • Create and configure a new Realm associated with + this object.
  • +
  • Edit the configurable properties of the associated Realm.
  • +
  • Remove the associated Realm.
  • +
  • Create and configure a new Request Filter associated with + this object.
  • +
  • Select and edit the configurable properties of an + associated Request Filter
  • +
  • Remove an associated Request Filter.
  • +
+ +

Default Context

+ +

From the perspective of a particular Default Context, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Engine or Host.
  • +
  • Edit the configurable properties of this object.
  • +
  • Create and configure a new Environment Entry associated + with this object.
  • +
  • Select and edit the configurable properties of an associated + Environment Entry.
  • +
  • Remove an associated Environment Entry.
  • +
  • Create and configure a new JDBC Resource associated + with this object.
  • +
  • Select and edit the configurable properties of an associated + JDBC Resource.
  • +
  • Remove an associated JDBC Resource.
  • +
+ +

Engine

+ +

From the perspective of a particular Engine, it shall be + possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Service.
  • +
  • Edit the configurable properties of this object.
  • +
  • Create and configure a new Access Logger associated + with this object.
  • +
  • Edit the configurable properties of the associated Access + Logger.
  • +
  • Remove the associated Access Logger.
  • +
  • Create and configure a new Default Context associated + with this object.
  • +
  • Edit the configurable properties of the associated Default + Context.
  • +
  • Remove the associated Default Context.
  • +
  • Create and configure a new Host associated with + this object.
  • +
  • Select and edit the configurable properties of an + associated Host.
  • +
  • Remove an associated Host.
  • +
  • Create and configure a new Realm associated with + this object.
  • +
  • Edit the configurable properties of the associated Realm.
  • +
  • Remove the associated Realm.
  • +
  • Create and configure a new Request Filter associated with + this object.
  • +
  • Select and edit the configurable properties of an + associated Request Filter
  • +
  • Remove an associated Request Filter.
  • +
+ +

Environment Entry

+ +

From the perspective of a particular Environment Entry, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Context or Default Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Host

+ +

From the perspective of a particular Host, it shall be + possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Engine.
  • +
  • Edit the configurable properties of this object.
  • +
  • Create and configure a new Access Logger associated + with this object.
  • +
  • Edit the configurable properties of the associated Access + Logger.
  • +
  • Remove the associated Access Logger.
  • +
  • Create and configure a new Context associated with + this object.
  • +
  • Select and edit the configurable properties of an associated + Context.
  • +
  • Remove an associated Context.
  • +
  • Create and configure a new Default Context associated + with this object.
  • +
  • Edit the configurable properties of the associated Default + Context.
  • +
  • Remove the associated Default Context.
  • +
  • Create and configure a new Realm associated with + this object.
  • +
  • Edit the configurable properties of the associated Realm.
  • +
  • Remove the associated Realm.
  • +
  • Create and configure a new Request Filter associated with + this object.
  • +
  • Select and edit the configurable properties of an + associated Request Filter
  • +
  • Remove an associated Request Filter.
  • +
+ +

JDBC Resource

+ +

From the perspective of a particular JDBC Resource, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Context or Default Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Loader

+ +

From the perspective of a particular Loader, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Manager

+ +

From the perspective of a particular Manager, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Realm

+ +

From the perspective of a particular Realm, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Engine, Host, or + Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Request Filter

+ +

From the perspective of a particular Request Filter, it shall + be possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Engine, Host, or + Context.
  • +
  • Edit the configurable properties of this object.
  • +
+ +

Server

+ +

From the perspective of the overall Server, it shall be + possible to perform the following administrative operations:

+
    +
  • Edit the configurable properties of this object.
  • +
  • Create and configure a new Service associated with + this object.
  • +
  • Select and edit the configurable properties of an associated + Service.
  • +
+ +

Service

+ +

From the perspective of a particular Service, it shall be + possible to perform the following administrative operations:

+
    +
  • Navigate to the owning Server.
  • +
  • Edit the configurable properties of this object.
  • +
  • Create and configure a new Connector associated with + this object.
  • +
  • Select and edit the configurable properties of an associated + Connector.
  • +
  • Remove an associated Connector.
  • +
  • Create and configure a new Engine associated with + this object.
  • +
  • Edit the configurable properties of the associated Engine.
  • +
  • Remove the associated Engine.
  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-default.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-default.html new file mode 100644 index 0000000..d5dc35d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-default.html @@ -0,0 +1,270 @@ + +Catalina Functional Specifications (8.0.53) - Default Servlet

Default Servlet

Table of Contents

Overview

+ + +

Introduction

+ +

The purpose of the Default Servlet is to serve + static resources of a web application in response to client requests. + As the name implies, it is generally configured as the "default" + servlet for a web application, by being mapped to a URL pattern "/".

+ +
+ + +

External Specifications

+ +

The following external specifications have provisions which + partially define the correct behavior of the default servlet:

+ + +
+ + +

Implementation Requirements

+ +

The implementation of this functionality shall conform to the + following requirements:

+
    +
  • Must be implemented as a servlet.
  • +
  • Must support configurable parameters for debugging detail level, + input buffer size, output buffer size, whether or not to produce + directory listings when no welcome file is present, and whether or not + modifications are supported via DELETE and PUT.
  • +
  • Log debugging and operational messages (suitably internationalized) + via the getServletContext().log() method.
  • +
+ +
+ + +

Dependencies

+ + +

Environmental Dependencies

+ +

The following environmental dependencies must be met in order for + the default servlet to operate correctly:

+
    +
  • The default servlet must be registered in the application deployment + descriptor (or the default deployment descriptor in file + $CATALINA_BASE/conf/web.xml) using a "default servlet" + servlet mapping, signified by URL pattern "/".
  • +
+ +
+ + +

Container Dependencies

+ +

Correct operation of the default servlet depends on the following + specific features of the surrounding container:

+
    +
  • The container shall provide a servlet context attribute that + lists the welcome file names that have been defined for this + web application.
  • +
  • The container shall provide a servlet context attribute that + contains a javax.naming.directory.DirContext + implementation representing the static resources of this + web application.
  • +
+ +
+ + +

Functionality

+ + +

Initialization Functionality

+ +

The following processing must be performed when the init() + method of the default servlet is called:

+
    +
  • Process and sanity check configuration parameters.
  • +
+ +
+ + +

Per-Request Functionality

+ + +

For all HTTP request methods, the resource path is determined from + the path information provided to this request, either as request attribute + javax.servlet.include.path_info (for a request dispatcher + access to a static resource) or by calling + request.getPathInfo() directly.

+ +

On each HTTP DELETE request processed by this servlet, the following + processing shall be performed:

+
    +
  • If modifications to the static resources are not allowed (set by a + configuration parameter), return HTTP status 403 (forbidden).
  • +
  • If an attempt is made to delete a resource from /META-INF + or /WEB-INF, return HTTP status 403 (forbidden).
  • +
  • If the requested resource does not exist, return HTTP status 404 + (not found)
  • +
  • Unbind the resource from the directory context containing the + static resources for this web application. If successful, return + HTTP status 204 (no content). Otherwise, return HTTP status 405 + (method not allowed).
  • +
+ + +

On each HTTP GET request processed by this servlet, the following + processing shall be performed:

+
    +
  • If the request is for a resource under /META-INF or + /WEB-INF, return HTTP status 404 (not found).
  • +
  • If the requested resource does not exist, return HTTP status 404 + (not found).
  • +
  • If the requested resource is not a directory, but the resource + path ends in "/" or "\", return HTTP status 404 (not found).
  • +
  • If the requested resource is a directory: +
      +
    • If the request path does not end with "/", redirect to a + corresponding path with "/" appended so that relative references + in welcome files are resolved correctly.
    • +
    • If one of the specified welcome files exists, redirect to the + path for that welcome file so that it will be served explicitly. +
    • +
  • +
  • If the request being processed contains an If-Range + header, perform the processing described in the HTTP/1.1 specification + to determine whether the client's information is up to date.
  • +
  • Determine the content type of the response, by looking up the + corresponding MIME type in our servlet context.
  • +
  • If the requested resource is a directory: +
      +
    • If directory listings are suppressed, return HTTP status 404 + (not found).
    • +
    • Set the content type to text/html.
    • +
  • +
  • Determine the range(s) to be returned, based on the existence of + any If-Range and Range headers.
  • +
  • If the requested resource is a directory, include an ETag + header in the response, with the value calculated based on the content + of the directory.
  • +
  • Include a Last-Modified header in the response documenting + the date/time that the resource was last modified.
  • +
  • Unless we are processing a HEAD request, include the appropriate + content (or content ranges) in the response.
  • +
+ +

On each HTTP HEAD request processed by this servlet, the following + processing shall be performed:

+
    +
  • Processed identically to an HTTP GET request, except that the data + content is not transmitted after the headers.
  • +
+ +

On each HTTP POST request processed by this servlet, the following + processing shall be performed:

+
    +
  • Processed identically to an HTTP GET request.
  • +
+ + +

On each HTTP PUT request processed by this servlet, the following + processing shall be performed:

+
    +
  • If modifications to the static resources are not allowed (set by a + configuration parameter), return HTTP status 403 (forbidden).
  • +
  • If an attempt is made to delete a resource from /META-INF + or /WEB-INF, return HTTP status 403 (forbidden).
  • +
  • Create a new resource from the body of this request.
  • +
  • Bind or rebind the specified path to the new resource (depending on + whether it currently exists or not). Return HTTP status as follows: +
      +
    • If binding was unsuccessful, return HTTP status 409 (conflict). +
    • +
    • If binding was successful and the resource did not previously + exist, return HTTP status 201 (created).
    • +
    • If binding was successful and the resource previously existed, + return HTTP status 204 (no content).
    • +
  • +
+ +
+ + +

Finalization Functionality

+ +

No specific processing is required when the destroy() + method is called:

+ +
+ + +

Testable Assertions

+ +

In addition to the assertions implied by the functionality requirements + listed above, the following additional assertions shall be tested to + validate the behavior of the default servlet:

+
    +
  • Requests for resources that do not exist in the web application must + return HTTP status 404 (not found).
  • +
  • The default servlet must operate identically for web applications that + are run out of a WAR file directly, or from an unpacked directory + structure.
  • +
  • If the web application is running out of an unpacked directory + structure, the default servlet must recognize cases where the resource + has been updated through external means.
  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jdbc-realm.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jdbc-realm.html new file mode 100644 index 0000000..823b3c9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jdbc-realm.html @@ -0,0 +1,266 @@ + +Catalina Functional Specifications (8.0.53) - JDBCRealm

JDBCRealm

Table of Contents

Overview

+ + +

Introduction

+ +

The purpose of the JDBCRealm implementation is to + provide a mechanism by which Tomcat can acquire information needed + to authenticate web application users, and define their security roles, + from a relational database accessed via JDBC APIs. For integration + with Catalina, the resulting class(es) must implement the + org.apache.catalina.Realm interface.

+ +

This specification reflects a combination of functionality that is + already present in the org.apache.catalina.realm.JDBCRealm + class, as well as requirements for enhancements that have been + discussed. Where appropriate, requirements statements are marked + [Current] and [Requested] to distinguish them.

+ +

The current status of this functional specification is + PROPOSED. It has not yet been discussed and + agreed to on the TOMCAT-DEV mailing list.

+ +
+ + +

External Specifications

+ +

The implementation of this functionality depends on the following + external specifications:

+ + +
+ + +

Implementation Requirements

+ +

The implementation of this functionality shall conform to the + following requirements:

+
    +
  • Be realized in one or more implementation classes.
  • +
  • Implement the org.apache.catalina.Realm interface. + [Current]
  • +
  • Implement the org.apache.catalina.Lifecycle + interface. [Current]
  • +
  • Subclass the org.apache.catalina.realm.RealmBase + base class.
  • +
  • Live in the org.apache.catalina.realm package. + [Current]
  • +
  • Support a configurable debugging detail level. [Current]
  • +
  • Log debugging and operational messages (suitably internationalized) + via the getContainer().log() method. [Current]
  • +
+ +
+ + +

Dependencies

+ + +

Environmental Dependencies

+ +

The following environmental dependencies must be met in order for + JDBCRealm to operate correctly:

+
    +
  • The desire to utilize JDBCRealm must be registered in + $CATALINA_BASE/conf/server.xml, in a + <Realm> element that is nested inside a + corresponding <Engine>, <Host>, + or <Context> element.
  • +
+ +
+ + +

Container Dependencies

+ +

Correct operation of JDBCRealm depends on the following + specific features of the surrounding container:

+
    +
  • Interactions with JDBCRealm will be initiated by + the appropriate Authenticator implementation, based + on the login method that is selected.
  • +
  • JDBCRealm must have the JDBC standard API classes + available to it. For a JDK 1.2 or later container, these APIs + are included in the standard platform.
  • +
  • When connection pooling is implemented, JDBCRealm + must have the JDBC Optional Package (version 2.0 or later) APIs + available to it. This library is available as a separate + download (and will be included in Tomcat binary distributions).
  • +
+ +
+ + +

Functionality

+ + +

Overview of Operation

+ +

The main purpose of JDBCRealm is to allow Catalina to + authenticate users, and look up the corresponding security roles, from + the information found in a relational database accessed via JDBC APIs. + For maximum flexibility, the details of how this is done (for example, + the names of the required tables and columns) should be configurable.

+ +

Each time that Catalina needs to authenticate a user, it will call + the authenticate() method of this Realm implementation, + passing the username and password that were specified by the user. If + we find the user in the database (and match on the password), we accumulate + all of the security roles that are defined for this user, and create a + new GenericPrincipal object to be returned. If the user + is not authenticated, we return null instead. The + GenericUser object caches the set of security roles that + were owned by this user at the time of authentication, so that calls to + isUserInRole() can be answered without going back to the + database every time.

+ +
+ + +

Detailed Functional Requirements

+ + +

Configurable Properties

+ +

The implementation shall support the following properties + that can be configured with JavaBeans property setters:

+
    +
  • Configuration parameters defining the JDBC driver to use, the + database connection URL to be accessed, and the username/password + to use for logging in. [Current]
  • +
  • Configuration parameters describing the connection pool to be + created to support simultaneous authentications. [Requested]
  • +
  • Name of the tables to be searched for users and roles. [Current]
  • +
  • Name of the columns to be used for usernames, passwords, and + role names. [Current]
  • +
+ +

Lifecycle Functionality

+ +

The following processing must be performed when the start() + method is called:

+
    +
  • Establish a connection to the configured database, using the + configured username and password. [Current]
  • +
  • Configure and establish a connection pool of connections to the + database. [Requested]
  • +
+ +

The following processing must be performed when the stop() + method is called:

+
    +
  • Close any opened connections to the database.
  • +
+ + +

Method authenticate() Functionality

+ +

When authenticate() is called, the following processing + is required:

+
    +
  • Acquire the one and only connection [Current] or acquire a connection + from the connection pool [Requested].
  • +
  • Select the one and only row from the user's table for this user, + and retrieve the corresponding password column. If zero rows (or + more than one row) are found, return null.
  • +
  • Authenticate the user by comparing the (possibly encrypted) password + value that was received against the password presented by the user. + If there is no match, return null.
  • +
  • Acquire a List of the security roles assigned to the + authenticated user by selecting from the roles table.
  • +
  • Construct a new instance of class + org.apache.catalina.realm.GenericPrincipal, passing as + constructor arguments: this realm instance, the authenticated + username, and a List of the security roles associated + with this user.
  • +
  • WARNING - Do not attempt to cache and reuse previous + GenericPrincipal objects for a particular user, because + the information in the directory server might have changed since the + last time this user was authenticated.
  • +
  • Return the newly constructed GenericPrincipal.
  • +
+ + +

Method hasRole() Functionality

+ +

When hasRole() is called, the following processing + is required:

+
    +
  • The principal that is passed as an argument SHOULD + be one that we returned (instanceof class + org.apache.catalina.realm.GenericPrincipal, with a + realm property that is equal to our instance.
  • +
  • If the passed principal meets these criteria, check + the specified role against the list returned by + getRoles(), and return true if the + specified role is included; otherwise, return false.
  • +
  • If the passed principal does not meet these criteria, + return false.
  • +
+ +
+ +

Testable Assertions

+ +

In addition to the assertions implied by the functionality requirements + listed above, the following additional assertions shall be tested to + validate the behavior of JDBCRealm:

+
    +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jndi-realm.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jndi-realm.html new file mode 100644 index 0000000..385b6aa --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-jndi-realm.html @@ -0,0 +1,417 @@ + +Catalina Functional Specifications (8.0.53) - JNDIRealm

JNDIRealm

Table of Contents

Overview

+ + +

Introduction

+ +

The purpose of the JNDIRealm implementation is to + provide a mechanism by which Tomcat can acquire information needed + to authenticate web application users, and define their security roles, + from a directory server or other service accessed via JNDI APIs. For + integration with Catalina, this class must implement the + org.apache.catalina.Realm interface.

+ +

This specification reflects a combination of functionality that is + already present in the org.apache.catalina.realm.JNDIRealm + class, as well as requirements for enhancements that have been + discussed. Where appropriate, requirements statements are marked + [Current] and [Requested] to distinguish them.

+ +

The current status of this functional specification is + PROPOSED. It has not yet been discussed and + agreed to on the TOMCAT-DEV mailing list.

+ +

The code in the current version of JNDIRealm, and the + ideas expressed in this functional specification, are the results of + contributions from many individuals, including (alphabetically):

+
    +
  • Holman, John <j.g.holman@qmw.ac.uk>
  • +
  • Lockhart, Ellen <elockhart@home.com>
  • +
  • McClanahan, Craig <craigmcc@apache.org>
  • +
+ +
+ + +

External Specifications

+ +

The implementation of this functionality depends on the following + external specifications:

+ + +
+ + +

Implementation Requirements

+ +

The implementation of this functionality shall conform to the + following requirements:

+
    +
  • Be realized in one or more implementation classes.
  • +
  • Implement the org.apache.catalina.Realm interface. + [Current]
  • +
  • Implement the org.apache.catalina.Lifecycle + interface. [Current]
  • +
  • Subclass the org.apache.catalina.realm.RealmBase + base class.
  • +
  • Live in the org.apache.catalina.realm package. + [Current]
  • +
  • Support a configurable debugging detail level. [Current]
  • +
  • Log debugging and operational messages (suitably internationalized) + via the getContainer().log() method. [Current]
  • +
+ +
+ + +

Dependencies

+ + +

Environmental Dependencies

+ +

The following environmental dependencies must be met in order for + JNDIRealm to operate correctly:

+
    +
  • The desire to utilize JNDIRealm must be registered in + $CATALINA_BASE/conf/server.xml, in a + <Realm> element that is nested inside a + corresponding <Engine>, <Host>, + or <Context> element.
  • +
  • If the Administrator Login operational mode is selected, + the configured administrator username and password must be configured + in the corresponding directory server.
  • +
  • If the Username Login operational mode is selected, + the corresponding directory server must be configured to accept + logins with the username and password that will be passed to + JNDIRealm by the appropriate Authenticator. +
  • +
+ +
+ + +

Container Dependencies

+ +

Correct operation of JNDIRealm depends on the following + specific features of the surrounding container:

+
    +
  • Interactions with JNDIRealm will be initiated by + the appropriate Authenticator implementation, based + on the login method that is selected.
  • +
+ +
+ + +

Functionality

+ + +

Operational Modes

+ +

The completed JNDIRealm must support two major operational + modes in order to support all of the required use cases. For the purposes + of this document, the modes are called administrator login and + Username Login. They are described further in the following + paragraphs.

+ +

For Administrator Login mode, JNDIRealm will be + configured to establish one or more connections (using a connection pool) + to an appropriate directory server, using JNDI APIs, under a "system + administrator" username and password. This is similar to the approach + normally used to configure JDBCRealm to access authentication + and access control information in a database. It is assumed that the + system administrator username and password that are configured provide + sufficient privileges within the directory server to read (but not modify) + the username, password, and assigned roles for each valid user of the + web application associated with this Realm. The password + can be stored in cleartext, or in one of the digested modes supported by + the org.apache.catalina.realm.RealmBase base class.

+ +

For Username Login mode, JNDIRealm does not + normally remain connected to the directory server. Instead, whenever a + user is to be authenticated, a connection to the directory server + (using the username and password received from the authenticator) is + attempted. If this connection is successful, the user is assumed to be + successfully authenticated. This connection is then utilized to read + the corresponding security roles associated with this user, and the + connection is then broken.

+ +

NOTE - Username Login mode cannot be used + if you have selected login method DIGEST in your web + application deployment descriptor (web.xml) file. This + restriction exists because the cleartext password is never available + to the container, so it is not possible to bind to the directory server + using the user's username and password.

+ +

Because these operational modes work so differently, the functionality + for each mode will be described separately. Whether or not both modes + are actually supported by a single class (versus a class per mode) is + an implementation detail left to the designer.

+ +

NOTE - The current implementation only implements + part of the Administrator Lookup mode requirements. It does + not support the Username Lookup mode at all, at this point.

+ +
+ + +

Administrator Login Mode Functionality

+ + +

Configurable Properties

+ +

The implementation shall support the following properties + that can be configured with JavaBeans property setters:

+
    +
  • connectionURL - URL of the directory server we will + be contacting.
  • +
  • contextFactory - Fully qualified class name of the JNDI + context factory used to retrieve our InitialContext. + [com.sun.jndi.ldap.LdapCtxFactory]
  • +
  • Additional configuration properties required to establish the + appropriate connection. [Requested]
  • +
  • Connection pool configuration properties. [Requested]
  • +
  • Configuration properties defining how a particular user is + authenticated. The following capabilities should be supported: +
      +
    • Substitute the specified username into a string. [Requested]
    • +
    • Retrieve the distinguished name (DN) of an authorized user via an + LDAP search string with a replacement placeholder for the + username, and comparison of the password to a configurable + attribute retrieved from the search result. [Current]
    • +
  • +
  • Configuration properties defining how the roles associated with a + particular authenticated user can be retrieved. The following + approaches should be supported: +
      +
    • Retrieve a specified attribute (possibly multi-valued) + from an LDAP search expression, + with a replacement placeholder for the DN of the user. + [Current]
    • +
    • Retrieve a set of role names that are defined implicitly (by + selecting principals that match a search pattern) rather than + explicitly (by finding a particular attribute value). + [Requested]
    • +
  • +
+ +

Lifecycle Functionality

+ +

The following processing must be performed when the start() + method is called:

+
    +
  • Establish a connection to the configured directory server, using the + configured system administrator username and password. [Current]
  • +
  • Configure and establish a connection pool of connections to the + directory server. [Requested]
  • +
+ +

The following processing must be performed when the stop() + method is called:

+
    +
  • Close any opened connections to the directory server.
  • +
+ + +

Method authenticate() Functionality

+ +

When authenticate() is called, the following processing + is required:

+
    +
  • Acquire the one and only connection [Current] or acquire a connection + from the connection pool [Requested].
  • +
  • Authenticate the user by retrieving the user's Distinguished Name, + based on the specified username and password.
  • +
  • If the user was not authenticated, release the allocated connection + and return null.
  • +
  • Acquire a List of the security roles assigned to the + authenticated user.
  • +
  • Construct a new instance of class + org.apache.catalina.realm.GenericPrincipal, passing as + constructor arguments: this realm instance, the authenticated + username, and a List of the security roles associated + with this user.
  • +
  • WARNING - Do not attempt to cache and reuse previous + GenericPrincipal objects for a particular user, because + the information in the directory server might have changed since the + last time this user was authenticated.
  • +
  • Return the newly constructed GenericPrincipal.
  • +
+ + +

Method hasRole() Functionality

+ +

When hasRole() is called, the following processing + is required:

+
    +
  • The principal that is passed as an argument SHOULD + be one that we returned (instanceof class + org.apache.catalina.realm.GenericPrincipal, with a + realm property that is equal to our instance.
  • +
  • If the passed principal meets these criteria, check + the specified role against the list returned by + getRoles(), and return true if the + specified role is included; otherwise, return false.
  • +
  • If the passed principal does not meet these criteria, + return false.
  • +
+ +
+ + +

Username Login Mode Functionality

+ +

Configurable Properties

+ +

The implementation shall support the following properties + that can be configured with JavaBeans property setters:

+
    +
  • connectionURL - URL of the directory server we will + be contacting.
  • +
  • contextFactory - Fully qualified class name of the JNDI + context factory used to retrieve our InitialContext. + [com.sun.jndi.ldap.LdapCtxFactory]
  • +
  • Additional configuration properties required to establish the + appropriate connection. [Requested]
  • +
  • Connection pool configuration properties. [Requested]
  • +
  • Configuration properties defining if and how a user might be looked + up before binding to the directory server. The following approaches + should be supported: +
      +
    • No previous lookup is required - username specified by the user + is the same as that used to authenticate to the directory + server.
    • +
    • Substitute the specified username into a string.
    • +
    • Search the directory server based on configured criteria to + retrieve the distinguished name of the user, then attempt to + bind with that distinguished name.
    • +
  • +
  • Configuration properties defining how the roles associated with a + particular authenticated user can be retrieved. The following + approaches should be supported: +
      +
    • Retrieve a specified attribute (possibly multi-valued) + from an LDAP search expression, + with a replacement placeholder for the DN of the user. + [Current]
    • +
  • +
+ +

Lifecycle Functionality

+ +

The following processing must be performed when the start() + method is called:

+
    +
  • None required.
  • +
+ +

The following processing must be performed when the stop() + method is called:

+
    +
  • None required.
  • +
+ + +

Method authenticate() Functionality

+ +

When authenticate() is called, the following processing + is required:

+
    +
  • Attempt to bind to the directory server, using the username and + password provided by the user.
  • +
  • If the user was not authenticated, release the allocated connection + and return null.
  • +
  • Acquire a List of the security roles assigned to the + authenticated user.
  • +
  • Construct a new instance of class + org.apache.catalina.realm.GenericPrincipal, passing as + constructor arguments: this realm instance, the authenticated + username, and a List of the security roles associated + with this user.
  • +
  • WARNING - Do not attempt to cache and reuse previous + GenericPrincipal objects for a particular user, because + the information in the directory server might have changed since the + last time this user was authenticated.
  • +
  • Return the newly constructed GenericPrincipal.
  • +
+ + +

Method hasRole() Functionality

+ +

When hasRole() is called, the following processing + is required:

+
    +
  • The principal that is passed as an argument SHOULD + be one that we returned (instanceof class + org.apache.catalina.realm.GenericPrincipal, with a + realm property that is equal to our instance.
  • +
  • If the passed principal meets these criteria, check + the specified role against the list returned by + getRoles(), and return true if the + specified role is included; otherwise, return false.
  • +
  • If the passed principal does not meet these criteria, + return false.
  • +
+ +
+ +

Testable Assertions

+ +

In addition to the assertions implied by the functionality requirements + listed above, the following additional assertions shall be tested to + validate the behavior of JNDIRealm:

+
    +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-memory-realm.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-memory-realm.html new file mode 100644 index 0000000..1493f3a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/fs-memory-realm.html @@ -0,0 +1,253 @@ + +Catalina Functional Specifications (8.0.53) - MemoryRealm

MemoryRealm

Table of Contents

Overview

+ + +

Introduction

+ +

The purpose of the MemoryRealm implementation is to + provide a mechanism by which Tomcat can acquire information needed + to authenticate web application users, and define their security roles, + from a simple text-based configuration file in XML format. This is + intended to simplify the initial installation and operation of Tomcat, + without the complexity of configuring a database or directory server + based Realm. It is not intended for production use.

+ +

This specification reflects a combination of functionality that is + already present in the org.apache.catalina.realm.MemoryRealm + class, as well as requirements for enhancements that have been + discussed. Where appropriate, requirements statements are marked + [Current] and [Requested] to distinguish them.

+ +

The current status of this functional specification is + PROPOSED. It has not yet been discussed and + agreed to on the TOMCAT-DEV mailing list.

+ +
+ + +

External Specifications

+ +

The implementation of this functionality depends on the following + external specifications:

+
    +
  • None
  • +
+ +
+ + +

Implementation Requirements

+ +

The implementation of this functionality shall conform to the + following requirements:

+
    +
  • Be realized in one or more implementation classes.
  • +
  • Implement the org.apache.catalina.Realm interface. + [Current]
  • +
  • Implement the org.apache.catalina.Lifecycle + interface. [Current]
  • +
  • Subclass the org.apache.catalina.realm.RealmBase + base class.
  • +
  • Live in the org.apache.catalina.realm package. + [Current]
  • +
  • Support a configurable debugging detail level. [Current]
  • +
  • Log debugging and operational messages (suitably internationalized) + via the getContainer().log() method. [Current]
  • +
+ +
+ + +

Dependencies

+ + +

Environmental Dependencies

+ +

The following environmental dependencies must be met in order for + MemoryRealm to operate correctly:

+
    +
  • The desire to utilize MemoryRealm must be registered in + $CATALINA_BASE/conf/server.xml, in a + <Realm> element that is nested inside a + corresponding <Engine>, <Host>, + or <Context> element. (This is already + included in the default server.xml file.)
  • +
+ +
+ + +

Container Dependencies

+ +

Correct operation of MemoryRealm depends on the following + specific features of the surrounding container:

+
    +
  • Interactions with MemoryRealm will be initiated by + the appropriate Authenticator implementation, based + on the login method that is selected.
  • +
  • MemoryRealm must have an XML parser compatible with + the JAXP/1.1 APIs available to it. This is normally accomplished + by placing the corresponding JAR files in directory + $CATALINA_HOME/lib.
  • +
+ +
+ + +

Functionality

+ + +

Overview of Operation

+ +

The main purpose of MemoryRealm is to allow Catalina to + authenticate users, and look up the corresponding security roles, from + the information found in an XML-format configuration file. The format + of this file is described below. When a MemoryRealm + instance is started, it will read the contents of this XML file and create + an "in memory database" of all the valid users and their associated + security roles.

+ +

Each time that Catalina needs to authenticate a user, it will call + the authenticate() method of this Realm implementation, + passing the username and password that were specified by the user. If + we find the user in the database (and match on the password), we accumulate + all of the security roles that are defined for this user, and create a + new GenericPrincipal object to be returned. If the user + is not authenticated, we return null instead. The + GenericUser object caches the set of security roles that + were owned by this user at the time of authentication, so that calls to + isUserInRole() can be answered without going back to the + database every time.

+ +
+ + +

Detailed Functional Requirements

+ + +

Configurable Properties

+ +

The implementation shall support the following properties + that can be configured with JavaBeans property setters:

+
    +
  • Configurable debugging detail level.
  • +
  • Configurable file pathname (absolute or relative to + $CATALINA_BASE of the XML file containing our + defined users. [conf/tomcat-users.xml].
  • +
+ +

Lifecycle Functionality

+ +

The following processing must be performed when the start() + method is called:

+
    +
  • Open and parse the specified XML file.
  • +
  • Create an in-memory database representation of the XML file + contents.
  • +
  • NOTE - There is no requirement to recognize + subsequent changes to the contents of the XML file.
  • +
+ +

The following processing must be performed when the stop() + method is called:

+
    +
  • Release object references to the in-memory database representation.
  • +
+ + +

Method authenticate() Functionality

+ +

When authenticate() is called, the following processing + is required:

+
    +
  • Select the one and only "user" instance from the in-memory database, + based on matching the specified username. If there is no such + instance, return null.
  • +
  • Authenticate the user by comparing the (possibly encrypted) password + value that was received against the password presented by the user. + If there is no match, return null.
  • +
  • Construct a new instance of class + org.apache.catalina.realm.GenericPrincipal (if not + already using this as the internal database representation) that + contains the authenticated username and a List of the + security roles associated with this user.
  • +
  • Return the newly constructed GenericPrincipal.
  • +
+ + +

Method hasRole() Functionality

+ +

When hasRole() is called, the following processing + is required:

+
    +
  • The principal that is passed as an argument SHOULD + be one that we returned (instanceof class + org.apache.catalina.realm.GenericPrincipal, with a + realm property that is equal to our instance.
  • +
  • If the passed principal meets these criteria, check + the specified role against the list returned by + getRoles(), and return true if the + specified role is included; otherwise, return false.
  • +
  • If the passed principal does not meet these criteria, + return false.
  • +
+ +
+ +

Testable Assertions

+ +

In addition to the assertions implied by the functionality requirements + listed above, the following additional assertions shall be tested to + validate the behavior of MemoryRealm:

+
    +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/index.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/index.html new file mode 100644 index 0000000..424446e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/index.html @@ -0,0 +1,80 @@ + +Catalina Functional Specifications (8.0.53) - Table of Contents

Table of Contents

Catalina Functional Specifications

+ +

This documentation area includes functional specifications for +many features supported by the Catalina servlet container +portion of Tomcat. In most cases, these features are not documented in the +underlying Servlet or JSP specifications, so a definition of the expected +correct behavior is important both to implementors of those features, and to +test writers trying to decide what to test.

+ +

The functional specifications are divided into the following categories +in the menu (to the left):

+
    +
  • Administrative Apps - Overall requirements for supporting an + ability to configure and operate a Tomcat installation through tools, + as well as detailed requirements for the tools themselves.
  • +
  • Internal Servlets - Requirements for Catalina features that are + implemented as internal, container-managed, servlets.
  • +
  • Realm Implementations - Requirements for the implementations of + the org.apache.catalina.Realm interface (providing access to + collections of users, passwords and roles) that are included in the + standard Tomcat distribution.
  • +
+ +

NOTE - In some cases, the contents of these functional specs has +been "reverse engineered" from existing implementations. This exercise is +still useful, because it provides an introduction to what +Catalina does, without being as concerned with how this is +accomplished.

+ +

TODO - Obviously, this area has a long ways to go before +it is complete. Contributions are welcome!

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/funcspecs/mbean-names.html b/test.dockerapp/tomcat/webapps/docs/funcspecs/mbean-names.html new file mode 100644 index 0000000..02cc521 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/funcspecs/mbean-names.html @@ -0,0 +1,710 @@ + +Catalina Functional Specifications (8.0.53) - Tomcat MBean Names

Tomcat MBean Names

Table of Contents

Background

+ +

We will be using JMX MBeans as the technology for + implementing manageability of Tomcat.

+ +

One of the key concepts of JMX is that each management bean has a unique + name in the MBeanServer's registry, and that management applications can + utilize these names to retrieve the MBean of interest to them for a + particular management operation. This document proposes a naming convention + for MBeans that allows easy calculation of the name for a particular MBean. + For background information on JMX MBean names, see the Java Management + Extensions Instrumentation and Agent Specification, version 1.0, + section 6. In particular, we will be discussing the String Representation of + ObjectName instances.

+ +

Catalina Object Hierarchy

+ +

Tomcat's servlet container implementation, called Catalina, can be +represented as a hierarchy of objects that contain references to each other. +The object hierarchy can be represented as a tree, or (isomorphically) based +on the nesting of configuration elements in the conf/server.xml +file that is traditionally used to configure Tomcat stand-alone.

+ +

The valid component nestings for Catalina are depicted in the following +table, with columns that contain the following values:

+
    +
  • Pattern - Nesting pattern of XML elements (in the + conf/server.xml file) used to configure this component.
  • +
  • Cardinality - Minimum and maximum number of occurrences of + this element at this nesting position, which also corresponds to the + minimum and maximum number of Catalina components.
  • +
  • Identifier - Name of the JavaBeans property of this component + that represents the unique identifier (within the nested hierarchy), + if any.
  • +
  • MBean ObjectName - The portion of the MBean object name that + appears after the domain name. For now, it should be + assumed that all of these MBeans appear in the default JMX domain.
  • +
+ +

In the MBean ObjectName descriptions, several types of symbolic +expressions are utilized to define variable text that is replaced by +corresponding values:

+
    +
  • ${GROUP} - One of the standard MBean names of the specified + "group" category. For example, the expression ${REALM} + represents the values like JDBCRealm and JAASRealm + that identify the various MBeans for possible Realm components.
  • +
  • ${name} - Replaced by the value of property name + from the current component.
  • +
  • ${parent.name} - Replaced by the value of property + name from a parent of the current component, with the + parent's type identified by parent.
  • +
  • ${###} - An arbitrary numeric identifier that preserves + order but has no other particular meaning. In general, the server will + assign numeric values to existing instances with large gaps into which + new items can be configured if desired.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PatternCardinalityIdentifierMBean ObjectName
Server1..1(none)type=${SERVER}
Server / Listener0..n(none)type=${LISTENER}, sequence=${###}
Server / Service1..nnametype=${SERVICE}, name=${name}
Server / Service / Connector1..naddress, porttype=${CONNECTOR}, service=${service}, port=${port}, + address=${address}
Server / Service / Connector / Factory0..1(none)(Only defined explicitly for an SSL connector, but can be treated + as part of the connector component)
Server / Service / Connector / Listener0..n(none)type=${LISTENER}, sequence=${###}, service=${service}, + port=${connector.port}, address=${connector.address}
Server / Service / Engine1..1(none)type=${ENGINE}, service=${service.name}
Server / Service / Engine / Host1..nnametype=${HOST}, host=${name}, + service=${service.name}
Server / Service / Engine / Host / Context1..npathtype=${CONTEXT}, context=${name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / InstanceListener0..n(none)type=${INSTANCE-LISTENER}, sequence=${###}, + context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / Listener0..n(none)type=${LISTENER}, sequence=${###}, context=${context.name}, + host=${host.name}, service=${service.name}
Server / Service / Engine / Host / Context / Loader0..1(none)type=${LOADER}, context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / Manager0..1(none)type=${MANAGER}, context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / Realm0..1(none)type=${REALM}, context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / Resources0..1(none)type=${RESOURCES}, context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / Valve0..n(none)type=${VALVE}, sequence=${###}, context=${context.name}, + host=${host.name}, service=${service.name}
Server / Service / Engine / Host / Context / Wrapper0..n(none)j2eeType=Servlet,name=${name}, + WebModule=//${host.name}/${context.name}, + J2EEApplication=${context.J2EEApplication}, + J2EEServer=${context.J2EEServer}
Server / Service / Engine / Host / Context / WrapperLifecycle0..n(none)type=${WRAPPER-LIFECYCLE}, sequence=${###}, + context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Context / WrapperListener0..n(none)type=${WRAPPER-LISTENER}, sequence=${###}, + context=${context.name}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Listener0..n(none)type=${LISTENER}, sequence=${###}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Realm0..1(none)type=${REALM}, host=${host.name}, + service=${service.name}
Server / Service / Engine / Host / Valve0..n(none)type=${VALVE}, sequence=${###}, + host=${host.name}, service=${service.name}
Server / Service / Engine / Listener0..n(none)type=${LISTENER}, sequence=${###} + (FIXME - disambiguate from Server / Service / + Listener)
Server / Service / Engine / Realm0..1(none)type=${REALM}, service=${service.name}
Server / Service / Engine / Valve0..n(none)type=${VALVE}, sequence=${###}, + service=${service.name}
Server / Service / Listener0..n(none)type=${LISTENER}, sequence=${###} + (FIXME - disambiguate from Server / Service / + Engine / Listener)
+ +

MBean Groups and Names

+ +

The following MBean names shall be defined in the resource file +/org/apache/catalina/mbeans/mbeans-descriptors.xml (and +therefore available for use within the Administration/Configuration +web application for Tomcat):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MBean NameGroup NameCatalina InterfaceImplementation Class
AccessLogValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.AccessLogValve
BasicAuthenticatorVALVEorg.apache.catalina.Valveorg.apache.catalina.authenticator.BasicAuthenticator
CertificatesValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.CertificatesValve
ContextConfigLISTENERorg.apache.catalina.LifecycleListenerorg.apache.catalina.startup.ContextConfig
ContextEnvironmentRESOURCESorg.apache.catalina.deploy.ContextEnvironmentorg.apache.catalina.deploy.ContextEnvironment
ContextResourceRESOURCESorg.apache.catalina.deploy.ContextResourceorg.apache.catalina.deploy.ContextResource
ContextResourceLinkRESOURCESorg.apache.catalina.deploy.ContextResourceLinkorg.apache.catalina.deploy.ContextResourceLink
CoyoteConnectorCONNECTORorg.apache.catalina.Connectororg.apache.coyote.tomcat4.CoyoteConnector
DigestAuthenticatorVALVEorg.apache.catalina.Valveorg.apache.catalina.authenticator.DigestAuthenticator
EngineConfigLISTENERorg.apache.catalina.LifecycleListenerorg.apache.catalina.startup.EngineConfig
ErrorReportValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.ErrorReportValve
ErrorDispatcherValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.ErrorDispatcherValve
FormAuthenticatorVALVEorg.apache.catalina.Valveorg.apache.catalina.authenticator.FormAuthenticator
GroupGROUPorg.apache.catalina.Grouporg.apache.catalina.Group
HostConfigLISTENERorg.apache.catalina.LifecycleListenerorg.apache.catalina.startup.HostConfig
HttpConnector10CONNECTORorg.apache.catalina.Connectororg.apache.catalina.connector.http10.HttpConnector
HttpConnector11CONNECTORorg.apache.catalina.Connectororg.apache.catalina.connector.http.HttpConnector
JAASRealmREALMorg.apache.catalina.Realmorg.apache.catalina.realm.JAASRealm
JDBCRealmREALMorg.apache.catalina.Realmorg.apache.catalina.realm.JDBCRealm
JDBCUserDatabaseUSERDATABASEorg.apache.catalina.users.JDBCUserDatabaseorg.apache.catalina.users.JDBCUserDatabase
JNDIRealmREALMorg.apache.catalina.Realmorg.apache.catalina.realm.JNDIRealm
MBeanFactoryorg.apache.catalina.mbeans.MBeanFactory
MemoryRealmREALMorg.apache.catalina.Realmorg.apache.catalina.realm.MemoryRealm
MemoryUserDatabaseUSERDATABASEorg.apache.catalina.users.MemoryUserDatabaseorg.apache.catalina.users.MemoryUserDatabase
NamingContextListenerLISTENERorg.apache.catalina.LifecycleListenerorg.apache.catalina.core.NamingContextListener
NamingResourcesRESOURCESorg.apache.catalina.deploy.NamingResourcesorg.apache.catalina.deploy.NamingResources
NonLoginAuthenticatorVALVEorg.apache.catalina.Valveorg.apache.catalina.authenticator.NonLoginAuthenticator
PersistentManagerMANAGERorg.apache.catalina.Managerorg.apache.catalina.session.PersistentManager
RemoteAddrValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.RemoteAddrValve
RemoteHostValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.RemoteHostValve
RequestDumperValveVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.RequestDumperValve
RoleROLEorg.apache.catalina.Roleorg.apache.catalina.Role
SingleSignOnVALVEorg.apache.catalina.Valveorg.apache.catalina.valves.SingleSignOn
SSLAuthenticatorVALVEorg.apache.catalina.Valveorg.apache.catalina.authenticator.SSLAuthenticator
StandardContextCONTEXTorg.apache.catalina.Contextorg.apache.catalina.core.StandardContext
StandardContextValveVALVEorg.apache.catalina.Valveorg.apache.catalina.core.StandardContextValve
StandardEngineENGINEorg.apache.catalina.Engineorg.apache.catalina.core.StandardEngine
StandardEngineValveVALVEorg.apache.catalina.Valveorg.apache.catalina.core.StandardEngineValve
StandardHostHOSTorg.apache.catalina.Hostorg.apache.catalina.core.StandardHost
StandardHostValveVALVEorg.apache.catalina.Valveorg.apache.catalina.core.StandardHostValve
StandardManagerMANAGERorg.apache.catalina.Managerorg.apache.catalina.session.StandardManager
StandardServerSERVERorg.apache.catalina.Serverorg.apache.catalina.core.StandardServer
StandardServiceSERVICEorg.apache.catalina.Serviceorg.apache.catalina.core.StandardService
StandardWrapperWRAPPERorg.apache.catalina.Wrapperorg.apache.catalina.core.StandardWrapper
StandardWrapperValveVALVEorg.apache.catalina.Valveorg.apache.catalina.core.StandardWrapperValve
UserUSERorg.apache.catalina.Userorg.apache.catalina.User
UserDatabaseRealmREALMorg.apache.catalina.Realmorg.apache.catalina.realm.UserDatabaseRealm
WebappLoaderLOADERorg.apache.catalina.Loaderorg.apache.catalina.loader.WebappLoader
+ +

JSR-88 Cross Reference

+ +

The deployment objects in the JSR-88 API object hierarchy correspond +to the specified MBean names or groups as follows:

+ + + + + + + + + + + + + + + + + + + + + +
JSR-88 API ObjectMBean Name or GroupComments
DeployableObject${CONTEXT}Context deployment info plus the corresponding WAR file
Target${HOST}
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/host-manager-howto.html b/test.dockerapp/tomcat/webapps/docs/host-manager-howto.html new file mode 100644 index 0000000..16afc78 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/host-manager-howto.html @@ -0,0 +1,232 @@ + +Apache Tomcat 8 (8.0.53) - Host Manager App -- Text Interface

Host Manager App -- Text Interface

Table of Contents

Introduction

+

+ The Tomcat Host Manager application enables you to create, + delete, and otherwise manage virtual hosts within Tomcat. This how-to guide + is best accompanied by the following pieces of documentation: +

+
    +
  • + Virtual Hosting How-To for more + information about virtual hosting. +
  • +
  • + The Host Container for more information + about the underlying xml configuration of virtual hosts and description + of attributes. +
  • +
+ +

+ The Tomcat Host Manager application is a part of + Tomcat installation, by default available using the following + context: /host-manager. You can use the host manager in the + following ways: +

+ +
    +
  • + Utilizing the graphical user interface, accessible at: + {server}:{port}/host-manager/html. +
  • +
  • + Utilizing a set of minimal HTTP requests suitable for scripting. + You can access this mode at: + {server}:{port}/host-manager/text. +
  • +
+

+ Both ways enable you to add, remove, start, and stop virtual hosts. Changes + are not persisted to the Tomcat configuraiton files. If you want your + settings to be persistent, you must write them into the server.xml + configuration file manually. For full documentation about the configuration, + see The Host Container. This document focuses + on the text interface. For further information about the graphical + interface, see + Host Manager App -- HTML Interface. +

+

Configuring Manager Application Access

+

The description below uses $CATALINA_HOME to refer the + base Tomcat directory. It is the directory in which you installed + Tomcat, for example C:\tomcat8, or + /usr/share/tomcat8.

+ +

+ The Host Manager application requires a user with one of the following + roles: +

+ +
    +
  • + admin-gui - use this role for the graphical web interface. +
  • +
  • + admin-script - use this role for the scripting web interface. +
  • +
+ +

+ To enable access to the text interface of the Host Manager application, + either grant your Tomcat user the appropriate role, or create a new one with + the correct role. For example, open + ${CATALINA_BASE}/conf/tomcat-users.xml and enter the following: +

+
<user username="test" password="chang3m3N#w" roles="admin-script"/>
+

+ No further settings is needed. When you now access + {server}:{port}/host-manager/text/${COMMAND},you are able to + log in with the created credentials. For example: +

$ curl -u ${USERNAME}:${PASSWORD} http://localhost:8080/host-manager/text/list
+OK - Listed hosts
+localhost:
+

+

+ Note that in case you retreive your users using the + DataSourceRealm, JDBCRealm, or + JNDIRealm mechanism, add the appropriate role in the database + or the directory server respectively. +

+

List of Commands

+

The following commands are supported:

+
    +
  • list
  • +
  • add
  • +
  • remove
  • +
  • start
  • +
  • stop
  • +
+

+ In the following subsections, the username and password is assumed to be + test:test. For your environment, use credentials created in the + previous sections. +

+

List command

+

+ Use the list command to see the available virtual hosts on your + Tomcat instance. +

+

Example command:

+ curl -u test:test http://localhost:8080/host-manager/text/list +

Example response:

+
OK - Listed hosts
+localhost:
+
+

Add command

+

+ Use the add command to add a new virtual host. Parameters used + for the add command: +

+
    +
  • String name: Name of the virtual host. REQUIRED
  • +
  • String aliases: Aliases for your virtual host.
  • +
  • String appBase: Base path for the application that will be + served by this virtual host. Provide relative or absolute path.
  • +
  • Boolean manager: If true, the Manager app is added to the + virtual host. You can access it with the /manager context.
  • +
  • Boolean autoDeploy: If true, Tomcat automatically redeploys + applications placed in the appBase directory.
  • +
  • Boolean deployOnStartup: If true, Tomcat automatically deploys + applications placed in the appBase directory on startup.
  • +
  • Boolean deployXML: If true, the /META-INF/context.xml + file is read and used by Tomcat.
  • +
  • Boolean copyXML: If true, Tomcat copies /META-INF/context.xml + file and uses the original copy regardless of updates to the application's + /META-INF/context.xml file. Available only for + Tomcat 8 and newer.
  • +
+

Example command:

+
curl -u test:test http://localhost:8080/host-manager/text/add?name=www.awesomeserver.com&aliases=awesomeserver.com&appBase/mnt/appDir&deployOnStartup=true
+

Example response:

+
add: Adding host [www.awesomeserver.com]
+
+

Remove command

+

+ Use the remove command to remove a virtual host. Parameters used + for the remove command: +

+
    +
  • String name: Name of the virtual host to be removed. + REQUIRED
  • +
+

Example command:

+
curl -u test:test http://localhost:8080/host-manager/text/remove?name=www.awesomeserver.com
+

Example response:

+
remove: Removing host [www.awesomeserver.com]
+
+

Start command

+

+ Use the start command to start a virtual host. Parameters used + for the start command: +

+
    +
  • String name: Name of the virtual host to be started. + REQUIRED
  • +
+

Example command:

+
curl -u test:test http://localhost:8080/host-manager/text/start?name=www.awesomeserver.com
+

Example response:

+
OK - Host www.awesomeserver.com started
+
+

Stop command

+

+ Use the stop command to stop a virtual host. Parameters used + for the stop command: +

+
    +
  • String name: Name of the virtual host to be stopped. + REQUIRED
  • +
+

Example command:

+
curl -u test:test http://localhost:8080/host-manager/text/stop?name=www.awesomeserver.com
+

Example response:

+
OK - Host www.awesomeserver.com stopped
+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/html-host-manager-howto.html b/test.dockerapp/tomcat/webapps/docs/html-host-manager-howto.html new file mode 100644 index 0000000..a7f7d87 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/html-host-manager-howto.html @@ -0,0 +1,201 @@ + +Apache Tomcat 8 (8.0.53) - Host Manager App -- HTML Interface

Host Manager App -- HTML Interface

Table of Contents

Introduction

+

+ The Tomcat Host Manager application enables you to create, + delete, and otherwise manage virtual hosts within Tomcat. This how-to guide + is best accompanied by the following pieces of documentation: +

+ + +

+ The Tomcat Host Manager application is a part of + Tomcat installation, by default available using the following + context: /host-manager. You can use the host manager in the + following ways: +

+ +
    +
  • + Utilizing the graphical user interface, accessible at: + {server}:{port}/host-manager/html. +
  • +
  • + Utilizing a set of minimal HTTP requests suitable for scripting. + You can access this mode at: + {server}:{port}/host-manager/text. +
  • +
+

+ Both ways enable you to add, remove, start, and stop virtual hosts. + Changes are not persisted to the Tomcat configuraiton files. If you want + your settings to be persistent, you must write them into the + server.xml configuration file manually. For full documentation + about the configuration, see The Host + Container. This document focuses on the HTML interface. For further + information about the graphical interface, see + Host Manager App -- Text Interface. +

+

Configuring Manager Application Access

+

The description below uses $CATALINA_HOME to refer the + base Tomcat directory. It is the directory in which you installed + Tomcat, for example C:\tomcat8, or + /usr/share/tomcat8.

+ +

+ The Host Manager application requires a user with one of the following + roles: +

+ +
    +
  • + admin-gui - use this role for the graphical web interface. +
  • +
  • + admin-script - use this role for the scripting web interface. +
  • +
+ +

+ To enable access to the HTML interface of the Host Manager application, + either grant your Tomcat user the appropriate role, or create a new one with + the correct role. For example, open + ${CATALINA_BASE}/conf/tomcat-users.xml and enter the following: +

+
<user username="test" password="chang3m3N#w" roles="admin-gui"/>
+

+ No further settings is needed. When you now access + {server}:{port}/host-manager/html,you are able to + log in with the created credentials. +

+

+ Note that in case you retreive your users using the + DataSourceRealm, JDBCRealm, or + JNDIRealm mechanism, add the appropriate role in the database + or the directory server respectively. +

+

Interface Description

+

The interface is divided into six sections:

+
    +
  • Message - Displays success and failure messages.
  • +
  • Host Manager - Provides basic Host Manager operations + , like list and help.
  • +
  • Host name - Provides a list of virtual Host Names and + enables you to operate them.
  • +
  • Add Virtual Host - Enables you to add a new Virtual + Host.
  • +
  • Server Information - Information about the Tomcat + server.
  • +
+

Message

+ +

+ Displays information about the success or failure of the last Host Manager + command you performed: +

+
    +
  • Success: OK is displayed + and may be followed by a success message.
  • +
  • Failure: FAIL + is displayed followed by an error message.
  • +
+

+ Note that the console of your Tomcat server may reveal more information + about each command. +

+

Host Manager

+ +

The Host Manager section enables you to:

+
    +
  • List Virtual Hosts - Refresh a list of + currently-configured virtual hosts.
  • +
  • HTML Host Manager Help - A documentation link.
  • +
  • Host Manager Help - A documentation link.
  • +
  • Server Status - A link to the Manager + application. Note that you user must have sufficient permissions to access + the application.
  • +
+

Host Name

+ +

The Host name section contains a list of currently-configured virtual host + names. It enables you to:

+
    +
  • View the host names
  • +
  • View the host name aliases
  • +
  • Perform basic commands, that is start, + stop, and remove.
  • +
+

Add Virtual Host

+ +

The Add Virtual Host section enables you to add a virtual host using a + graphical interface. For a description of each property, see the + Host Manager App -- Text Interface + documentation. Note that any configuration added via this interface is + non-persistent.

+

Server Information

+

+ Provides a basic information about the currently-running Tomcat instance, + the JVM, and the underlying operating system. +

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/html-manager-howto.html b/test.dockerapp/tomcat/webapps/docs/html-manager-howto.html new file mode 100644 index 0000000..e087298 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/html-manager-howto.html @@ -0,0 +1,537 @@ + +Apache Tomcat 8 (8.0.53) - Tomcat Web Application Manager How To

Tomcat Web Application Manager How To

Table of Contents

Introduction

+ +

In many production environments it is very useful to have the capability +to manage your web applications without having to shut down and restart +Tomcat. This document is for the HTML web interface to the web application +manager.

+ +

The interface is divided into six sections:

+
    +
  • Message - Displays success and failure messages.
  • +
  • Manager - General manager operations like list and + help.
  • +
  • Applications - List of web applications and + commands.
  • +
  • Deploy - Deploying web applications.
  • +
  • Diagnostics - Identifying potential problems.
  • +
  • Server Information - Information about the Tomcat + server.
  • +
+ +

Message

+ +

+Displays information about the success or failure of the last web application +manager command you performed. If it succeeded OK is displayed +and may be followed by a success message. If it failed FAIL +is displayed followed by an error message. Common failure messages are +documented below for each command. The complete list of failure messages for +each command can be found in the manager web +application documentation. +

+ +

Manager

+ +

The Manager section has three links:

+
    +
  • List Applications - Redisplay a list of web + applications.
  • +
  • HTML Manager Help - A link to this document.
  • +
  • Manager Help - A link to the comprehensive Manager + App HOW TO.
  • +
+ +

Applications

+ +

The Applications section lists information about all the installed web +applications and provides links for managing them. For each web application +the following is displayed:

+
    +
  • Path - The web application context path.
  • +
  • Display Name - The display name for the web application + if it has one configured in its "web.xml" file.
  • +
  • Running - Whether the web application is running and + available (true), or not running and unavailable (false).
  • +
  • Sessions - The number of active sessions for remote + users of this web application. The number of sessions is a link which + when submitted displays more details about session usage by the web + application in the Message box.
  • +
  • Commands - Lists all commands which can be performed on + the web application. Only those commands which can be performed will be + listed as a link which can be submitted. No commands can be performed on + the manager web application itself. The following commands can be + performed: +
      +
    • Start - Start a web application which had been + stopped.
    • +
    • Stop - Stop a web application which is currently + running and make it unavailable.
    • +
    • Reload - Reload the web application so that new + ".jar" files in /WEB-INF/lib/ or new classes in + /WEB-INF/classes/ can be used.
    • +
    • Undeploy - Stop and then remove this web + application from the server.
    • +
    +
  • +
+ +

Start

+ +

Signal a stopped application to restart, and make itself available again. +Stopping and starting is useful, for example, if the database required by +your application becomes temporarily unavailable. It is usually better to +stop the web application that relies on this database rather than letting +users continuously encounter database exceptions.

+ +

If this command succeeds, you will see a Message like this:

+
OK - Started application at context path /examples
+ +

Otherwise, the Message will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to start the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character, unless you are + referencing the ROOT web application -- in which case the context path + must be a zero-length string.

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified +

    + The path parameter is required. +

    +
  • +
+ +
+ +

Stop

+ +

Signal an existing application to make itself unavailable, but leave it +deployed. Any request that comes in while an application is +stopped will see an HTTP error 404, and this application will show as +"stopped" on a list applications command.

+ +

If this command succeeds, you will see a Message like this:

+
OK - Stopped application at context path /examples
+ +

Otherwise, the Message will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to stop the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character, unless you are + referencing the ROOT web application -- in which case the context path + must be a zero-length string.

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified +

    + The path parameter is required. +

    +
  • +
+ +
+ +

Reload

+ +

Signal an existing application to shut itself down and reload. This can +be useful when the web application context is not reloadable and you have +updated classes or property files in the /WEB-INF/classes +directory or when you have added or updated jar files in the +/WEB-INF/lib directory. +

+

NOTE: The /WEB-INF/web.xml +web application configuration file is not checked on a reload; +the previous web.xml configuration is used. +If you have made changes to your web.xml file you must stop +then start the web application. +

+ +

If this command succeeds, you will see a Message like this:

+

+OK - Reloaded application at context path /examples
+
+ +

Otherwise, the Message will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to restart the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character, unless you are + referencing the ROOT web application -- in which case the context path + must be a zero-length string.

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified +

    The path parameter is required.

    +
  • +
  • Reload not supported on WAR deployed at path /foo +

    Currently, application reloading (to pick up changes to the classes or + web.xml file) is not supported when a web application is + installed directly from a WAR file, which happens when the host is + configured to not unpack WAR files. As it only works when the web + application is installed from an unpacked directory, if you are using + a WAR file, you should undeploy and then deploy + the application again to pick up your changes.

    +
  • +
+ +
+ +

Undeploy

+ +

WARNING - This command will delete the +contents of the web application directory and/or ".war" file if it exists within +the appBase directory (typically "webapps") for this virtual host +. The web application temporary work directory is also deleted. If +you simply want to take an application out of service, you should use the +/stop command instead.

+ +

Signal an existing application to gracefully shut itself down, and then +remove it from Tomcat (which also makes this context path available for +reuse later). This command is the logical opposite of the +/deploy Ant command, and the related deploy features available +in the HTML manager.

+ +

If this command succeeds, you will see a Message like this:

+
OK - Undeployed application at context path /examples
+ +

Otherwise, the Message will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to undeploy the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character, unless you are + referencing the ROOT web application -- in which case the context path + must be a zero-length string.

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified + The path parameter is required. +
  • +
+ +
+ +

Deploy

+ +

Web applications can be deployed using files or directories located +on the Tomcat server or you can upload a web application archive (WAR) +file to the server.

+ +

To install an application, fill in the appropriate fields for the type +of install you want to do and then submit it using the Install +button.

+ +

Deploy directory or WAR file located on server

+ +

Deploy and start a new web application, attached to the specified Context +Path: (which must not be in use by any other web application). +This command is the logical opposite of the Undeploy command.

+ +

There are a number of different ways the deploy command can be used.

+ +

Deploy a Directory or WAR by URL

+ +

Install a web application directory or ".war" file located on the Tomcat +server. If no Context Path is specified, the directory name or the +war file name without the ".war" extension is used as the path. The +WAR or Directory URL specifies a URL (including the file: +scheme) for either a directory or a web application archive (WAR) file. The +supported syntax for a URL referring to a WAR file is described on the Javadocs +page for the java.net.JarURLConnection class. Use only URLs that +refer to the entire WAR file.

+ +

In this example the web application located in the directory +C:\path\to\foo on the Tomcat server (running on Windows) +is deployed as the web application context named /footoo.

+
Context Path: /footoo
+WAR or Directory URL: file:C:/path/to/foo
+
+ + +

In this example the ".war" file /path/to/bar.war on the +Tomcat server (running on Unix) is deployed as the web application +context named /bar. Notice that there is no path +parameter so the context path defaults to the name of the web application +archive file without the ".war" extension.

+
WAR or Directory URL: jar:file:/path/to/bar.war!/
+ +
+ +

Deploy a Directory or War from the Host appBase

+ +

Install a web application directory or ".war" file located in your Host +appBase directory. If no Context Path is specified the directory name +or the war file name without the ".war" extension is used as the path.

+ +

In this example the web application located in a subdirectory named +foo in the Host appBase directory of the Tomcat server is +deployed as the web application context named /foo. Notice +that there is no path parameter so the context path defaults +to the name of the web application directory.

+
WAR or Directory URL: foo
+ + +

In this example the ".war" file bar.war located in your +Host appBase directory on the Tomcat server is deployed as the web +application context named /bartoo.

+
Context Path: /bartoo
+WAR or Directory URL: bar.war
+ +
+ +

Deploy using a Context configuration ".xml" file

+ +

If the Host deployXML flag is set to true, you can install a web +application using a Context configuration ".xml" file and an optional +".war" file or web application directory. The Context Path +is not used when installing a web application using a context ".xml" +configuration file.

+ +

A Context configuration ".xml" file can contain valid XML for a +web application Context just as if it were configured in your +Tomcat server.xml configuration file. Here is an +example for Tomcat running on Windows:

+
<Context path="/foobar" docBase="C:\path\to\application\foobar">
+</Context>
+ + +

Use of the WAR or Directory URL is optional. When used +to select a web application ".war" file or directory it overrides any +docBase configured in the context configuration ".xml" file.

+ +

Here is an example of installing an application using a Context +configuration ".xml" file for Tomcat running on Windows.

+
XML Configuration file URL: file:C:/path/to/context.xml
+ + +

Here is an example of installing an application using a Context +configuration ".xml" file and a web application ".war" file located +on the server (Tomcat running on Unix).

+
XML Configuration file URL: file:/path/to/context.xml
+WAR or Directory URL: jar:file:/path/to/bar.war!/
+ +
+
+ +

Upload a WAR file to install

+ +

Upload a WAR file from your local system and install it into the +appBase for your Host. The name of the WAR file without the ".war" +extension is used as the context path name.

+ +

Use the Browse button to select a WAR file to upload to the +server from your local desktop system.

+ +

The .WAR file may include Tomcat specific deployment configuration, by +including a Context configuration XML file in +/META-INF/context.xml.

+ +

Upload of a WAR file could fail for the following reasons:

+
    +
  • File uploaded must be a .war +

    The upload install will only accept files which have the filename + extension of ".war".

    +
  • +
  • War file already exists on server +

    If a war file of the same name already exists in your Host's + appBase the upload will fail. Either undeploy the existing war file + from your Host's appBase or upload the new war file using a different + name.

    +
  • +
  • File upload failed, no file +

    The file upload failed, no file was received by the server.

    +
  • +
  • Install Upload Failed, Exception: +

    The war file upload or install failed with a Java Exception. + The exception message will be listed.

    +
  • +
+ +
+ +

Deployment Notes

+ +

If the Host is configured with unpackWARs=true and you install a war +file, the war will be unpacked into a directory in your Host appBase +directory.

+ +

If the application war or directory is deployed in your Host appBase +directory and either the Host is configured with autoDeploy=true the Context +path must match the directory name or war file name without the ".war" +extension.

+ +

For security when untrusted users can manage web applications, the +Host deployXML flag can be set to false. This prevents untrusted users +from installing web applications using a configuration XML file and +also prevents them from installing application directories or ".war" +files located outside of their Host appBase.

+ +
+ +

Deploy Message

+ +

If deployment and startup is successful, you will receive a Message +like this:

+
OK - Deployed application at context path /foo
+ +

Otherwise, the Message will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Application already exists at path /foo +

    The context paths for all currently running web applications must be + unique. Therefore, you must either undeploy the existing web + application using this context path, or choose a different context path + for the new one.

    +
  • +
  • Document base does not exist or is not a readable directory +

    The URL specified by the WAR or Directory URL: field must + identify a directory on this server that contains the "unpacked" version + of a web application, or the absolute URL of a web application archive + (WAR) file that contains this application. Correct the value entered for + the WAR or Directory URL: field.

    +
  • +
  • Encountered exception +

    An exception was encountered trying to start the new web application. + Check the Tomcat logs for the details, but likely explanations include + problems parsing your /WEB-INF/web.xml file, or missing + classes encountered when initializing application event listeners and + filters.

    +
  • +
  • Invalid application URL was specified +

    The URL for the WAR or Directory URL: field that you specified + was not valid. Such URLs must start with file:, and URLs + for a WAR file must end in ".war".

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character, unless you are + referencing the ROOT web application -- in which case the context path + must be a "/" string.

    +
  • +
  • Context path must match the directory or WAR file name: +

    If the application war or directory is deployed in your Host appBase + directory and either the Host is configured with autoDeploy=true the Context + path must match the directory name or war file name without the ".war" + extension.

    +
  • +
  • Only web applications in the Host web application directory can + be deployed +

    + If the Host deployXML flag is set to false this error will happen + if an attempt is made to install a web application directory or + ".war" file outside of the Host appBase directory. +

  • +
+ +
+

Diagnostics

+ +

Finding memory leaks

+ +

The find leaks diagnostic triggers a full garbage collection. It +should be used with extreme caution on production systems.

+ +

The find leaks diagnostic attempts to identify web applications that have +caused memory leaks when they were stopped, reloaded or undeployed. Results +should always be confirmed +with a profiler. The diagnostic uses additional functionality provided by the +StandardHost implementation. It will not work if a custom host is used that +does not extend StandardHost.

+ +

This diagnostic will list context paths for the web applications that were +stopped, reloaded or undeployed, but which classes from the previous runs +are still present in memory, thus being a memory leak. If an application +has been reloaded several times, it may be listed several times.

+ +

Explicitly triggering a full garbage collection from Java code is documented +to be unreliable. Furthermore, depending on the JVM used, there are options to +disable explicit GC triggering, like -XX:+DisableExplicitGC. +If you want to make sure, that the diagnostics were successfully running a full GC, +you will need to check using tools like GC logging, JConsole or similar.

+ +
+

Server Information

+ +

This section displays information about Tomcat, the operating system of the +server Tomcat is hosted on, the Java Virtual Machine Tomcat is running in, the +primary host name of the server (may not be the host name used to access Tomcat) +and the primary IP address of the server (may not be the IP address used to +access Tomcat).

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/images/add.gif b/test.dockerapp/tomcat/webapps/docs/images/add.gif new file mode 100644 index 0000000000000000000000000000000000000000..0774d074e5e48291bdacfacb086506e6be117e51 GIT binary patch literal 1037 zcmZ?wbhEHb6k!lyc+SA^9|->a|M&0T|Nno1n4h0tnTz4o;>0&glV!LWO;{KX^ykTP zGrU;!o~1phVTD*cK_!)em>kR#mn&Z^0eO_xlSoe_rhTdU2{GAH%zidEYmsygkrvrz1CG(e()%elNK2f9s9cY)lOA zFHHY+vFYoj2~vCv9}m?1K3M+d$V54A1}%N3>6>p)KJ;Ph^-o+33=fX46z69#)mMIU zX`LuPvyQH3L))$XdH+|R`pLj3#K*_?|NDPF1}|^fSwWhMt)w~)6|3?yj#iYvY3u#U zz+k?5_Z0?4&i}vuGc&jbXzljryOSdOKilYUx!k$z`*f|fsunnK;giFW)5K{fr5eq4b7~gYAGEP z7#KS_xkU;zCM1>#7e(d>$#qP^BWE~tBtO4mJmGb}q literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/asf-logo.svg b/test.dockerapp/tomcat/webapps/docs/images/asf-logo.svg new file mode 100644 index 0000000..e24cbe5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/images/asf-logo.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/docs/images/code.gif b/test.dockerapp/tomcat/webapps/docs/images/code.gif new file mode 100644 index 0000000000000000000000000000000000000000..d27307b5c09467c2e45bbfcd1ff74989eb2e7d65 GIT binary patch literal 394 zcmZ?wbhEHb6k!lySjxcg|NsAg|Na>m7<~Bf;lYCk`uh5YhK2_Y90&`0TwMGlHulx| z^XKp1zrTO~{%OFIr0wCGk>*L_#l_fx07^78uf_y0eALxXeY&ZVS$tf_gsW5<=_ z#~&LR{Wx~~@qq*T{{8>o&~U}u`>TV)%Z7#qKR>_t`1lhio=8gm&d$CqCiY|X>Z2Pr zZ1DH@->~lav}tGl|Nm=XU^H>*6ylK%0}z1x!oarPp`pM-N2)dikZ=q-8iKhfFV&ot-Z?#bsK$q(mDRr`$3(c`=?^VUbBf3LBO?F*3FB z2rH&5?cP|btfH!>&Z(iPC8xdDk6A}sSMT=aD<1m#3{1+}>>KXh^JOqF2nv4n;e)*V JgAa}j)&TJ-upR&a literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/cors-flowchart.png b/test.dockerapp/tomcat/webapps/docs/images/cors-flowchart.png new file mode 100644 index 0000000000000000000000000000000000000000..9abb09d1c7fee7ed73d8d4bbccbff6876aeb378b GIT binary patch literal 86555 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 VKDgrEutEa=bhHh$$~0`l{|B@zSO5S3 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/design.gif b/test.dockerapp/tomcat/webapps/docs/images/design.gif new file mode 100644 index 0000000000000000000000000000000000000000..f5db0a9fc783924486176ce157924fba53df73fc GIT binary patch literal 608 zcmZ?wbhEHb6k!lyIL5&6|NsAgK=A*+y}iAiot?eCt%HMuEs*J8ujLw+y7Ptq{{K!J zf7q}4X0-UF?)+zRlW&T4U*v2)!e6yXwRo0{SJEe-5&!>cxrG=mdLiwZn4h0tkeBaZ zXTN^^`uFeOe|Y!)!-o&&&!6AFfB%LJ8x|~BuzKPA|Ns7#x-xkKyruV1%sHz7ZzCM7sKSh-eh--RQa&hK1ucJ=HF%O;;& z(71m>$AyWdcbfMc+`Vw!lBw%v)-7nyom8CNS*TU6fAIXF^#?X=1X{Rn{hEX8E?l^< zY2Dfj=YX!b$S}x&4#+*AxL{yE+Q87%#Ms=-#MIW++}hp8(Az(WfqCjw7G_pfW;S+? zK29!f9$r3v0YM>Q5mB)&afwAsB$uyTEw!$TO?uDXeKN9r%yRNakI5@2C^8>9BCn*Z zBB!dVrgo-TU7hjpQ4LKkZEYR#ysImZEe>aVg^r Vos(-!G%qcgJt^mrj0gvVH2@9_)ye<> literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/docs-stylesheet.css b/test.dockerapp/tomcat/webapps/docs/images/docs-stylesheet.css new file mode 100644 index 0000000..768e2ed --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/images/docs-stylesheet.css @@ -0,0 +1,303 @@ +@charset "utf-8"; +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +*/ + +/* Fonts */ +@import url("fonts/fonts.css"); + +/* General style */ + +h1, h2, h3, h4, h5, h6, th { + font-weight: 600; +} + +body { + margin: 0; +} + +body, input { + font-family: 'Open Sans', sans-serif; + font-size: 10.5pt; +} + +code, pre { + font-family: Consolas, monospace; +} + +img { + border: 0; +} + +table { + border-collapse: collapse; + text-align: left; +} +table *:not(table) { + /* Prevent border-collapsing for table child elements like

*/ + border-collapse: separate; +} + +th { + text-align: left; +} + +main { + /* Remove this once all IEs support
element */ + display: block; +} + + +/* Layout */ + +#wrapper { + min-width: 400px; +} + +#header { + border-bottom: 1px solid #bbb; +} + +@media not print { + #header { + box-shadow: 0 0 7px #aaa; + } +} + +#header > div { + padding-left: 15px; + padding-right: 15px; + + /* Work-around for old browsers: */ + background-color: #F8F3E4; + background: linear-gradient(to bottom, #ffffff -10%, #F8F3E4 100%); + position: relative; +} + +#header .logo { + float: left; + padding-top: 10px; + min-width: 190px; +} + +#header .logo img{ + /* To avoid that the Font Descender being added to the parent div's height */ + vertical-align: middle; +} + +#header .asfLogo { + float: right; + position: relative; + top: 8px; +} + +#header h1 { + margin-top: 0.6em; + margin-bottom: 0; +} + +#header .versionInfo { + font-size: 13pt; + margin-bottom: 1em; +} + +#middle { + display: table; + table-layout: fixed; + margin: 0; + width: 100%; +} +#middle > div { display: table-row; } +#middle > div > div { display: table-cell; vertical-align: top; } + + + +#mainLeft { + width: 190px; +} + +#mainLeft > div { + margin-top: -1px; /* to overwrite border of element above */ + padding-left: 16px; + padding-right: 14px; + padding-top: 6px; + padding-bottom: 15px; + background-color: #F8F3E4; + border-right: 1px solid #bbb; + border-bottom: 1px solid #bbb; + font-size: 10pt; + border-bottom-right-radius: 20px; + box-shadow: 0 0 5px #aaa; +} + +#mainLeft h2 { + margin-bottom: 0.2em; + font-size: 1.2em; +} + +#mainLeft ul { + padding: 0; + margin: 0; + list-style-type: none; +} + +#mainLeft ul a { + text-indent: -0.6em; + padding-left: 1.4em; + display: block; + text-decoration: none; + color: #444; +} +#mainLeft ul a:hover { + color: #000; + background-color: #D1c9b9; +} + +#mainRight { + padding-left: 14px; + padding-right: 20px; + +} + +#footer { + margin-top: 30px; + padding-top: 20px; + padding-bottom: 20px; + padding-left: 20px; + padding-right: 20px; + border-top: 1px solid #ccc; + color: #444; + text-align: center; + /* font-style: italic; */ + font-size: 9pt; +} + + +/* Content */ + +#content div.text { + padding-left: 1em; + padding-left: 1em; +} + +#content h3, #content h4, #content h5, #content h6 { + padding-left: 5px; + padding-right: 5px; + background-color: #eaeaea; +} + +@media not print { + #content h3, #content h4, #content h5, #content h6 { + border: 1px solid #ccc; + border-radius: 4px; + } +} + +#content h4, #content h5, #content h6 { + background-color: #f6f6f6; +} + +code { + background-color: rgb(224,255,255); +} + +div.codeBox pre code, code.attributeName, code.propertyName, code.noHighlight, .noHighlight code { + background-color: transparent; +} +div.codeBox { + overflow: auto; + margin: 1em 0; +} +div.codeBox pre { + margin: 0; + padding: 4px; + border: 1px solid #999; + border-radius: 5px; + background-color: #eff8ff; + display: table; /* To prevent
s from taking the complete available width. */
+  /*
+  When it is officially supported, use the following CSS instead of display: table
+  to prevent big 
s from exceeding the browser window:
+  max-width: available;
+  width: min-content;
+  */
+}
+
+div.codeBox pre.wrap {
+  white-space: pre-wrap;
+}
+
+
+table.defaultTable tr, table.detail-table tr {
+    border: 1px solid #CCC;
+}
+
+table.defaultTable tr:nth-child(even), table.detail-table tr:nth-child(even) {
+    background-color: #FAFBFF;
+}
+
+table.defaultTable tr:nth-child(odd), table.detail-table tr:nth-child(odd) {
+    background-color: #EEEFFF;
+}
+
+table.defaultTable th, table.detail-table th {
+  background-color: #88b;
+  color: #fff;
+}
+
+table.defaultTable th, table.defaultTable td, table.detail-table th, table.detail-table td {
+  padding: 5px 8px;
+}
+
+
+p.notice {
+  border: 1px solid rgb(255, 0, 0);
+  background-color: rgb(238, 238, 238);
+  color: rgb(0, 51, 102);
+  padding: 0.5em;
+  margin: 1em 2em 1em 1em;
+}
+
+
+/* Changelog-Styles */
+
+ul.changelog {
+  padding-left: 1em;
+  list-style-type: none;
+}
+
+ul.changelog  li{
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+
+ul.changelog img {
+  vertical-align: middle
+}
+
+
+/* Printer-only Styles */
+@media print {
+    .noPrint { display: none; }
+    #middle > div > div#mainLeft { display: none; }
+    a { color: inherit; text-decoration: none; }
+}
+
+/* Fix for Comments section which contains a 

*/ +#comments_thread h1, #comments_thread h2, #comments_thread h3, #comments_thread h4, #comments_thread h5, #comments_thread h6 { + border: none; + background-color: transparent; +} \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/images/docs.gif b/test.dockerapp/tomcat/webapps/docs/images/docs.gif new file mode 100644 index 0000000000000000000000000000000000000000..d64a4a18c405e2c10ab791363f9f7acd16f3d433 GIT binary patch literal 261 zcmZ?wbhEHb6k!lyXklRZ|NsBLfBy^&3_g7L@ZiA%eSLjHL&F0H4xB%K{{H>@`}gm^ zaN)w=|Nrz24bGiAckjXd0|)l~`~Sb8p~273FFrp0;lqa;Hf-?s_kVc*!TptFK^W zYAveoFcA_K5zXln5UZ$U78jG4CN@JuQj&p5NQ}L2!9raIDJdi4wVO8!3NGHP$Y2cs DYrJfE literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/fix.gif b/test.dockerapp/tomcat/webapps/docs/images/fix.gif new file mode 100644 index 0000000000000000000000000000000000000000..d59ad642ba46c0bc1af17ebd2485722e92d6c70e GIT binary patch literal 345 zcmZ?wbhEHb6k!lySjxcg|NsAg|NhCz$;r#h*Vot2pFe-Xgb57|4F?V!*sx)Pf`Wp- zzyHC52YafE7nQ{H_?deNa@Yt7|Ns5_|Np=BjScHJZqShyb`oKj>}~Xa{jy+g9z6-E ze;_me7)uCF^D_FsZh9ae>;K=s{^BeQRBRf^&21nd@qhh{Kt8trzduj* zHV)$93F2e56B6$9w|uc@qp`Ti|35%m2ml=hAOQJ=fvwJ=K|nx4s{h22qR1Gdx!wm8 zv|72?TbvF$Sny2pWe}U_A+XHvXu`zQIrE#HnF2E`LX!mA98j7>H; OF){5sba63^6 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans400.woff b/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans400.woff new file mode 100644 index 0000000000000000000000000000000000000000..55b25f867099eb26c436b1c9fecff14a51290d46 GIT binary patch literal 21956 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 V`l^D1+v7dzXWE*Ozus}S{{vS5Z1n&D literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans400italic.woff b/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans400italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..cedefb8f6ff406c6b77e75ae55ee88e2bd88dc17 GIT binary patch literal 21092 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 F;UD<^W={YB literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans600.woff b/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans600.woff new file mode 100644 index 0000000000000000000000000000000000000000..e83bb333d2ea4655120d1791947d19d28ac710bc GIT binary patch literal 22604 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 IY-b(*0efB24gdfE literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans700.woff b/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans700.woff new file mode 100644 index 0000000000000000000000000000000000000000..27619e7cea1c29f9d71567b78470fdd705c174dc GIT binary patch literal 22748 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans700italic.woff b/test.dockerapp/tomcat/webapps/docs/images/fonts/OpenSans700italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..e12c3a9f273c2f0e4952293bb852406c2ab1eb0a GIT binary patch literal 21184 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 E05v70Bme*a literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/tomcat.gif b/test.dockerapp/tomcat/webapps/docs/images/tomcat.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6f863e43e3924a35854c556a9c1b6d125cba GIT binary patch literal 2066 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/docs/images/tomcat.png b/test.dockerapp/tomcat/webapps/docs/images/tomcat.png new file mode 100644 index 0000000000000000000000000000000000000000..209b07fd8a8d2429b1a0c9740dc184f803ba3c67 GIT binary patch literal 5103 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 + + + + + + + + + + + + + + + + + + + + + + + + + + 2006-05-09T08:17:21Z + 2006-05-09T08:37:38Z + Illustrator + + + + JPEG + 256 + 184 + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA +AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK +DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f +Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAuAEAAwER +AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA +AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB +UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE +1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ +qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy +obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp +0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo ++DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 +FXYq7FXYq7FXYq7FXYq7FXhH/OYHnWfQ/wAurfRLSUxXXmK49GQqaN9VtwJJqH3cxqfYnFXhP5Y/ +85O+f/JU0enaw769okbBJLS8ZvrUKg0IhnarDj/I9R2HHFX2F+Xn5neT/P8ApP6R8u3glKAfW7KS +iXNuzdFljqaezCqnsTirK8VdirsVdirsVdirsVdirC/zM/Nvyd+XemC71255Xcqk2WmQUa5nI2+F +CRxUd3ag+nbFXx1+Zf8Azkn+YvneaW1tLh9C0NgwXTrB2V3Sm/rzji8m3UDitP2cVfV//OOfmabz +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 + + + + + + + image/svg+xml + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +/Dn4G1vgFa2715u9zrn+L1T7Dxc= + + + TM + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/images/update.gif b/test.dockerapp/tomcat/webapps/docs/images/update.gif new file mode 100644 index 0000000000000000000000000000000000000000..31e22abbc7a2e24b20b978e9be9bce91d4d97728 GIT binary patch literal 627 zcmZ?wbhEHb6k!lyIL5&6|NsAgK=A*+y}iAiot?eCt%HMuEs*J8ujLw+y7Ptq{{K!J zf7q}4X0-UF?)+zRlW&T4U*v2)!e6yXwRo0{SJEe-5&!>cxrG=mdLiwZn4h0tkeBaZ zXTN^^`uFeOe|Y!)!-o&&&!6AFfB%LJ8x|~BprD}e|KI zixKbaBa2L3t=6qucmCpq-3N9pT)$}Y+DUZ_>hmV#r_`iKsYvtb2q@R8MedK$FEQlQ z=a5vD+;`!~rt>?OoLxQp!m`Qd7Budkz+leWabaTVo#u#BStWN`r`%g8s3p4R;O>R% zmP}nYvu;6q?xf=E&O#{_89^-(t#bYP8*L_qrri462hSf`e_+E#pd0tCUvqFBkFL=A zvs*7*xUgy6+SLo^E6dAWI0y8^MUY>q3UnBN02CJt>^B-1nwl7!o0*u}x|& +Apache Tomcat 8 (8.0.53) - Documentation Index

Documentation Index

Introduction

+ +

This is the top-level entry point of the documentation bundle for the +Apache Tomcat Servlet/JSP container. Apache Tomcat version +8.0 implements the Servlet 3.1 and JavaServer Pages 2.3 +specifications from the +Java Community Process, and includes many +additional features that make it a useful platform for developing and deploying +web applications and web services.

+ +

Select one of the links from the navigation menu (to the left) to drill +down to the more detailed documentation that is available. Each available +manual is described in more detail below.

+ +

Apache Tomcat User Guide

+ +

The following documents will assist you in downloading and installing +Apache Tomcat, and using many of the Apache Tomcat features.

+ +
    +
  1. Introduction - A + brief, high level, overview of Apache Tomcat.
  2. +
  3. Setup - How to install and run + Apache Tomcat on a variety of platforms.
  4. +
  5. First web application + - An introduction to the concepts of a web application as defined + in the Servlet Specification. Covers basic organization of your web application + source tree, the structure of a web application archive, and an + introduction to the web application deployment descriptor + (/WEB-INF/web.xml).
  6. +
  7. Deployer - + Operating the Apache Tomcat Deployer to deploy, precompile, and validate web + applications.
  8. +
  9. Manager - + Operating the Manager web app to deploy, undeploy, and + redeploy applications while Apache Tomcat is running.
  10. +
  11. Host Manager - + Operating the Host Manager web app to add and remove + virtual hosts while Apache Tomcat is running.
  12. +
  13. Realms and Access Control + - Description of how to configure Realms (databases of users, + passwords, and their associated roles) for use in web applications that + utilize Container Managed Security.
  14. +
  15. Security Manager + - Configuring and using a Java Security Manager to + support fine-grained control over the behavior of your web applications. +
  16. +
  17. JNDI Resources + - Configuring standard and custom resources in the JNDI naming context + that is provided to each web application.
  18. +
  19. + JDBC DataSource + - Configuring a JNDI DataSource with a DB connection pool. + Examples for many popular databases.
  20. +
  21. Classloading + - Information about class loading in Apache Tomcat, including where to place + your application classes so that they are visible.
  22. +
  23. JSPs + - Information about Jasper configuration, as well as the JSP compiler + usage.
  24. +
  25. SSL/TLS - + Installing and configuring SSL/TLS support so that your Apache Tomcat will + serve requests using the https protocol.
  26. +
  27. SSI - + Using Server Side Includes in Apache Tomcat.
  28. +
  29. CGI - + Using CGIs with Apache Tomcat.
  30. +
  31. Proxy Support - + Configuring Apache Tomcat to run behind a proxy server (or a web server + functioning as a proxy server).
  32. +
  33. MBeans Descriptors - + Configuring MBean descriptors files for custom components.
  34. +
  35. Default Servlet - + Configuring the default servlet and customizing directory listings.
  36. +
  37. Apache Tomcat Clustering - + Enable session replication in a Apache Tomcat environment.
  38. +
  39. Balancer - + Configuring, using, and extending the load balancer application.
  40. +
  41. Connectors - + Connectors available in Apache Tomcat, and native web server integration.
  42. +
  43. Monitoring and Management - + Enabling JMX Remote support, and using tools to monitor and manage Apache Tomcat.
  44. +
  45. Logging - + Configuring logging in Apache Tomcat.
  46. +
  47. Apache Portable Runtime - + Using APR to provide superior performance, scalability and better + integration with native server technologies.
  48. +
  49. Virtual Hosting - + Configuring virtual hosting in Apache Tomcat.
  50. +
  51. Advanced IO - + Extensions available over regular, blocking IO.
  52. +
  53. Additional Components - + Obtaining additional, optional components.
  54. +
  55. Using Tomcat libraries with Maven - + Obtaining Tomcat jars through Maven.
  56. +
  57. Security Considerations - + Options to consider when securing an Apache Tomcat installation.
  58. +
  59. Windows Service - + Running Tomcat as a service on Microsoft Windows.
  60. +
  61. Windows Authentication - + Configuring Tomcat to use integrated Windows authentication.
  62. +
  63. High Concurrency JDBC Pool - + Configuring Tomcat to use an alternative JDBC pool.
  64. +
  65. WebSocket support - + Developing WebSocket applications for Apache Tomcat.
  66. +
  67. URL rewrite - + Using the regexp based rewrite valve for conditional URL and host rewrite.
  68. + +
+ +

Reference

+ +

The following documents are aimed at System Administrators who +are responsible for installing, configuring, and operating an Apache Tomcat server. +

+ + +

Apache Tomcat Developers

+ +

The following documents are for Java developers who wish to contribute to +the development of the Apache Tomcat project.

+
    +
  • Building from Source - + Details the steps necessary to download Apache Tomcat source code (and the + other packages that it depends on), and build a binary distribution from + those sources. +
  • +
  • Changelog - Details the + changes made to Apache Tomcat. +
  • +
  • Status - + Apache Tomcat development status. +
  • +
  • Developers - List of active + Apache Tomcat contributors. +
  • +
  • Functional Specifications + - Requirements specifications for features of the Catalina servlet + container portion of Apache Tomcat.
  • +
  • Javadocs + - Javadoc API documentation for Apache Tomcat's internals.
  • +
  • Apache Tomcat Architecture + - Documentation of the Apache Tomcat Server Architecture.
  • +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/introduction.html b/test.dockerapp/tomcat/webapps/docs/introduction.html new file mode 100644 index 0000000..0553150 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/introduction.html @@ -0,0 +1,147 @@ + +Apache Tomcat 8 (8.0.53) - Introduction

Introduction

Table of Contents

Introduction

+ +

For administrators and web developers alike, there are some important bits +of information you should familiarize yourself with before starting out. This +document serves as a brief introduction to some of the concepts and +terminology behind the Tomcat container. As well, where to go when you need +help.

+ +

Terminology

+ +

In the course of reading these documents, you will run across a number of +terms; some specific to Tomcat, and others defined by the +Servlet and +JSP specifications.

+ +
    +
  • Context - In a nutshell, a Context is a + web application.
  • +
+

That is it. If you find any more terms we need to add to this section, please +do let us know.

+ +

Directories and Files

+ +

Throughout the docs, you'll notice there are numerous references to +$CATALINA_HOME. This represents the root of your Tomcat +installation. When we say, "This information can be found in your +$CATALINA_HOME/README.txt file" we mean to look at the README.txt file at the +root of your Tomcat install. Optionally, Tomcat may be configured for multiple +instances by defining $CATALINA_BASE for each instance. If +multiple instances are not configured, $CATALINA_BASE is the +same as $CATALINA_HOME.

+ +

These are some of the key tomcat directories:

+ +
    +
  • /bin - Startup, shutdown, and other scripts. The + *.sh files (for Unix systems) are functional duplicates of + the *.bat files (for Windows systems). Since the Win32 + command-line lacks certain functionality, there are some additional + files in here.
  • +
  • /conf - Configuration files and related DTDs. The most + important file in here is server.xml. It is the main configuration file + for the container.
  • +
  • /logs - Log files are here by default.
  • +
  • /webapps - This is where your webapps go.
  • +
+ +

Configuring Tomcat

+ +

This section will acquaint you with the basic information used during +the configuration of the container.

+ +

All of the information in the configuration files is read at startup, +meaning that any change to the files necessitates a restart of the container. +

+ +

Where to Go for Help

+ +

While we've done our best to ensure that these documents are clearly +written and easy to understand, we may have missed something. Provided +below are various web sites and mailing lists in case you get stuck.

+ +

Keep in mind that some of the issues and solutions vary between the +major versions of Tomcat. As you search around the web, there will be +some documentation that is not relevant to Tomcat 8, but +only to earlier versions.

+ +
    +
  • Current document - most documents will list potential hangups. Be sure + to fully read the relevant documentation as it will save you much time + and effort. There's nothing like scouring the web only to find out that + the answer was right in front of you all along!
  • +
  • Tomcat FAQ
  • +
  • Tomcat WIKI
  • +
  • Tomcat FAQ at jGuru
  • +
  • Tomcat mailing list archives - numerous sites archive the Tomcat mailing + lists. Since the links change over time, clicking here will search + Google. +
  • +
  • The TOMCAT-USER mailing list, which you can subscribe to + here. If you don't + get a reply, then there's a good chance that your question was probably + answered in the list archives or one of the FAQs. Although questions + about web application development in general are sometimes asked and + answered, please focus your questions on Tomcat-specific issues.
  • +
  • The TOMCAT-DEV mailing list, which you can subscribe to + here. This list is + reserved for discussions about the development of Tomcat + itself. Questions about Tomcat configuration, and the problems you run + into while developing and running applications, will normally be more + appropriate on the TOMCAT-USER list instead.
  • +
+ +

And, if you think something should be in the docs, by all means let us know +on the TOMCAT-DEV list.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/jasper-howto.html b/test.dockerapp/tomcat/webapps/docs/jasper-howto.html new file mode 100644 index 0000000..711f9cd --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/jasper-howto.html @@ -0,0 +1,411 @@ + +Apache Tomcat 8 (8.0.53) - Jasper 2 JSP Engine How To

Jasper 2 JSP Engine How To

Table of Contents

Introduction

+ +

Tomcat 8.0 uses the Jasper 2 JSP Engine to implement +the JavaServer Pages 2.3 +specification.

+ +

Jasper 2 has been redesigned to significantly improve performance over +the original Jasper. In addition to general code improvements the following +changes were made:

+
    +
  • JSP Custom Tag Pooling - The java objects instantiated +for JSP Custom Tags can now be pooled and reused. This significantly boosts +the performance of JSP pages which use custom tags.
  • +
  • Background JSP compilation - If you make a change to +a JSP page which had already been compiled Jasper 2 can recompile that +page in the background. The previously compiled JSP page will still be +available to serve requests. Once the new page has been compiled +successfully it will replace the old page. This helps improve availability +of your JSP pages on a production server.
  • +
  • Recompile JSP when included page changes - Jasper 2 +can now detect when a page included at compile time from a JSP has changed +and then recompile the parent JSP.
  • +
  • JDT used to compile JSP pages - The +Eclipse JDT Java compiler is now used to perform JSP java source code +compilation. This compiler loads source dependencies from the container +classloader. Ant and javac can still be used.
  • +
+ + +

Jasper is implemented using the servlet class +org.apache.jasper.servlet.JspServlet.

+ +

Configuration

+ +

By default Jasper is configured for use when doing web application +development. See the section +Production Configuration for information on configuring Jasper +for use on a production Tomcat server.

+ +

The servlet which implements Jasper is configured using init parameters +in your global $CATALINA_BASE/conf/web.xml. +

+
    +
  • checkInterval - If development is false and checkInterval +is greater than zero, background compiles are enabled. checkInterval is the time +in seconds between checks to see if a JSP page (and its dependent files) needs +to be recompiled. Default 0 seconds.
  • + +
  • classdebuginfo - Should the class file be compiled with +debugging information? true or false, default +true. +
  • + +
  • classpath - Defines the class path to be used to compile +the generated servlets. This parameter only has an effect if the ServletContext +attribute org.apache.jasper.Constants.SERVLET_CLASSPATH is not set. This +attribute is always set when Jasper is used within Tomcat. By default the +classpath is created dynamically based on the current web application.
  • + +
  • compiler - Which compiler Ant should use to compile JSP +pages. The valid values for this are the same as for the compiler attribute of +Ant's +javac +task. If the value is not set, then the default Eclipse JDT Java compiler will +be used instead of using Ant. There is no default value. If this attribute is +set then setenv.[sh|bat] should be used to add +ant.jar, ant-launcher.jar and tools.jar +to the CLASSPATH environment variable.
  • + +
  • compilerSourceVM - What JDK version are the source files +compatible with? (Default value: 1.7)
  • + +
  • compilerTargetVM - What JDK version are the generated files +compatible with? (Default value: 1.7)
  • + +
  • development - Is Jasper used in development mode? If true, +the frequency at which JSPs are checked for modification may be specified via +the modificationTestInterval parameter.true or false, +default true.
  • + +
  • displaySourceFragment - Should a source fragment be +included in exception messages? true or false, +default true.
  • + +
  • dumpSmap - Should the SMAP info for JSR45 debugging be +dumped to a file? true or false, default +false. false if suppressSmap is true.
  • + +
  • enablePooling - Determines whether tag handler pooling is +enabled. This is a compilation option. It will not alter the behaviour of JSPs +that have already been compiled. true or false, +default true. +
  • + +
  • engineOptionsClass - Allows specifying the Options class +used to configure Jasper. If not present, the default EmbeddedServletOptions +will be used. This option is ignored if running under a SecurityManager. +
  • + +
  • errorOnUseBeanInvalidClassAttribute - Should Jasper issue +an error when the value of the class attribute in an useBean action is not a +valid bean class? true or false, default +true.
  • + +
  • fork - Have Ant fork JSP page compiles so they are +performed in a separate JVM from Tomcat? true or +false, default true.
  • + +
  • genStringAsCharArray - Should text strings be generated as char +arrays, to improve performance in some cases? Default false.
  • + +
  • ieClassId - The class-id value to be sent to Internet +Explorer when using <jsp:plugin> tags. Default +clsid:8AD9C840-044E-11D1-B3E9-00805F499D93.
  • + +
  • javaEncoding - Java file encoding to use for generating +java source files. Default UTF8.
  • + +
  • keepgenerated - Should we keep the generated Java source +code for each page instead of deleting it? true or +false, default true.
  • + +
  • mappedfile - Should we generate static content with one +print statement per input line, to ease debugging? +true or false, default true.
  • + +
  • maxLoadedJsps - The maximum number of JSPs that will be +loaded for a web application. If more than this number of JSPs are loaded, the +least recently used JSPs will be unloaded so that the number of JSPs loaded at +any one time does not exceed this limit. A value of zero or less indicates no +limit. Default -1
  • + +
  • jspIdleTimeout - The amount of time in seconds a JSP can be +idle before it is unloaded. A value of zero or less indicates never unload. +Default -1
  • + +
  • modificationTestInterval - Causes a JSP (and its dependent +files) to not be checked for modification during the specified time interval +(in seconds) from the last time the JSP was checked for modification. A value of +0 will cause the JSP to be checked on every access. Used in development mode +only. Default is 4 seconds.
  • + +
  • recompileOnFail - If a JSP compilation fails should the +modificationTestInterval be ignored and the next access trigger a re-compilation +attempt? Used in development mode only and is disabled by default as compilation +may be expensive and could lead to excessive resource usage.
  • + +
  • scratchdir - What scratch directory should we use when +compiling JSP pages? Default is the work directory for the current web +application. This option is ignored if running under a SecurityManager.
  • + +
  • suppressSmap - Should the generation of SMAP info for JSR45 +debugging be suppressed? true or false, default +false.
  • + +
  • trimSpaces - Should template text that consists entirely of +whitespace be removed? true or false, default +false.
  • + +
  • xpoweredBy - Determines whether X-Powered-By response +header is added by generated servlet. true or false, +default false.
  • + +
  • strictQuoteEscaping - When scriptlet expressions are used +for attribute values, should the rules in JSP.1.6 for the escaping of quote +characters be strictly applied? true or false, default +true which can be changed with the +org.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING system +property.
  • + +
  • quoteAttributeEL - When EL is used in an attribute value +on a JSP page, should the rules for quoting of attributes described in JSP.1.6 +be applied to the expression? true or false, default +true.
  • +
+ +

The Java compiler from Eclipse JDT in included as the default compiler. It is +an advanced Java compiler which will load all dependencies from the Tomcat class +loader, which will help tremendously when compiling on large installations with +tens of JARs. On fast servers, this will allow sub-second recompilation cycles +for even large JSP pages.

+ +

Apache Ant, which was used in previous Tomcat releases, can be used instead +of the new compiler by configuring the compiler attribute as explained above. +

+ +

Known issues

+ +

As described in + +bug 39089, a known JVM issue, + +bug 6294277, may cause a +java.lang.InternalError: name is too long to represent exception +when compiling very large JSPs. If this is observed then it may be worked around +by using one of the following: +

+
    +
  • reduce the size of the JSP
  • +
  • disable SMAP generation and JSR-045 support by setting +suppressSmap to true.
  • +
+ +

Production Configuration

+ +

The main JSP optimization which can be done is precompilation of JSPs. +However, this might not be possible (for example, when using the +jsp-property-group feature) or practical, in which case the configuration of the +Jasper servlet becomes critical.

+ +

When using Jasper 2 in a production Tomcat server you should consider making +the following changes from the default configuration.

+
    +
  • development - To disable on access checks for JSP +pages compilation set this to false.
  • +
  • genStringAsCharArray - To generate slightly more efficient +char arrays, set this to true.
  • +
  • modificationTestInterval - If development has to be set to +true for any reason (such as dynamic generation of JSPs), setting +this to a high value will improve performance a lot.
  • +
  • trimSpaces - To remove useless bytes from the response, +set this to true.
  • +
+ +

Web Application Compilation

+ +

Using Ant is the preferred way to compile web applications using JSPC. Note +that when pre-compiling JSPs, SMAP information will only be included in the +final classes if suppressSmap is false and compile is true. +Use the script given below (a similar script is included in the "deployer" +download) to precompile a webapp: +

+ +
<project name="Webapp Precompilation" default="all" basedir=".">
+
+   <import file="${tomcat.home}/bin/catalina-tasks.xml"/>
+
+   <target name="jspc">
+
+    <jasper
+             validateXml="false"
+             uriroot="${webapp.path}"
+             webXmlFragment="${webapp.path}/WEB-INF/generated_web.xml"
+             outputDir="${webapp.path}/WEB-INF/src" />
+
+  </target>
+
+  <target name="compile">
+
+    <mkdir dir="${webapp.path}/WEB-INF/classes"/>
+    <mkdir dir="${webapp.path}/WEB-INF/lib"/>
+
+    <javac destdir="${webapp.path}/WEB-INF/classes"
+           optimize="off"
+           debug="on" failonerror="false"
+           srcdir="${webapp.path}/WEB-INF/src"
+           excludes="**/*.smap">
+      <classpath>
+        <pathelement location="${webapp.path}/WEB-INF/classes"/>
+        <fileset dir="${webapp.path}/WEB-INF/lib">
+          <include name="*.jar"/>
+        </fileset>
+        <pathelement location="${tomcat.home}/lib"/>
+        <fileset dir="${tomcat.home}/lib">
+          <include name="*.jar"/>
+        </fileset>
+        <fileset dir="${tomcat.home}/bin">
+          <include name="*.jar"/>
+        </fileset>
+      </classpath>
+      <include name="**" />
+      <exclude name="tags/**" />
+    </javac>
+
+  </target>
+
+  <target name="all" depends="jspc,compile">
+  </target>
+
+  <target name="cleanup">
+    <delete>
+        <fileset dir="${webapp.path}/WEB-INF/src"/>
+        <fileset dir="${webapp.path}/WEB-INF/classes/org/apache/jsp"/>
+    </delete>
+  </target>
+
+</project>
+ +

+The following command line can be used to run the script +(replacing the tokens with the Tomcat base path and the path to the webapp +which should be precompiled): +

+
$ANT_HOME/bin/ant -Dtomcat.home=<$TOMCAT_HOME> -Dwebapp.path=<$WEBAPP_PATH>
+ + +

+Then, the declarations and mappings for the servlets which were generated +during the precompilation must be added to the web application deployment +descriptor. Insert the ${webapp.path}/WEB-INF/generated_web.xml +at the right place inside the ${webapp.path}/WEB-INF/web.xml file. +Restart the web application (using the manager) and test it to verify it is +running fine with precompiled servlets. An appropriate token placed in the +web application deployment descriptor may also be used to automatically +insert the generated servlet declarations and mappings using Ant filtering +capabilities. This is actually how all the webapps distributed with Tomcat +are automatically compiled as part of the build process. +

+ +

+At the jasper task you can use the option addWebXmlMappings for +automatic merge the ${webapp.path}/WEB-INF/generated_web.xml +with the current web application deployment descriptor at +${webapp.path}/WEB-INF/web.xml. When you want to use Java 6 +features inside your jsp's, add the following javac compiler task attributes: +source="1.6" target="1.6". For live +applications you can also compile with optimize="on" and +without debug info debug="off". +

+ +

+When you don't want to stop the jsp generation at first jsp syntax error, use +failOnError="false"and with +showSuccess="true" all successful jsp to java +generation are printed out. Sometimes it is very helpful, when you cleanup the +generate java source files at ${webapp.path}/WEB-INF/src +and the compile jsp servlet classes at +${webapp.path}/WEB-INF/classes/org/apache/jsp. +

+ +

Hints:

+
    +
  • When you switch to another Tomcat release, then regenerate and recompile +your jsp's with the new Tomcat version.
  • +
  • Use java system property at server runtime to disable PageContext pooling +org.apache.jasper.runtime.JspFactoryImpl.USE_POOL=false. +and limit the buffering with +org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true. Note +that changing from the defaults may affect performance, but it will vary +depending on the application.
  • +
+

Optimisation

+

+There are a number of extension points provided within Jasper that enable the +user to optimise the behaviour for their environment. +

+ +

+The first of these extension points is the tag plug-in mechanism. This allows +alternative implementations of tag handlers to be provided for a web application +to use. Tag plug-ins are registered via a tagPlugins.xml file +located under WEB-INF. A sample plug-in for the JSTL is included +with Jasper. +

+ +

+The second extension point is the Expression Language interpreter. Alternative +interpreters may be configured through the ServletContext. See the +ELInterpreterFactory javadoc for details of how to configure an +alternative EL interpreter. +

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/jdbc-pool.html b/test.dockerapp/tomcat/webapps/docs/jdbc-pool.html new file mode 100644 index 0000000..8cd7804 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/jdbc-pool.html @@ -0,0 +1,929 @@ + +Apache Tomcat 8 (8.0.53) - The Tomcat JDBC Connection Pool

The Tomcat JDBC Connection Pool

Table of Contents

Introduction

+ +

The JDBC Connection Pool org.apache.tomcat.jdbc.pool + is a replacement or an alternative to the Apache Commons DBCP + connection pool.

+ +

So why do we need a new connection pool?

+ +

Here are a few of the reasons:

+
    +
  1. Commons DBCP 1.x is single threaded. In order to be thread safe + Commons locks the entire pool for short periods during both object + allocation and object return. Note that this does not apply to + Commons DBCP 2.x.
  2. +
  3. Commons DBCP 1.x can be slow. As the number of logical CPUs grows and + the number of concurrent threads attempting to borrow or return + objects increases, the performance suffers. For highly concurrent + systems the impact can be significant. Note that this does not apply + to Commons DBCP 2.x.
  4. +
  5. Commons DBCP is over 60 classes. tomcat-jdbc-pool core is 8 classes, + hence modifications for future requirement will require much less + changes. This is all you need to run the connection pool itself, the + rest is gravy.
  6. +
  7. Commons DBCP uses static interfaces. This means you have to use the + right version for a given JRE version or you may see + NoSuchMethodException exceptions.
  8. +
  9. It's not worth rewriting over 60 classes, when a connection pool can + be accomplished with a much simpler implementation.
  10. +
  11. Tomcat jdbc pool implements the ability retrieve a connection + asynchronously, without adding additional threads to the library + itself.
  12. +
  13. Tomcat jdbc pool is a Tomcat module, it depends on Tomcat JULI, a + simplified logging framework used in Tomcat.
  14. +
  15. Retrieve the underlying connection using the + javax.sql.PooledConnection interface.
  16. +
  17. Starvation proof. If a pool is empty, and threads are waiting for a + connection, when a connection is returned, the pool will awake the + correct thread waiting. Most pools will simply starve.
  18. +
+ +

Features added over other connection pool implementations

+
    +
  1. Support for highly concurrent environments and multi core/cpu systems.
  2. +
  3. Dynamic implementation of interface, will support java.sql and javax.sql interfaces for + your runtime environment (as long as your JDBC driver does the same), even when compiled with a lower version of the JDK.
  4. +
  5. Validation intervals - we don't have to validate every single time we use the connection, we can do this + when we borrow or return the connection, just not more frequent than an interval we can configure.
  6. +
  7. Run-Once query, a configurable query that will be run only once, when the connection to the database is established. + Very useful to setup session settings, that you want to exist during the entire time the connection is established.
  8. +
  9. Ability to configure custom interceptors. + This allows you to write custom interceptors to enhance the functionality. You can use interceptors to gather query stats, + cache session states, reconnect the connection upon failures, retry queries, cache query results, and so on. + Your options are endless and the interceptors are dynamic, not tied to a JDK version of a + java.sql/javax.sql interface.
  10. +
  11. High performance - we will show some differences in performance later on
  12. +
  13. Extremely simple, due to the very simplified implementation, the line count and source file count are very low, compare with c3p0 + that has over 200 source files(last time we checked), Tomcat jdbc has a core of 8 files, the connection pool itself is about half + that. As bugs may occur, they will be faster to track down, and easier to fix. Complexity reduction has been a focus from inception.
  14. +
  15. Asynchronous connection retrieval - you can queue your request for a connection and receive a Future<Connection> back.
  16. +
  17. Better idle connection handling. Instead of closing connections directly, it can still pool connections and sizes the idle pool with a smarter algorithm.
  18. +
  19. You can decide at what moment connections are considered abandoned, is it when the pool is full, or directly at a timeout + by specifying a pool usage threshold. +
  20. +
  21. The abandon connection timer will reset upon a statement/query activity. Allowing a connections that is in use for a long time to not timeout. + This is achieved using the ResetAbandonedTimer +
  22. +
  23. Close connections after they have been connected for a certain time. Age based close upon return to the pool. +
  24. +
  25. Get JMX notifications and log entries when connections are suspected for being abandoned. This is similar to + the removeAbandonedTimeout but it doesn't take any action, only reports the information. + This is achieved using the suspectTimeout attribute.
  26. +
  27. Connections can be retrieved from a java.sql.Driver, javax.sql.DataSource or javax.sql.XADataSource + This is achieved using the dataSource and dataSourceJNDI attributes.
  28. +
  29. XA connection support
  30. +
+ + +

How to use

+

+ Usage of the Tomcat connection pool has been made to be as simple as possible, for those of you that are familiar with commons-dbcp, the + transition will be very simple. Moving from other connection pools is also fairly straight forward. +

+

Additional features

+

The Tomcat connection pool offers a few additional features over what most other pools let you do:

+
    +
  • initSQL - the ability to run a SQL statement exactly once, when the connection is created
  • +
  • validationInterval - in addition to running validations on connections, avoid running them too frequently.
  • +
  • jdbcInterceptors - flexible and pluggable interceptors to create any customizations around the pool, + the query execution and the result set handling. More on this in the advanced section.
  • +
  • fairQueue - Set the fair flag to true to achieve thread fairness or to use asynchronous connection retrieval
  • +
+
+

Inside the Apache Tomcat Container

+

+ The Tomcat Connection pool is configured as a resource described in The Tomcat JDBC documentation + With the only difference being that you have to specify the factory attribute and set the value to + org.apache.tomcat.jdbc.pool.DataSourceFactory +

+
+

Standalone

+

+ The connection pool only has another dependency, and that is on tomcat-juli.jar. + To configure the pool in a stand alone project using bean instantiation, the bean to instantiate is + org.apache.tomcat.jdbc.pool.DataSource. The same attributes (documented below) as you use to configure a connection + pool as a JNDI resource, are used to configure a data source as a bean. +

+
+

JMX

+

+ The connection pool object exposes an MBean that can be registered. + In order for the connection pool object to create the MBean, the flag jmxEnabled has to be set to true. + This doesn't imply that the pool will be registered with an MBean server, merely that the MBean is created. + In a container like Tomcat, Tomcat itself registers the DataSource with the MBean server, the + org.apache.tomcat.jdbc.pool.DataSource object will then register the actual + connection pool MBean. + If you're running outside of a container, you can register the DataSource yourself under any object name you specify, + and it propagates the registration to the underlying pool. To do this you would call mBeanServer.registerMBean(dataSource.getPool().getJmxPool(),objectname). + Prior to this call, ensure that the pool has been created by calling dataSource.createPool(). +

+
+ +

Attributes

+

To provide a very simple switch to and from commons-dbcp and tomcat-jdbc-pool, + Most attributes are the same and have the same meaning.

+

JNDI Factory and Type

+
+ Attribute + + Description +
factory +

factory is required, and the value should be org.apache.tomcat.jdbc.pool.DataSourceFactory

+
type +

Type should always be javax.sql.DataSource or javax.sql.XADataSource

+

Depending on the type a org.apache.tomcat.jdbc.pool.DataSource or a org.apache.tomcat.jdbc.pool.XADataSource will be created.

+
+
+ +

System Properties

+

System properties are JVM wide, affect all pools created in the JVM

+
+ Attribute + + Description +
org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader +

(boolean) Controls classloading of dynamic classes, such as + JDBC drivers, interceptors and validators. If set to + false, default value, the pool will first attempt + to load using the current loader (i.e. the class loader that + loaded the pool classes) and if class loading fails attempt to + load using the thread context loader. Set this value to + true, if you wish to remain backwards compatible + with Apache Tomcat 8.0.8 and earlier, and only attempt the + current loader. + If not set then the default value is false. +

+
+
+ +

Common Attributes

+

These attributes are shared between commons-dbcp and tomcat-jdbc-pool, in some cases default values are different.

+
+ Attribute + + Description +
defaultAutoCommit +

(boolean) The default auto-commit state of connections created by this pool. If not set, default is JDBC driver default (If not set then the setAutoCommit method will not be called.)

+
defaultReadOnly +

(boolean) The default read-only state of connections created by this pool. If not set then the setReadOnly method will not be called. (Some drivers don't support read only mode, ex: Informix)

+
defaultTransactionIsolation +

(String) The default TransactionIsolation state of connections created by this pool. One of the following: (see javadoc )

+
    +
  • NONE
  • +
  • READ_COMMITTED
  • +
  • READ_UNCOMMITTED
  • +
  • REPEATABLE_READ
  • +
  • SERIALIZABLE
  • +
+

If not set, the method will not be called and it defaults to the JDBC driver.

+
defaultCatalog +

(String) The default catalog of connections created by this pool.

+
driverClassName +

(String) The fully qualified Java class name of the JDBC driver to be used. The driver has to be accessible + from the same classloader as tomcat-jdbc.jar +

+
username +

(String) The connection username to be passed to our JDBC driver to establish a connection. + Note that method DataSource.getConnection(username,password) + by default will not use credentials passed into the method, + but will use the ones configured here. See alternateUsernameAllowed + property for more details. +

+
password +

(String) The connection password to be passed to our JDBC driver to establish a connection. + Note that method DataSource.getConnection(username,password) + by default will not use credentials passed into the method, + but will use the ones configured here. See alternateUsernameAllowed + property for more details. +

+
maxActive +

(int) The maximum number of active connections that can be allocated from this pool at the same time. + The default value is 100

+
maxIdle +

(int) The maximum number of connections that should be kept in the pool at all times. + Default value is maxActive:100 + Idle connections are checked periodically (if enabled) and + connections that been idle for longer than minEvictableIdleTimeMillis + will be released. (also see testWhileIdle)

+
minIdle +

+ (int) The minimum number of established connections that should be kept in the pool at all times. + The connection pool can shrink below this number if validation queries fail. + Default value is derived from initialSize:10 (also see testWhileIdle) +

+
initialSize +

(int)The initial number of connections that are created when the pool is started. + Default value is 10

+
maxWait +

(int) The maximum number of milliseconds that the pool will wait (when there are no available connections) + for a connection to be returned before throwing an exception. + Default value is 30000 (30 seconds)

+
testOnBorrow +

(boolean) The indication of whether objects will be validated before being borrowed from the pool. + If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another. + In order to have a more efficient validation, see validationInterval. + Default value is false +

+
testOnConnect +

(boolean) The indication of whether objects will be validated when a connection is first created. + If an object fails to validate, it will be throw SQLException. + Default value is false +

+
testOnReturn +

(boolean) The indication of whether objects will be validated before being returned to the pool. + The default value is false. +

+
testWhileIdle +

(boolean) The indication of whether objects will be validated by the idle object evictor (if any). + If an object fails to validate, it will be dropped from the pool. + The default value is false and this property has to be set in order for the + pool cleaner/test thread is to run (also see timeBetweenEvictionRunsMillis) +

+
validationQuery +

(String) The SQL query that will be used to validate connections from this pool before returning them to the caller. + If specified, this query does not have to return any data, it just can't throw a SQLException. + The default value is null. + If not specified, connections will be validation by the isValid() method. + Example values are SELECT 1(mysql), select 1 from dual(oracle), SELECT 1(MS Sql Server) +

+
validationQueryTimeout +

(int) The timeout in seconds before a connection validation queries fail. This works by calling + java.sql.Statement.setQueryTimeout(seconds) on the statement that executes the validationQuery. + The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts. + A value less than or equal to zero will disable this feature. + The default value is -1. +

+
validatorClassName +

(String) The name of a class which implements the + org.apache.tomcat.jdbc.pool.Validator interface and + provides a no-arg constructor (may be implicit). If specified, the + class will be used to create a Validator instance which is then used + instead of any validation query to validate connections. The default + value is null. An example value is + com.mycompany.project.SimpleValidator. +

+
timeBetweenEvictionRunsMillis +

(int) The number of milliseconds to sleep between runs of the idle connection validation/cleaner thread. + This value should not be set under 1 second. It dictates how often we check for idle, abandoned connections, and how often + we validate idle connections. + The default value is 5000 (5 seconds).
+

+
numTestsPerEvictionRun +

(int) Property not used in tomcat-jdbc-pool.

+
minEvictableIdleTimeMillis +

(int) The minimum amount of time an object may sit idle in the pool before it is eligible for eviction. + The default value is 60000 (60 seconds).

+
accessToUnderlyingConnectionAllowed +

(boolean) Property not used. Access can be achieved by calling unwrap on the pooled connection. + see javax.sql.DataSource interface, or call getConnection through reflection or + cast the object as javax.sql.PooledConnection

+
removeAbandoned +

(boolean) Flag to remove abandoned connections if they exceed the removeAbandonedTimeout. + If set to true a connection is considered abandoned and eligible for removal if it has been in use + longer than the removeAbandonedTimeout Setting this to true can recover db connections from + applications that fail to close a connection. See also logAbandoned + The default value is false.

+
removeAbandonedTimeout +

(int) Timeout in seconds before an abandoned(in use) connection can be removed. + The default value is 60 (60 seconds). The value should be set to the longest running query your applications + might have.

+
logAbandoned +

(boolean) Flag to log stack traces for application code which abandoned a Connection. + Logging of abandoned Connections adds overhead for every Connection borrow because a stack trace has to be generated. + The default value is false.

+
connectionProperties +

(String) The connection properties that will be sent to our JDBC driver when establishing new connections. + Format of the string must be [propertyName=property;]* + NOTE - The "user" and "password" properties will be passed explicitly, so they do not need to be included here. + The default value is null.

+
poolPreparedStatements +

(boolean) Property not used.

+
maxOpenPreparedStatements +

(int) Property not used.

+
+ +
+ +

Tomcat JDBC Enhanced Attributes

+ +
+ Attribute + + Description +
initSQL +

(String) A custom query to be run when a connection is first created. + The default value is null.

+
jdbcInterceptors +

(String) A semicolon separated list of classnames extending + org.apache.tomcat.jdbc.pool.JdbcInterceptor class. + See Configuring JDBC interceptors + below for more detailed description of syntax and examples. +

+

+ These interceptors will be inserted as an interceptor into the chain + of operations on a java.sql.Connection object. + The default value is null. +

+

+ Predefined interceptors:
+ org.apache.tomcat.jdbc.pool.interceptor.
ConnectionState
+ - keeps track of auto commit, read only, catalog and transaction isolation level.
+ org.apache.tomcat.jdbc.pool.interceptor.
StatementFinalizer
+ - keeps track of opened statements, and closes them when the connection is returned to the pool. +

+

+ More predefined interceptors are described in detail in the + JDBC Interceptors section. +

+
validationInterval +

(long) avoid excess validation, only run validation at most at this frequency - time in milliseconds. + If a connection is due for validation, but has been validated previously within this interval, it will not be validated again. + The default value is 3000 (3 seconds).

+
jmxEnabled +

(boolean) Register the pool with JMX or not. + The default value is true.

+
fairQueue +

(boolean) Set to true if you wish that calls to getConnection should be treated + fairly in a true FIFO fashion. This uses the org.apache.tomcat.jdbc.pool.FairBlockingQueue + implementation for the list of the idle connections. The default value is true. + This flag is required when you want to use asynchronous connection retrieval.
+ Setting this flag ensures that threads receive connections in the order they arrive.
+ During performance tests, there is a very large difference in how locks + and lock waiting is implemented. When fairQueue=true + there is a decision making process based on what operating system the system is running. + If the system is running on Linux (property os.name=Linux. + To disable this Linux specific behavior and still use the fair queue, simply add the property + org.apache.tomcat.jdbc.pool.FairBlockingQueue.ignoreOS=true to your system properties + before the connection pool classes are loaded. +

+
abandonWhenPercentageFull +

(int) Connections that have been abandoned (timed out) wont get closed and reported up unless + the number of connections in use are above the percentage defined by abandonWhenPercentageFull. + The value should be between 0-100. + The default value is 0, which implies that connections are eligible for closure as soon + as removeAbandonedTimeout has been reached.

+
maxAge +

(long) Time in milliseconds to keep this connection. This attribute + works both when returning connection and when borrowing connection. + When a connection is borrowed from the pool, the pool will check to see + if the now - time-when-connected > maxAge has been reached + , and if so, it reconnects before borrow it. When a connection is + returned to the pool, the pool will check to see if the + now - time-when-connected > maxAge has been reached, and + if so, it closes the connection rather than returning it to the pool. + The default value is 0, which implies that connections + will be left open and no age check will be done upon borrowing from the + pool and returning the connection to the pool.

+
useEquals +

(boolean) Set to true if you wish the ProxyConnection class to use String.equals and set to false + when you wish to use == when comparing method names. This property does not apply to added interceptors as those are configured individually. + The default value is true. +

+
suspectTimeout +

(int) Timeout value in seconds. Default value is 0.
+ Similar to to the removeAbandonedTimeout value but instead of treating the connection + as abandoned, and potentially closing the connection, this simply logs the warning if + logAbandoned is set to true. If this value is equal or less than 0, no suspect + checking will be performed. Suspect checking only takes place if the timeout value is larger than 0 and + the connection was not abandoned or if abandon check is disabled. If a connection is suspect a WARN message gets + logged and a JMX notification gets sent once. +

+
rollbackOnReturn +

(boolean) If autoCommit==false then the pool can terminate the transaction by calling rollback on the connection as it is returned to the pool + Default value is false.
+

+
commitOnReturn +

(boolean) If autoCommit==false then the pool can complete the transaction by calling commit on the connection as it is returned to the pool + If rollbackOnReturn==true then this attribute is ignored. + Default value is false.
+

+
alternateUsernameAllowed +

(boolean) By default, the jdbc-pool will ignore the + DataSource.getConnection(username,password) + call, and simply return a previously pooled connection under the globally configured properties username and password, for performance reasons. +

+

+ The pool can however be configured to allow use of different credentials + each time a connection is requested. To enable the functionality described in the + DataSource.getConnection(username,password) + call, simply set the property alternateUsernameAllowed + to true.
+ Should you request a connection with the credentials user1/password1 and the connection + was previously connected using different user2/password2, the connection will be closed, + and reopened with the requested credentials. This way, the pool size is still managed + on a global level, and not on a per schema level.
+ The default value is false.
+ This property was added as an enhancement to bug 50025. +

+
dataSource +

(javax.sql.DataSource) Inject a data source to the connection pool, and the pool will use the data source to retrieve connections instead of establishing them using the java.sql.Driver interface. + This is useful when you wish to pool XA connections or connections established using a data source instead of a connection string. Default value is null +

+
dataSourceJNDI +

(String) The JNDI name for a data source to be looked up in JNDI and then used to establish connections to the database. See the dataSource attribute. Default value is null +

+
useDisposableConnectionFacade +

(boolean) Set this to true if you wish to put a facade on your connection so that it cannot be reused after it has been closed. This prevents a thread holding on to a + reference of a connection it has already called closed on, to execute queries on it. Default value is true. +

+
logValidationErrors +

(boolean) Set this to true to log errors during the validation phase to the log file. If set to true, errors will be logged as SEVERE. Default value is false for backwards compatibility. +

+
propagateInterruptState +

(boolean) Set this to true to propagate the interrupt state for a thread that has been interrupted (not clearing the interrupt state). Default value is false for backwards compatibility. +

+
ignoreExceptionOnPreLoad +

(boolean) Flag whether ignore error of connection creation while initializing the pool. + Set to true if you want to ignore error of connection creation while initializing the pool. + Set to false if you want to fail the initialization of the pool by throwing exception. + The default value is false. +

+
useStatementFacade +

(boolean) Set this to true if you wish to wrap statements in order to + enable equals() and hashCode() methods to be + called on the closed statements if any statement proxy is set. + Default value is true. +

+
+
+

Advanced usage

+

JDBC interceptors

+

To see an example of how to use an interceptor, take a look at + org.apache.tomcat.jdbc.pool.interceptor.ConnectionState. + This simple interceptor is a cache of three attributes, transaction isolation level, auto commit and read only state, + in order for the system to avoid not needed roundtrips to the database. +

+

Further interceptors will be added to the core of the pool as the need arises. Contributions are always welcome!

+

Interceptors are of course not limited to just java.sql.Connection but can be used to wrap any + of the results from a method invocation as well. You could build query performance analyzer that provides JMX notifications when a + query is running longer than the expected time.

+
+

Configuring JDBC interceptors

+

Configuring JDBC interceptors is done using the jdbcInterceptors property. + The property contains a list of semicolon separated class names. If the + classname is not fully qualified it will be prefixed with the + org.apache.tomcat.jdbc.pool.interceptor. prefix. +

+

Example:
+ + jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; + org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer" + +
+ is the same as +
+ jdbcInterceptors="ConnectionState;StatementFinalizer" +

+

+ Interceptors can have properties as well. Properties for an interceptor + are specified within parentheses after the class name. Several properties + are separated by commas. +

+

Example:
+ + jdbcInterceptors="ConnectionState;StatementFinalizer(useEquals=true)" + +

+

+ Extra whitespace characters around class names, property names and values + are ignored. +

+
+

org.apache.tomcat.jdbc.pool.JdbcInterceptor

+

Abstract base class for all interceptors, can not be instantiated.

+
+ Attribute + + Description +
useEquals +

(boolean) Set to true if you wish the ProxyConnection class to use String.equals and set to false + when you wish to use == when comparing method names. + The default value is true. +

+
+
+

org.apache.tomcat.jdbc.pool.interceptor.ConnectionState

+

Caches the connection for the following attributes autoCommit, readOnly, + transactionIsolation and catalog. + It is a performance enhancement to avoid roundtrip to the database when getters are called or setters are called with an already set value. +

+
+ Attribute + + Description +
+
+

org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer

+

Keeps track of all statements created using createStatement, prepareStatement or prepareCall + and closes these statements when the connection is returned to the pool. +

+
+ Attribute + + Description +
trace +

(boolean as String) Enable tracing of unclosed statements. + When enabled and a connection is closed, and statements are not closed, + the interceptor will log all stack traces. + The default value is false. +

+
+
+

org.apache.tomcat.jdbc.pool.interceptor.StatementCache

+

Caches PreparedStatement and/or CallableStatement + instances on a connection. +

+

The statements are cached per connection. + The count limit is counted globally for all connections that belong to + the same pool. Once the count reaches max, subsequent + statements are not returned to the cache and are closed immediately. +

+
+ Attribute + + Description +
prepared +

(boolean as String) Enable caching of PreparedStatement + instances created using prepareStatement calls. + The default value is true. +

+
callable +

(boolean as String) Enable caching of CallableStatement + instances created using prepareCall calls. + The default value is false. +

+
max +

(int as String) Limit on the count of cached statements across + the connection pool. + The default value is 50. +

+
+
+

org.apache.tomcat.jdbc.pool.interceptor.StatementDecoratorInterceptor

+

See 48392. Interceptor to wrap statements and result sets in order to prevent access to the actual connection + using the methods ResultSet.getStatement().getConnection() and Statement.getConnection() +

+
+ Attribute + + Description +
+
+

org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor

+

Automatically calls java.sql.Statement.setQueryTimeout(seconds) when a new statement is created. + The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts. +

+
+ Attribute + + Description +
queryTimeout +

(int as String) The number of seconds to set for the query timeout. + A value less than or equal to zero will disable this feature. + The default value is 1 seconds. +

+
+
+

org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport

+

Keeps track of query performance and issues log entries when queries exceed a time threshold of fail. + The log level used is WARN +

+
+ Attribute + + Description +
threshold +

(int as String) The number of milliseconds a query has to exceed before issuing a log alert. + The default value is 1000 milliseconds. +

+
maxQueries +

(int as String) The maximum number of queries to keep track of in order to preserve memory space. + A value less than or equal to 0 will disable this feature. + The default value is 1000. +

+
logSlow +

(boolean as String) Set to true if you wish to log slow queries. + The default value is true. +

+
logFailed +

(boolean as String) Set to true if you wish to log failed queries. + The default value is false. +

+
+
+

org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx

+

Extends the SlowQueryReport and in addition to log entries it issues JMX notification + for monitoring tools to react to. Inherits all the attributes from its parent class. + This class uses Tomcat's JMX engine so it wont work outside of the Tomcat container. + By default, JMX notifications are sent through the ConnectionPool mbean if it is enabled. + The SlowQueryReportJmx can also register an MBean if notifyPool=false +

+
+ Attribute + + Description +
notifyPool +

(boolean as String) Set to false if you want JMX notifications to go to the SlowQueryReportJmx MBean + The default value is true. +

+
objectName +

(String) Define a valid javax.management.ObjectName string that will be used to register this object with the platform mbean server + The default value is null and the object will be registered using + tomcat.jdbc:type=org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx,name=the-name-of-the-pool +

+
+
+

org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer

+

+ The abandoned timer starts when a connection is checked out from the pool. + This means if you have a 30second timeout and run 10x10second queries using the connection + it will be marked abandoned and potentially reclaimed depending on the abandonWhenPercentageFull + attribute. + Using this interceptor it will reset the checkout timer every time you perform an operation on the connection or execute a + query successfully. +

+
+ Attribute + + Description +
+
+

Code Example

+

Other examples of Tomcat configuration for JDBC usage can be found in the Tomcat documentation.

+

Plain Ol' Java

+

Here is a simple example of how to create and use a data source.

+
  import java.sql.Connection;
+  import java.sql.ResultSet;
+  import java.sql.Statement;
+
+  import org.apache.tomcat.jdbc.pool.DataSource;
+  import org.apache.tomcat.jdbc.pool.PoolProperties;
+
+  public class SimplePOJOExample {
+
+      public static void main(String[] args) throws Exception {
+          PoolProperties p = new PoolProperties();
+          p.setUrl("jdbc:mysql://localhost:3306/mysql");
+          p.setDriverClassName("com.mysql.jdbc.Driver");
+          p.setUsername("root");
+          p.setPassword("password");
+          p.setJmxEnabled(true);
+          p.setTestWhileIdle(false);
+          p.setTestOnBorrow(true);
+          p.setValidationQuery("SELECT 1");
+          p.setTestOnReturn(false);
+          p.setValidationInterval(30000);
+          p.setTimeBetweenEvictionRunsMillis(30000);
+          p.setMaxActive(100);
+          p.setInitialSize(10);
+          p.setMaxWait(10000);
+          p.setRemoveAbandonedTimeout(60);
+          p.setMinEvictableIdleTimeMillis(30000);
+          p.setMinIdle(10);
+          p.setLogAbandoned(true);
+          p.setRemoveAbandoned(true);
+          p.setJdbcInterceptors(
+            "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
+            "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
+          DataSource datasource = new DataSource();
+          datasource.setPoolProperties(p);
+
+          Connection con = null;
+          try {
+            con = datasource.getConnection();
+            Statement st = con.createStatement();
+            ResultSet rs = st.executeQuery("select * from user");
+            int cnt = 1;
+            while (rs.next()) {
+                System.out.println((cnt++)+". Host:" +rs.getString("Host")+
+                  " User:"+rs.getString("User")+" Password:"+rs.getString("Password"));
+            }
+            rs.close();
+            st.close();
+          } finally {
+            if (con!=null) try {con.close();}catch (Exception ignore) {}
+          }
+      }
+
+  }
+
+

As a Resource

+

And here is an example on how to configure a resource for JNDI lookups

+
<Resource name="jdbc/TestDB"
+          auth="Container"
+          type="javax.sql.DataSource"
+          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
+          testWhileIdle="true"
+          testOnBorrow="true"
+          testOnReturn="false"
+          validationQuery="SELECT 1"
+          validationInterval="30000"
+          timeBetweenEvictionRunsMillis="30000"
+          maxActive="100"
+          minIdle="10"
+          maxWait="10000"
+          initialSize="10"
+          removeAbandonedTimeout="60"
+          removeAbandoned="true"
+          logAbandoned="true"
+          minEvictableIdleTimeMillis="30000"
+          jmxEnabled="true"
+          jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
+            org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
+          username="root"
+          password="password"
+          driverClassName="com.mysql.jdbc.Driver"
+          url="jdbc:mysql://localhost:3306/mysql"/>
+ +
+

Asynchronous Connection Retrieval

+

The Tomcat JDBC connection pool supports asynchronous connection retrieval without adding additional threads to the + pool library. It does this by adding a method to the data source called Future<Connection> getConnectionAsync(). + In order to use the async retrieval, two conditions must be met: +

+
    +
  1. You must configure the fairQueue property to be true.
  2. +
  3. You will have to cast the data source to org.apache.tomcat.jdbc.pool.DataSource
  4. +
+ An example of using the async feature is show below. +
  Connection con = null;
+  try {
+    Future<Connection> future = datasource.getConnectionAsync();
+    while (!future.isDone()) {
+      System.out.println("Connection is not yet available. Do some background work");
+      try {
+        Thread.sleep(100); //simulate work
+      }catch (InterruptedException x) {
+        Thread.currentThread().interrupt();
+      }
+    }
+    con = future.get(); //should return instantly
+    Statement st = con.createStatement();
+    ResultSet rs = st.executeQuery("select * from user");
+ +
+

Interceptors

+

Interceptors are a powerful way to enable, disable or modify functionality on a specific connection or its sub components. + There are many different use cases for when interceptors are useful. By default, and for performance reasons, the connection pool is stateless. + The only state the pool itself inserts are defaultAutoCommit, defaultReadOnly, defaultTransactionIsolation, defaultCatalog if + these are set. These 4 properties are only set upon connection creation. Should these properties be modified during the usage of the connection, + the pool itself will not reset them.

+

An interceptor has to extend the org.apache.tomcat.jdbc.pool.JdbcInterceptor class. This class is fairly simple, + You will need to have a no arg constructor

+
  public JdbcInterceptor() {
+  }
+

+ When a connection is borrowed from the pool, the interceptor can initialize or in some other way react to the event by implementing the +

+
  public abstract void reset(ConnectionPool parent, PooledConnection con);
+

+ method. This method gets called with two parameters, a reference to the connection pool itself ConnectionPool parent + and a reference to the underlying connection PooledConnection con. +

+

+ When a method on the java.sql.Connection object is invoked, it will cause the +

+
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+

+ method to get invoked. The Method method is the actual method invoked, and Object[] args are the arguments. + To look at a very simple example, where we demonstrate how to make the invocation to java.sql.Connection.close() a noop + if the connection has been closed +

+
  if (CLOSE_VAL==method.getName()) {
+      if (isClosed()) return null; //noop for already closed.
+  }
+  return super.invoke(proxy,method,args);
+

+ There is an observation being made. It is the comparison of the method name. One way to do this would be to do + "close".equals(method.getName()). + Above we see a direct reference comparison between the method name and static final String reference. + According to the JVM spec, method names and static final String end up in a shared constant pool, so the reference comparison should work. + One could of course do this as well: +

+
  if (compare(CLOSE_VAL,method)) {
+      if (isClosed()) return null; //noop for already closed.
+  }
+  return super.invoke(proxy,method,args);
+

+ The compare(String,Method) will use the useEquals flag on an interceptor and do either reference comparison or + a string value comparison when the useEquals=true flag is set. +

+

Pool start/stop
+ When the connection pool is started or closed, you can be notifed. You will only be notified once per interceptor class + even though it is an instance method. and you will be notified using an interceptor currently not attached to a pool. +

+
  public void poolStarted(ConnectionPool pool) {
+  }
+
+  public void poolClosed(ConnectionPool pool) {
+  }
+

+ When overriding these methods, don't forget to call super if you are extending a class other than JdbcInterceptor +

+

Configuring interceptors
+ Interceptors are configured using the jdbcInterceptors property or the setJdbcInterceptors method. + An interceptor can have properties, and would be configured like this +

+
  String jdbcInterceptors=
+    "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState(useEquals=true,fast=yes)"
+ +

Interceptor properties
+ Since interceptors can have properties, you need to be able to read the values of these properties within your + interceptor. Taking an example like the one above, you can override the setProperties method. +

+
  public void setProperties(Map<String, InterceptorProperty> properties) {
+     super.setProperties(properties);
+     final String myprop = "myprop";
+     InterceptorProperty p1 = properties.get(myprop);
+     if (p1!=null) {
+         setMyprop(Long.parseLong(p1.getValue()));
+     }
+  }
+ +
+

Getting the actual JDBC connection

+

Connection pools create wrappers around the actual connection in order to properly pool them. + We also create interceptors in these wrappers to be able to perform certain functions. + If there is a need to retrieve the actual connection, one can do so using the javax.sql.PooledConnection + interface. +

+
  Connection con = datasource.getConnection();
+  Connection actual = ((javax.sql.PooledConnection)con).getConnection();
+ +
+ +

Building

+

We build the JDBC pool code with 1.6, but it is backwards compatible down to 1.5 for runtime environment. For unit test, we use 1.6 and higher

+

Other examples of Tomcat configuration for JDBC usage can be found in the Tomcat documentation.

+

Building from source

+

Building is pretty simple. The pool has a dependency on tomcat-juli.jar and in case you want the SlowQueryReportJmx

+
  javac -classpath tomcat-juli.jar \
+        -d . \
+        org/apache/tomcat/jdbc/pool/*.java \
+        org/apache/tomcat/jdbc/pool/interceptor/*.java \
+        org/apache/tomcat/jdbc/pool/jmx/*.java
+

+ A build file can be found in the Tomcat source repository. +

+

+ As a convenience, a build file is also included where a simple build command will generate all files needed. +

+
  ant download  (downloads dependencies)
+  ant build     (compiles and generates .jar files)
+  ant dist      (creates a release package)
+  ant test      (runs tests, expects a test database to be setup)
+ +

+ The system is structured for a Maven build, but does generate release artifacts. Just the library itself. +

+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/jndi-datasource-examples-howto.html b/test.dockerapp/tomcat/webapps/docs/jndi-datasource-examples-howto.html new file mode 100644 index 0000000..3cb1c38 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/jndi-datasource-examples-howto.html @@ -0,0 +1,676 @@ + +Apache Tomcat 8 (8.0.53) - JNDI Datasource HOW-TO

JNDI Datasource HOW-TO

Table of Contents

Introduction

+ +

JNDI Datasource configuration is covered extensively in the +JNDI-Resources-HOWTO. However, feedback from tomcat-user has +shown that specifics for individual configurations can be rather tricky.

+ +

Here then are some example configurations that have been posted to +tomcat-user for popular databases and some general tips for db usage.

+ +

You should be aware that since these notes are derived from configuration +and/or feedback posted to tomcat-user YMMV :-). Please let us +know if you have any other tested configurations that you feel may be of use +to the wider audience, or if you feel we can improve this section in anyway.

+ +

+Please note that JNDI resource configuration changed somewhat between +Tomcat 7.x and Tomcat 8.x as they are using different versions of +Apache Commons DBCP library. You will most likely need to modify older +JNDI resource configurations to match the syntax in the example below in order +to make them work in Tomcat 8. +See Tomcat Migration Guide +for details. +

+ +

+Also, please note that JNDI DataSource configuration in general, and this +tutorial in particular, assumes that you have read and understood the +Context and +Host configuration references, including +the section about Automatic Application Deployment in the latter reference. +

+

DriverManager, the service provider mechanism and memory leaks

+ +

java.sql.DriverManager supports the +service +provider mechanism. This feature is that all the available JDBC drivers +that announce themselves by providing a META-INF/services/java.sql.Driver +file are automatically discovered, loaded and registered, +relieving you from the need to load the database driver explicitly before +you create a JDBC connection. +However, the implementation is fundamentally broken in all Java versions for +a servlet container environment. The problem is that +java.sql.DriverManager will scan for the drivers only once.

+ +

The JRE Memory Leak Prevention Listener +that is included with Apache Tomcat solves this by triggering the drivers scan +during Tomcat startup. This is enabled by default. It means that only +libraries visible to the listener such as the ones in +$CATALINA_BASE/lib will be scanned for database drivers. +If you are considering disabling this feature, note that +the scan would be triggered by the first web application that is +using JDBC, leading to failures when this web application is reloaded +and for other web applications that rely on this feature. +

+ +

Thus, the web applications that have database drivers in their +WEB-INF/lib directory cannot rely on the service provider +mechanism and should register the drivers explicitly.

+ +

The list of drivers in java.sql.DriverManager is also +a known source of memory leaks. Any Drivers registered +by a web application must be deregistered when the web application stops. +Tomcat will attempt to automatically discover and deregister any +JDBC drivers loaded by the web application class loader when the web +application stops. +However, it is expected that applications do this for themselves via +a ServletContextListener. +

+ +

Database Connection Pool (DBCP 2) Configurations

+ +

The default database connection pool implementation in Apache Tomcat +relies on the libraries from the +Apache Commons project. +The following libraries are used: +

+ +
    +
  • Commons DBCP
  • +
  • Commons Pool
  • +
+ +

+These libraries are located in a single JAR at +$CATALINA_HOME/lib/tomcat-dbcp.jar. However, +only the classes needed for connection pooling have been included, and the +packages have been renamed to avoid interfering with applications. +

+ +

DBCP 2.0 provides support for JDBC 4.1.

+ +

Installation

+ +

See the +DBCP documentation for a complete list of configuration parameters. +

+ +
+ +

Preventing database connection pool leaks

+ +

+A database connection pool creates and manages a pool of connections +to a database. Recycling and reusing already existing connections +to a database is more efficient than opening a new connection. +

+ +

+There is one problem with connection pooling. A web application has +to explicitly close ResultSet's, Statement's, and Connection's. +Failure of a web application to close these resources can result in +them never being available again for reuse, a database connection pool "leak". +This can eventually result in your web application database connections failing +if there are no more available connections.

+ +

+There is a solution to this problem. The Apache Commons DBCP can be +configured to track and recover these abandoned database connections. Not +only can it recover them, but also generate a stack trace for the code +which opened these resources and never closed them.

+ +

+To configure a DBCP DataSource so that abandoned database connections are +removed and recycled, add one or both of the following attributes to the +Resource configuration for your DBCP DataSource: +

+
removeAbandonedOnBorrow=true
+
removeAbandonedOnMaintenance=true
+

The default for both of these attributes is false. Note that +removeAbandonedOnMaintenance has no effect unless pool +maintenance is enabled by setting timeBetweenEvictionRunsMillis +to a positive value. See the + +DBCP documentation for full documentation on these attributes. +

+ +

+Use the removeAbandonedTimeout attribute to set the number +of seconds a database connection has been idle before it is considered abandoned. +

+ +
removeAbandonedTimeout="60"
+ +

+The default timeout for removing abandoned connections is 300 seconds. +

+ +

+The logAbandoned attribute can be set to true +if you want DBCP to log a stack trace of the code which abandoned the +database connection resources. +

+
logAbandoned="true"
+

+The default is false. +

+ +
+ +

MySQL DBCP Example

+ +
0. Introduction
+

Versions of MySQL and JDBC +drivers that have been reported to work: +

+
    +
  • MySQL 3.23.47, MySQL 3.23.47 using InnoDB,, MySQL 3.23.58, MySQL 4.0.1alpha
  • +
  • Connector/J 3.0.11-stable (the official JDBC Driver)
  • +
  • mm.mysql 2.0.14 (an old 3rd party JDBC Driver)
  • +
+ +

Before you proceed, don't forget to copy the JDBC Driver's jar into $CATALINA_HOME/lib.

+ +
1. MySQL configuration
+

+Ensure that you follow these instructions as variations can cause problems. +

+ +

Create a new test user, a new database and a single test table. +Your MySQL user must have a password assigned. The driver +will fail if you try to connect with an empty password. +

+
mysql> GRANT ALL PRIVILEGES ON *.* TO javauser@localhost
+    ->   IDENTIFIED BY 'javadude' WITH GRANT OPTION;
+mysql> create database javatest;
+mysql> use javatest;
+mysql> create table testdata (
+    ->   id int not null auto_increment primary key,
+    ->   foo varchar(25),
+    ->   bar int);
+
+Note: the above user should be removed once testing is +complete! +
+ +

Next insert some test data into the testdata table. +

+
mysql> insert into testdata values(null, 'hello', 12345);
+Query OK, 1 row affected (0.00 sec)
+
+mysql> select * from testdata;
++----+-------+-------+
+| ID | FOO   | BAR   |
++----+-------+-------+
+|  1 | hello | 12345 |
++----+-------+-------+
+1 row in set (0.00 sec)
+
+mysql>
+ +
2. Context configuration
+

Configure the JNDI DataSource in Tomcat by adding a declaration for your +resource to your Context.

+

For example:

+
<Context>
+
+    <!-- maxTotal: Maximum number of database connections in pool. Make sure you
+         configure your mysqld max_connections large enough to handle
+         all of your db connections. Set to -1 for no limit.
+         -->
+
+    <!-- maxIdle: Maximum number of idle database connections to retain in pool.
+         Set to -1 for no limit.  See also the DBCP documentation on this
+         and the minEvictableIdleTimeMillis configuration parameter.
+         -->
+
+    <!-- maxWaitMillis: Maximum time to wait for a database connection to become available
+         in ms, in this example 10 seconds. An Exception is thrown if
+         this timeout is exceeded.  Set to -1 to wait indefinitely.
+         -->
+
+    <!-- username and password: MySQL username and password for database connections  -->
+
+    <!-- driverClassName: Class name for the old mm.mysql JDBC driver is
+         org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
+         Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
+         -->
+
+    <!-- url: The JDBC connection url for connecting to your MySQL database.
+         -->
+
+  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
+               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
+               username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
+               url="jdbc:mysql://localhost:3306/javatest"/>
+
+</Context>
+ +
3. web.xml configuration
+ +

Now create a WEB-INF/web.xml for this test application.

+
<web-app 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
+http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+    version="2.4">
+  <description>MySQL Test App</description>
+  <resource-ref>
+      <description>DB Connection</description>
+      <res-ref-name>jdbc/TestDB</res-ref-name>
+      <res-type>javax.sql.DataSource</res-type>
+      <res-auth>Container</res-auth>
+  </resource-ref>
+</web-app>
+ +
4. Test code
+

Now create a simple test.jsp page for use later.

+
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+
+<sql:query var="rs" dataSource="jdbc/TestDB">
+select id, foo, bar from testdata
+</sql:query>
+
+<html>
+  <head>
+    <title>DB Test</title>
+  </head>
+  <body>
+
+  <h2>Results</h2>
+
+<c:forEach var="row" items="${rs.rows}">
+    Foo ${row.foo}<br/>
+    Bar ${row.bar}<br/>
+</c:forEach>
+
+  </body>
+</html>
+ +

That JSP page makes use of +JSTL's +SQL and Core taglibs. You can get it from +Apache Tomcat Taglibs - Standard Tag Library +project — just make sure you get a 1.1.x or later release. Once you have +JSTL, copy jstl.jar and standard.jar to your web app's +WEB-INF/lib directory. + +

+ +

Finally deploy your web app into $CATALINA_BASE/webapps either +as a warfile called DBTest.war or into a sub-directory called +DBTest

+

Once deployed, point a browser at +http://localhost:8080/DBTest/test.jsp to view the fruits of +your hard work.

+ +
+ +

Oracle 8i, 9i & 10g

+
0. Introduction
+ +

Oracle requires minimal changes from the MySQL configuration except for the +usual gotchas :-)

+

Drivers for older Oracle versions may be distributed as *.zip files rather +than *.jar files. Tomcat will only use *.jar files installed in +$CATALINA_HOME/lib. Therefore classes111.zip +or classes12.zip will need to be renamed with a .jar +extension. Since jarfiles are zipfiles, there is no need to unzip and jar these +files - a simple rename will suffice.

+ +

For Oracle 9i onwards you should use oracle.jdbc.OracleDriver +rather than oracle.jdbc.driver.OracleDriver as Oracle have stated +that oracle.jdbc.driver.OracleDriver is deprecated and support +for this driver class will be discontinued in the next major release. +

+ +
1. Context configuration
+

In a similar manner to the mysql config above, you will need to define your +Datasource in your Context. Here we define a +Datasource called myoracle using the thin driver to connect as user scott, +password tiger to the sid called mysid. (Note: with the thin driver this sid is +not the same as the tnsname). The schema used will be the default schema for the +user scott.

+ +

Use of the OCI driver should simply involve a changing thin to oci in the URL string. +

+
<Resource name="jdbc/myoracle" auth="Container"
+              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
+              url="jdbc:oracle:thin:@127.0.0.1:1521:mysid"
+              username="scott" password="tiger" maxTotal="20" maxIdle="10"
+              maxWaitMillis="-1"/>
+ +
2. web.xml configuration
+

You should ensure that you respect the element ordering defined by the DTD when you +create you applications web.xml file.

+
<resource-ref>
+ <description>Oracle Datasource example</description>
+ <res-ref-name>jdbc/myoracle</res-ref-name>
+ <res-type>javax.sql.DataSource</res-type>
+ <res-auth>Container</res-auth>
+</resource-ref>
+
3. Code example
+

You can use the same example application as above (assuming you create the required DB +instance, tables etc.) replacing the Datasource code with something like

+
Context initContext = new InitialContext();
+Context envContext  = (Context)initContext.lookup("java:/comp/env");
+DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
+Connection conn = ds.getConnection();
+//etc.
+
+ + +

PostgreSQL

+
0. Introduction
+

PostgreSQL is configured in a similar manner to Oracle.

+ +
1. Required files
+

+Copy the Postgres JDBC jar to $CATALINA_HOME/lib. As with Oracle, the +jars need to be in this directory in order for DBCP's Classloader to find +them. This has to be done regardless of which configuration step you take next. +

+ +
2. Resource configuration
+ +

+You have two choices here: define a datasource that is shared across all Tomcat +applications, or define a datasource specifically for one application. +

+ +
2a. Shared resource configuration
+

+Use this option if you wish to define a datasource that is shared across +multiple Tomcat applications, or if you just prefer defining your datasource +in this file. +

+

This author has not had success here, although others have reported so. +Clarification would be appreciated here.

+ +
<Resource name="jdbc/postgres" auth="Container"
+          type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
+          url="jdbc:postgresql://127.0.0.1:5432/mydb"
+          username="myuser" password="mypasswd" maxTotal="20" maxIdle="10" maxWaitMillis="-1"/>
+
2b. Application-specific resource configuration
+ +

+Use this option if you wish to define a datasource specific to your application, +not visible to other Tomcat applications. This method is less invasive to your +Tomcat installation. +

+ +

+Create a resource definition for your Context. +The Context element should look something like the following. +

+ +
<Context>
+
+<Resource name="jdbc/postgres" auth="Container"
+          type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
+          url="jdbc:postgresql://127.0.0.1:5432/mydb"
+          username="myuser" password="mypasswd" maxTotal="20" maxIdle="10"
+maxWaitMillis="-1"/>
+</Context>
+ +
3. web.xml configuration
+
<resource-ref>
+ <description>postgreSQL Datasource example</description>
+ <res-ref-name>jdbc/postgres</res-ref-name>
+ <res-type>javax.sql.DataSource</res-type>
+ <res-auth>Container</res-auth>
+</resource-ref>
+ +
4. Accessing the datasource
+

+When accessing the datasource programmatically, remember to prepend +java:/comp/env to your JNDI lookup, as in the following snippet of +code. Note also that "jdbc/postgres" can be replaced with any value you prefer, provided +you change it in the above resource definition file as well. +

+ +
InitialContext cxt = new InitialContext();
+if ( cxt == null ) {
+   throw new Exception("Uh oh -- no context!");
+}
+
+DataSource ds = (DataSource) cxt.lookup( "java:/comp/env/jdbc/postgres" );
+
+if ( ds == null ) {
+   throw new Exception("Data source not found!");
+}
+ +
+

Non-DBCP Solutions

+

+These solutions either utilise a single connection to the database (not recommended for anything other +than testing!) or some other pooling technology. +

+

Oracle 8i with OCI client

+

Introduction

+

Whilst not strictly addressing the creation of a JNDI DataSource using the OCI client, these notes can be combined with the +Oracle and DBCP solution above.

+

+In order to use OCI driver, you should have an Oracle client installed. You should have installed +Oracle8i(8.1.7) client from cd, and download the suitable JDBC/OCI +driver(Oracle8i 8.1.7.1 JDBC/OCI Driver) from otn.oracle.com. +

+

+After renaming classes12.zip file to classes12.jar +for Tomcat, copy it into $CATALINA_HOME/lib. +You may also have to remove the javax.sql.* classes +from this file depending upon the version of Tomcat and JDK you are using. +

+
+ +

Putting it all together

+

+Ensure that you have the ocijdbc8.dll or .so in your $PATH or LD_LIBRARY_PATH + (possibly in $ORAHOME\bin) and also confirm that the native library can be loaded by a simple test program +using System.loadLibrary("ocijdbc8"); +

+

+You should next create a simple test servlet or jsp that has these +critical lines: +

+
DriverManager.registerDriver(new
+oracle.jdbc.driver.OracleDriver());
+conn =
+DriverManager.getConnection("jdbc:oracle:oci8:@database","username","password");
+

+where database is of the form host:port:SID Now if you try to access the URL of your +test servlet/jsp and what you get is a +ServletException with a root cause of java.lang.UnsatisfiedLinkError:get_env_handle. +

+

+First, the UnsatisfiedLinkError indicates that you have +

+
    +
  • a mismatch between your JDBC classes file and +your Oracle client version. The giveaway here is the message stating that a needed library file cannot be +found. For example, you may be using a classes12.zip file from Oracle Version 8.1.6 with a Version 8.1.5 +Oracle client. The classesXXX.zip file and Oracle client software versions must match. +
  • +
  • A $PATH, LD_LIBRARY_PATH problem.
  • +
  • It has been reported that ignoring the driver you have downloaded from otn and using +the classes12.zip file from the directory $ORAHOME\jdbc\lib will also work. +
  • +
+

+Next you may experience the error ORA-06401 NETCMN: invalid driver designator +

+

+The Oracle documentation says : "Cause: The login (connect) string contains an invalid +driver designator. Action: Correct the string and re-submit." + +Change the database connect string (of the form host:port:SID) with this one: +(description=(address=(host=myhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl))) +

+

+Ed. Hmm, I don't think this is really needed if you sort out your TNSNames - but I'm not an Oracle DBA :-) +

+
+

Common Problems

+

Here are some common problems encountered with a web application which +uses a database and tips for how to solve them.

+ +

Intermittent Database Connection Failures

+

+Tomcat runs within a JVM. The JVM periodically performs garbage collection +(GC) to remove java objects which are no longer being used. When the JVM +performs GC execution of code within Tomcat freezes. If the maximum time +configured for establishment of a database connection is less than the amount +of time garbage collection took you can get a database connection failure. +

+ +

To collect data on how long garbage collection is taking add the +-verbose:gc argument to your CATALINA_OPTS +environment variable when starting Tomcat. When verbose gc is enabled +your $CATALINA_BASE/logs/catalina.out log file will include +data for every garbage collection including how long it took.

+ +

When your JVM is tuned correctly 99% of the time a GC will take less +than one second. The remainder will only take a few seconds. Rarely, +if ever should a GC take more than 10 seconds.

+ +

Make sure that the db connection timeout is set to 10-15 seconds. +For the DBCP you set this using the parameter maxWaitMillis.

+ +
+ +

Random Connection Closed Exceptions

+

+These can occur when one request gets a db connection from the connection +pool and closes it twice. When using a connection pool, closing the +connection just returns it to the pool for reuse by another request, +it doesn't close the connection. And Tomcat uses multiple threads to +handle concurrent requests. Here is an example of the sequence +of events which could cause this error in Tomcat: +

+
+  Request 1 running in Thread 1 gets a db connection.
+
+  Request 1 closes the db connection.
+
+  The JVM switches the running thread to Thread 2
+
+  Request 2 running in Thread 2 gets a db connection
+  (the same db connection just closed by Request 1).
+
+  The JVM switches the running thread back to Thread 1
+
+  Request 1 closes the db connection a second time in a finally block.
+
+  The JVM switches the running thread back to Thread 2
+
+  Request 2 Thread 2 tries to use the db connection but fails
+  because Request 1 closed it.
+
+

+Here is an example of properly written code to use a database connection +obtained from a connection pool: +

+
  Connection conn = null;
+  Statement stmt = null;  // Or PreparedStatement if needed
+  ResultSet rs = null;
+  try {
+    conn = ... get connection from connection pool ...
+    stmt = conn.createStatement("select ...");
+    rs = stmt.executeQuery();
+    ... iterate through the result set ...
+    rs.close();
+    rs = null;
+    stmt.close();
+    stmt = null;
+    conn.close(); // Return to connection pool
+    conn = null;  // Make sure we don't close it twice
+  } catch (SQLException e) {
+    ... deal with errors ...
+  } finally {
+    // Always make sure result sets and statements are closed,
+    // and the connection is returned to the pool
+    if (rs != null) {
+      try { rs.close(); } catch (SQLException e) { ; }
+      rs = null;
+    }
+    if (stmt != null) {
+      try { stmt.close(); } catch (SQLException e) { ; }
+      stmt = null;
+    }
+    if (conn != null) {
+      try { conn.close(); } catch (SQLException e) { ; }
+      conn = null;
+    }
+  }
+ +
+ +

Context versus GlobalNamingResources

+

+ Please note that although the above instructions place the JNDI declarations in a Context + element, it is possible and sometimes desirable to place these declarations in the + GlobalNamingResources section of the server + configuration file. A resource placed in the GlobalNamingResources section will be shared + among the Contexts of the server. +

+
+ +

JNDI Resource Naming and Realm Interaction

+

+ In order to get Realms to work, the realm must refer to the datasource as + defined in the <GlobalNamingResources> or <Context> section, not a datasource as renamed + using <ResourceLink>. +

+
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/jndi-resources-howto.html b/test.dockerapp/tomcat/webapps/docs/jndi-resources-howto.html new file mode 100644 index 0000000..ec026a0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/jndi-resources-howto.html @@ -0,0 +1,1056 @@ + +Apache Tomcat 8 (8.0.53) - JNDI Resources HOW-TO

JNDI Resources HOW-TO

Table of Contents

Introduction

+ +

Tomcat provides a JNDI InitialContext implementation +instance for each web application running under it, in a manner that is +compatible with those provided by a + +Java Enterprise Edition application server. The Java EE standard provides +a standard set of elements in the /WEB-INF/web.xml file to +reference/define resources.

+ +

See the following Specifications for more information about programming APIs +for JNDI, and for the features supported by Java Enterprise Edition (Java EE) +servers, which Tomcat emulates for the services that it provides:

+ + +

web.xml configuration

+ +

The following elements may be used in the web application deployment +descriptor (/WEB-INF/web.xml) of your web application to define +resources:

+
    +
  • <env-entry> - Environment entry, a + single-value parameter that can be used to configure how the application + will operate.
  • +
  • <resource-ref> - Resource reference, + which is typically to an object factory for resources such as a JDBC + DataSource, a JavaMail Session, or custom + object factories configured into Tomcat.
  • +
  • <resource-env-ref> - Resource + environment reference, a new variation of resource-ref + added in Servlet 2.4 that is simpler to configure for resources + that do not require authentication information.
  • +
+ +

Providing that Tomcat is able to identify an appropriate resource factory to +use to create the resource and that no further configuration information is +required, Tomcat will use the information in /WEB-INF/web.xml to +create the resource.

+ +

Tomcat provides a number of Tomcat specific options for JNDI resources that +cannot be specified in web.xml. These include closeMethod that +enables faster cleaning-up of JNDI resources when a web application stops and +singleton that controls whether or not a new instance of the +resource is created for every JNDI lookup. To use these configuration options +the resource must be specified in a web application's +<Context> element or in the + +<GlobalNamingResources> element of +$CATALINA_BASE/conf/server.xml.

+ +

context.xml configuration

+ +

If Tomcat is unable to identify the appropriate resource factory and/or +additional configuration information is required, additional Tomcat specific +configuration must be specified before Tomcat can create the resource. +Tomcat specific resource configuration is entered in +the <Context> elements that +can be specified in either $CATALINA_BASE/conf/server.xml or, +preferably, the per-web-application context XML file +(META-INF/context.xml).

+ +

Tomcat specific resource configuration is performed using the following +elements in the <Context> +element:

+ +
    +
  • <Environment> - + Configure names and values for scalar environment entries that will be + exposed to the web application through the JNDI + InitialContext (equivalent to the inclusion of an + <env-entry> element in the web application + deployment descriptor).
  • +
  • <Resource> - + Configure the name and data type of a resource made available to the + application (equivalent to the inclusion of a + <resource-ref> element in the web application + deployment descriptor).
  • +
  • <ResourceLink> - + Add a link to a resource defined in the global JNDI context. Use resource + links to give a web application access to a resource defined in + the <GlobalNamingResources> + child element of the <Server> + element.
  • +
  • <Transaction> - + Add a resource factory for instantiating the UserTransaction object + instance that is available at java:comp/UserTransaction.
  • + +
+ +

Any number of these elements may be nested inside a +<Context> element and will +be associated only with that particular web application.

+ +

If a resource has been defined in a +<Context> element it is not +necessary for that resource to be defined in /WEB-INF/web.xml. +However, it is recommended to keep the entry in /WEB-INF/web.xml +to document the resource requirements for the web application.

+ +

Where the same resource name has been defined for a +<env-entry> element included in the web application +deployment descriptor (/WEB-INF/web.xml) and in an +<Environment> element as part of the +<Context> element for the +web application, the values in the deployment descriptor will take precedence +only if allowed by the corresponding +<Environment> element (by setting the override +attribute to "true").

+ +

Global configuration

+ +

Tomcat maintains a separate namespace of global resources for the +entire server. These are configured in the + +<GlobalNamingResources> element of +$CATALINA_BASE/conf/server.xml. You may expose these resources to +web applications by using a +<ResourceLink> to +include it in the per-web-application context.

+ +

If a resource has been defined using a +<ResourceLink>, it is not +necessary for that resource to be defined in /WEB-INF/web.xml. +However, it is recommended to keep the entry in /WEB-INF/web.xml +to document the resource requirements for the web application.

+ +

Using resources

+ +

The InitialContext is configured as a web application is +initially deployed, and is made available to web application components (for +read-only access). All configured entries and resources are placed in +the java:comp/env portion of the JNDI namespace, so a typical +access to a resource - in this case, to a JDBC DataSource - +would look something like this:

+ +
// Obtain our environment naming context
+Context initCtx = new InitialContext();
+Context envCtx = (Context) initCtx.lookup("java:comp/env");
+
+// Look up our data source
+DataSource ds = (DataSource)
+  envCtx.lookup("jdbc/EmployeeDB");
+
+// Allocate and use a connection from the pool
+Connection conn = ds.getConnection();
+... use this connection to access the database ...
+conn.close();
+ +

Tomcat Standard Resource Factories

+ +

Tomcat includes a series of standard resource factories that can + provide services to your web applications, but give you configuration + flexibility (via the + <Context> element) + without modifying the web application or the deployment descriptor. Each + subsection below details the configuration and usage of the standard resource + factories.

+ +

See Adding Custom + Resource Factories for information about how to create, install, + configure, and use your own custom resource factory classes with + Tomcat.

+ +

NOTE - Of the standard resource factories, only the + "JDBC Data Source" and "User Transaction" factories are mandated to + be available on other platforms, and then they are required only if + the platform implements the Java Enterprise Edition (Java EE) specs. + All other standard resource factories, plus custom resource factories + that you write yourself, are specific to Tomcat and cannot be assumed + to be available on other containers.

+ +

Generic JavaBean Resources

+ +
0. Introduction
+ +

This resource factory can be used to create objects of any + Java class that conforms to standard JavaBeans naming conventions (i.e. + it has a zero-arguments constructor, and has property setters that + conform to the setFoo() naming pattern. The resource factory will + only create a new instance of the appropriate bean class every time a + lookup() for this entry is made if the singleton + attribute of the factory is set to false.

+ +

The steps required to use this facility are described below.

+ +
1. Create Your JavaBean Class
+ +

Create the JavaBean class which will be instantiated each time + that the resource factory is looked up. For this example, assume + you create a class com.mycompany.MyBean, which looks + like this:

+ +
package com.mycompany;
+
+public class MyBean {
+
+  private String foo = "Default Foo";
+
+  public String getFoo() {
+    return (this.foo);
+  }
+
+  public void setFoo(String foo) {
+    this.foo = foo;
+  }
+
+  private int bar = 0;
+
+  public int getBar() {
+    return (this.bar);
+  }
+
+  public void setBar(int bar) {
+    this.bar = bar;
+  }
+
+
+}
+ +
2. Declare Your Resource Requirements
+ +

Next, modify your web application deployment descriptor + (/WEB-INF/web.xml) to declare the JNDI name under which + you will request new instances of this bean. The simplest approach is + to use a <resource-env-ref> element, like this:

+ +
<resource-env-ref>
+  <description>
+    Object factory for MyBean instances.
+  </description>
+  <resource-env-ref-name>
+    bean/MyBeanFactory
+  </resource-env-ref-name>
+  <resource-env-ref-type>
+    com.mycompany.MyBean
+  </resource-env-ref-type>
+</resource-env-ref>
+ +

WARNING - Be sure you respect the element ordering + that is required by the DTD for web application deployment descriptors! + See the + Servlet + Specification for details.

+ +
3. Code Your Application's Use Of This Resource
+ +

A typical use of this resource environment reference might look + like this:

+ +
Context initCtx = new InitialContext();
+Context envCtx = (Context) initCtx.lookup("java:comp/env");
+MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
+
+writer.println("foo = " + bean.getFoo() + ", bar = " +
+               bean.getBar());
+ +
4. Configure Tomcat's Resource Factory
+ +

To configure Tomcat's resource factory, add an element like this to the + <Context> element for + this web application.

+ +
<Context ...>
+  ...
+  <Resource name="bean/MyBeanFactory" auth="Container"
+            type="com.mycompany.MyBean"
+            factory="org.apache.naming.factory.BeanFactory"
+            bar="23"/>
+  ...
+</Context>
+ +

Note that the resource name (here, bean/MyBeanFactory + must match the value specified in the web application deployment + descriptor. We are also initializing the value of the bar + property, which will cause setBar(23) to be called before + the new bean is returned. Because we are not initializing the + foo property (although we could have), the bean will + contain whatever default value is set up by its constructor.

+ +

Some beans have properties with types that can not automatically be + converted from a string value. Setting such properties using the Tomcat + BeanFactory will fail with a NamingException. In cases were those beans + provide methods to set the properties from a string value, the Tomcat + BeanFactory can be configured to use these methods. The configuration is + done with the forceString attribute.

+ +

Assume our bean looks like this:

+ +
package com.mycompany;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class MyBean2 {
+
+  private InetAddress local = null;
+
+  public InetAddress getLocal() {
+    return local;
+  }
+
+  public void setLocal(InetAddress ip) {
+    local = ip;
+  }
+
+  public void setLocal(String localHost) {
+    try {
+      local = InetAddress.getByName(localHost);
+    } catch (UnknownHostException ex) {
+    }
+  }
+
+  private InetAddress remote = null;
+
+  public InetAddress getRemote() {
+    return remote;
+  }
+
+  public void setRemote(InetAddress ip) {
+    remote = ip;
+  }
+
+  public void host(String remoteHost) {
+    try {
+      remote = InetAddress.getByName(remoteHost);
+    } catch (UnknownHostException ex) {
+    }
+  }
+
+}
+ +

The bean has two properties, both are of type InetAddress. + The first property local has an additional setter taking a + string argument. By default the Tomcat BeanFactory would try to use the + automatically detected setter with the same argument type as the property + type and then throw a NamingException, because it is not prepared to convert + the given string attribute value to InetAddress. + We can tell the Tomcat BeanFactory to use the other setter like that:

+ +
<Context ...>
+  ...
+  <Resource name="bean/MyBeanFactory" auth="Container"
+            type="com.mycompany.MyBean2"
+            factory="org.apache.naming.factory.BeanFactory"
+            forceString="local"
+            local="localhost"/>
+  ...
+</Context>
+ +

The bean property remote can also be set from a string, + but one has to use the non-standard method name host. + To set local and remote use the following + configuration:

+ +
<Context ...>
+  ...
+  <Resource name="bean/MyBeanFactory" auth="Container"
+            type="com.mycompany.MyBean2"
+            factory="org.apache.naming.factory.BeanFactory"
+            forceString="local,remote=host"
+            local="localhost"
+            remote="tomcat.apache.org"/>
+  ...
+</Context>
+ +

Multiple property descriptions can be combined in + forceString by concatenation with comma as a separator. + Each property description consists of either only the property name + in which case the BeanFactory calls the setter method. Or it consist + of name=method in which case the property named + name is set by calling method method. + For properties of types String or of primitive type + or of their associated primitive wrapper classes using + forceString is not needed. The correct setter will be + automatically detected and argument conversion will be applied.

+ +
+ + +

UserDatabase Resources

+ +
0. Introduction
+ +

UserDatabase resources are typically configured as global resources for + use by a UserDatabase realm. Tomcat includes a UserDatabaseFactory that + creates UserDatabase resources backed by an XML file - usually + tomcat-users.xml

+ +

The steps required to set up a global UserDatabase resource are described + below.

+ +
1. Create/edit the XML file
+ +

The XML file is typically located at + $CATALINA_BASE/conf/tomcat-users.xml however, you are free to + locate the file anywhere on the file system. It is recommended that the XML + files are placed in $CATALINA_BASE/conf. A typical XML would + look like:

+ +
<?xml version='1.0' encoding='utf-8'?>
+<tomcat-users>
+  <role rolename="tomcat"/>
+  <role rolename="role1"/>
+  <user username="tomcat" password="tomcat" roles="tomcat"/>
+  <user username="both" password="tomcat" roles="tomcat,role1"/>
+  <user username="role1" password="tomcat" roles="role1"/>
+</tomcat-users>
+ +
2. Declare Your Resource
+ +

Next, modify $CATALINA_BASE/conf/server.xml to create the + UserDatabase resource based on your XML file. It should look something like + this:

+ +
<Resource name="UserDatabase"
+          auth="Container"
+          type="org.apache.catalina.UserDatabase"
+          description="User database that can be updated and saved"
+          factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+          pathname="conf/tomcat-users.xml"
+          readonly="false" />
+ +

The pathname attribute can be a URL, an absolute path or a + relative path. If relative, it is relative to $CATALINA_BASE. +

+ +

The readonly attribute is optional and defaults to + true if not supplied. If the XML is writeable then it will be + written to when Tomcat starts. WARNING: When the file is + written it will inherit the default file permissions for the user Tomcat + is running as. Ensure that these are appropriate to maintain the security + of your installation.

+ +
3. Configure the Realm
+ +

Configure a UserDatabase Realm to use this resource as described in the + Realm configuration documentation.

+ +
+ + +

JavaMail Sessions

+ +
0. Introduction
+ +

In many web applications, sending electronic mail messages is a + required part of the system's functionality. The + Java Mail API + makes this process relatively straightforward, but requires many + configuration details that the client application must be aware of + (including the name of the SMTP host to be used for message sending).

+ +

Tomcat includes a standard resource factory that will create + javax.mail.Session session instances for you, already + configured to connect to an SMTP server. + In this way, the application is totally insulated from changes in the + email server configuration environment - it simply asks for, and receives, + a preconfigured session whenever needed.

+ +

The steps required for this are outlined below.

+ +
1. Declare Your Resource Requirements
+ +

The first thing you should do is modify the web application deployment + descriptor (/WEB-INF/web.xml) to declare the JNDI name under + which you will look up preconfigured sessions. By convention, all such + names should resolve to the mail subcontext (relative to the + standard java:comp/env naming context that is the root of + all provided resource factories. A typical web.xml entry + might look like this:

+
<resource-ref>
+  <description>
+    Resource reference to a factory for javax.mail.Session
+    instances that may be used for sending electronic mail
+    messages, preconfigured to connect to the appropriate
+    SMTP server.
+  </description>
+  <res-ref-name>
+    mail/Session
+  </res-ref-name>
+  <res-type>
+    javax.mail.Session
+  </res-type>
+  <res-auth>
+    Container
+  </res-auth>
+</resource-ref>
+ +

WARNING - Be sure you respect the element ordering + that is required by the DTD for web application deployment descriptors! + See the + Servlet + Specification for details.

+ +
2. Code Your Application's Use Of This Resource
+ +

A typical use of this resource reference might look like this:

+
Context initCtx = new InitialContext();
+Context envCtx = (Context) initCtx.lookup("java:comp/env");
+Session session = (Session) envCtx.lookup("mail/Session");
+
+Message message = new MimeMessage(session);
+message.setFrom(new InternetAddress(request.getParameter("from")));
+InternetAddress to[] = new InternetAddress[1];
+to[0] = new InternetAddress(request.getParameter("to"));
+message.setRecipients(Message.RecipientType.TO, to);
+message.setSubject(request.getParameter("subject"));
+message.setContent(request.getParameter("content"), "text/plain");
+Transport.send(message);
+ +

Note that the application uses the same resource reference name + that was declared in the web application deployment descriptor. This + is matched up against the resource factory that is configured in the + <Context> element + for the web application as described below.

+ +
3. Configure Tomcat's Resource Factory
+ +

To configure Tomcat's resource factory, add an elements like this to the + <Context> element for + this web application.

+ +
<Context ...>
+  ...
+  <Resource name="mail/Session" auth="Container"
+            type="javax.mail.Session"
+            mail.smtp.host="localhost"/>
+  ...
+</Context>
+ +

Note that the resource name (here, mail/Session) must + match the value specified in the web application deployment descriptor. + Customize the value of the mail.smtp.host parameter to + point at the server that provides SMTP service for your network.

+ +

Additional resource attributes and values will be converted to properties + and values and passed to + javax.mail.Session.getInstance(java.util.Properties) as part of + the java.util.Properties collection. In addition to the + properties defined in Annex A of the JavaMail specification, individual + providers may also support additional properties. +

+ +

If the resource is configured with a password attribute and + either a mail.smtp.user or mail.user attribute + then Tomcat's resource factory will configure and add a + javax.mail.Authenticator to the mail session.

+ +
4. Install the JavaMail libraries
+ +

+ Download the JavaMail API.

+ +

Unpackage the distribution and place mail.jar into $CATALINA_HOME/lib so + that it is available to Tomcat during the initialization of the mail Session + Resource. Note: placing this jar in both $CATALINA_HOME/lib + and a web application's lib folder will cause an error, so ensure you have + it in the $CATALINA_HOME/lib location only. +

+ +
5. Restart Tomcat
+ +

For the additional JAR to be visible to Tomcat, it is necessary for the + Tomcat instance to be restarted.

+ + +
Example Application
+ +

The /examples application included with Tomcat contains + an example of utilizing this resource factory. It is accessed via the + "JSP Examples" link. The source code for the servlet that actually + sends the mail message is in + /WEB-INF/classes/SendMailServlet.java.

+ +

WARNING - The default configuration assumes that there + is an SMTP server listing on port 25 on localhost. If this is + not the case, edit the + <Context> element for + this web application and modify the parameter value for the + mail.smtp.host parameter to be the host name of an SMTP server + on your network.

+ +
+ +

JDBC Data Sources

+ +
0. Introduction
+ +

Many web applications need to access a database via a JDBC driver, + to support the functionality required by that application. The Java EE + Platform Specification requires Java EE Application Servers to make + available a DataSource implementation (that is, a connection + pool for JDBC connections) for this purpose. Tomcat offers exactly + the same support, so that database-based applications you develop on + Tomcat using this service will run unchanged on any Java EE server.

+ +

For information about JDBC, you should consult the following:

+ + +

NOTE - The default data source support in Tomcat + is based on the DBCP connection pool from the + Commons + project. However, it is possible to use any other connection pool + that implements javax.sql.DataSource, by writing your + own custom resource factory, as described + below.

+ +
1. Install Your JDBC Driver
+ +

Use of the JDBC Data Sources JNDI Resource Factory requires + that you make an appropriate JDBC driver available to both Tomcat internal + classes and to your web application. This is most easily accomplished by + installing the driver's JAR file(s) into the + $CATALINA_HOME/lib directory, which makes the driver + available both to the resource factory and to your application.

+ +
2. Declare Your Resource Requirements
+ +

Next, modify the web application deployment descriptor + (/WEB-INF/web.xml) to declare the JNDI name under + which you will look up preconfigured data source. By convention, all such + names should resolve to the jdbc subcontext (relative to the + standard java:comp/env naming context that is the root of + all provided resource factories. A typical web.xml entry + might look like this:

+
<resource-ref>
+  <description>
+    Resource reference to a factory for java.sql.Connection
+    instances that may be used for talking to a particular
+    database that is configured in the <Context>
+    configuration for the web application.
+  </description>
+  <res-ref-name>
+    jdbc/EmployeeDB
+  </res-ref-name>
+  <res-type>
+    javax.sql.DataSource
+  </res-type>
+  <res-auth>
+    Container
+  </res-auth>
+</resource-ref>
+ +

WARNING - Be sure you respect the element ordering + that is required by the DTD for web application deployment descriptors! + See the + Servlet + Specification for details.

+ +
3. Code Your Application's Use Of This Resource
+ +

A typical use of this resource reference might look like this:

+
Context initCtx = new InitialContext();
+Context envCtx = (Context) initCtx.lookup("java:comp/env");
+DataSource ds = (DataSource)
+  envCtx.lookup("jdbc/EmployeeDB");
+
+Connection conn = ds.getConnection();
+... use this connection to access the database ...
+conn.close();
+ +

Note that the application uses the same resource reference name that was + declared in the web application deployment descriptor. This is matched up + against the resource factory that is configured in the + <Context> element for + the web application as described below.

+ +
4. Configure Tomcat's Resource Factory
+ +

To configure Tomcat's resource factory, add an element like this to the + <Context> element for + the web application.

+ +
<Context ...>
+  ...
+  <Resource name="jdbc/EmployeeDB"
+            auth="Container"
+            type="javax.sql.DataSource"
+            username="dbusername"
+            password="dbpassword"
+            driverClassName="org.hsql.jdbcDriver"
+            url="jdbc:HypersonicSQL:database"
+            maxTotal="8"
+            maxIdle="4"/>
+  ...
+</Context>
+ +

Note that the resource name (here, jdbc/EmployeeDB) must + match the value specified in the web application deployment descriptor.

+ +

This example assumes that you are using the HypersonicSQL database + JDBC driver. Customize the driverClassName and + driverName parameters to match your actual database's + JDBC driver and connection URL.

+ +

The configuration properties for Tomcat's standard data source + resource factory + (org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory) are + as follows:

+
    +
  • driverClassName - Fully qualified Java class name + of the JDBC driver to be used.
  • +
  • username - Database username to be passed to our + JDBC driver.
  • +
  • password - Database password to be passed to our + JDBC driver.
  • +
  • url - Connection URL to be passed to our JDBC driver. + (For backwards compatibility, the property driverName + is also recognized.)
  • +
  • initialSize - The initial number of connections + that will be created in the pool during pool initialization. Default: 0
  • +
  • maxTotal - The maximum number of connections + that can be allocated from this pool at the same time. Default: 8
  • +
  • minIdle - The minimum number of connections that + will sit idle in this pool at the same time. Default: 0
  • +
  • maxIdle - The maximum number of connections that + can sit idle in this pool at the same time. Default: 8
  • +
  • maxWaitMillis - The maximum number of milliseconds that the + pool will wait (when there are no available connections) for a + connection to be returned before throwing an exception. Default: -1 (infinite)
  • +
+

Some additional properties handle connection validation:

+
    +
  • validationQuery - SQL query that can be used by the + pool to validate connections before they are returned to the + application. If specified, this query MUST be an SQL SELECT + statement that returns at least one row.
  • +
  • validationQueryTimeout - Timeout in seconds + for the validation query to return. Default: -1 (infinite)
  • +
  • testOnBorrow - true or false: whether a connection + should be validated using the validation query each time it is + borrowed from the pool. Default: true
  • +
  • testOnReturn - true or false: whether a connection + should be validated using the validation query each time it is + returned to the pool. Default: false
  • +
+

The optional evictor thread is responsible for shrinking the pool + by removing any connections which are idle for a long time. The evictor + does not respect minIdle. Note that you do not need to + activate the evictor thread if you only want the pool to shrink according + to the configured maxIdle property.

+

The evictor is disabled by default and can be configured using + the following properties:

+
    +
  • timeBetweenEvictionRunsMillis - The number of + milliseconds between consecutive runs of the evictor. + Default: -1 (disabled)
  • +
  • numTestsPerEvictionRun - The number of connections + that will be checked for idleness by the evictor during each + run of the evictor. Default: 3
  • +
  • minEvictableIdleTimeMillis - The idle time in + milliseconds after which a connection can be removed from the pool + by the evictor. Default: 30*60*1000 (30 minutes)
  • +
  • testWhileIdle - true or false: whether a connection + should be validated by the evictor thread using the validation query + while sitting idle in the pool. Default: false
  • +
+

Another optional feature is the removal of abandoned connections. + A connection is called abandoned if the application does not return it + to the pool for a long time. The pool can close such connections + automatically and remove them from the pool. This is a workaround + for applications leaking connections.

+

The abandoning feature is disabled by default and can be configured + using the following properties:

+
    +
  • removeAbandoned - true or false: whether to + remove abandoned connections from the pool. Default: false
  • +
  • removeAbandonedTimeout - The number of + seconds after which a borrowed connection is assumed to be abandoned. + Default: 300
  • +
  • logAbandoned - true or false: whether to log + stack traces for application code which abandoned a statement + or connection. This adds serious overhead. Default: false
  • +
+

Finally there are various properties that allow further fine tuning + of the pool behaviour:

+
    +
  • defaultAutoCommit - true or false: default + auto-commit state of the connections created by this pool. + Default: true
  • +
  • defaultReadOnly - true or false: default + read-only state of the connections created by this pool. + Default: false
  • +
  • defaultTransactionIsolation - This sets the + default transaction isolation level. Can be one of + NONE, READ_COMMITTED, + READ_UNCOMMITTED, REPEATABLE_READ, + SERIALIZABLE. Default: no default set
  • +
  • poolPreparedStatements - true or false: whether to + pool PreparedStatements and CallableStatements. Default: false
  • +
  • maxOpenPreparedStatements - The maximum number of open + statements that can be allocated from the statement pool at the same time. + Default: -1 (unlimited)
  • +
  • defaultCatalog - The name of the default catalog. + Default: not set
  • +
  • connectionInitSqls - A list of SQL statements + run once after a Connection is created. Separate multiple statements + by semicolons (;). Default: no statement
  • +
  • connectionProperties - A list of driver specific + properties passed to the driver for creating connections. Each + property is given as name=value, multiple properties + are separated by semicolons (;). Default: no properties
  • +
  • accessToUnderlyingConnectionAllowed - true or false: whether + accessing the underlying connections is allowed. Default: false
  • +
+

For more details, please refer to the commons-dbcp documentation.

+ +
+ +

Adding Custom Resource Factories

+ +

If none of the standard resource factories meet your needs, you can write + your own factory and integrate it into Tomcat, and then configure the use + of this factory in the + <Context> element for + the web application. In the example below, we will create a factory that only + knows how to create com.mycompany.MyBean beans from the + Generic JavaBean Resources example + above.

+ +

1. Write A Resource Factory Class

+ +

You must write a class that implements the JNDI service provider + javax.naming.spi.ObjectFactory interface. Every time your + web application calls lookup() on a context entry that is + bound to this factory (assuming that the factory is configured with + singleton="false"), the + getObjectInstance() method is called, with the following + arguments:

+
    +
  • Object obj - The (possibly null) object containing + location or reference information that can be used in creating an object. + For Tomcat, this will always be an object of type + javax.naming.Reference, which contains the class name of + this factory class, as well as the configuration properties (from the + <Context> for the + web application) to use in creating objects to be returned.
  • +
  • Name name - The name to which this factory is bound + relative to nameCtx, or null if no name + is specified.
  • +
  • Context nameCtx - The context relative to which the + name parameter is specified, or null if + name is relative to the default initial context.
  • +
  • Hashtable environment - The (possibly null) + environment that is used in creating this object. This is generally + ignored in Tomcat object factories.
  • +
+ +

To create a resource factory that knows how to produce MyBean + instances, you might create a class like this:

+ +
package com.mycompany;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+
+public class MyBeanFactory implements ObjectFactory {
+
+  public Object getObjectInstance(Object obj,
+      Name name2, Context nameCtx, Hashtable environment)
+      throws NamingException {
+
+      // Acquire an instance of our specified bean class
+      MyBean bean = new MyBean();
+
+      // Customize the bean properties from our attributes
+      Reference ref = (Reference) obj;
+      Enumeration addrs = ref.getAll();
+      while (addrs.hasMoreElements()) {
+          RefAddr addr = (RefAddr) addrs.nextElement();
+          String name = addr.getType();
+          String value = (String) addr.getContent();
+          if (name.equals("foo")) {
+              bean.setFoo(value);
+          } else if (name.equals("bar")) {
+              try {
+                  bean.setBar(Integer.parseInt(value));
+              } catch (NumberFormatException e) {
+                  throw new NamingException("Invalid 'bar' value " + value);
+              }
+          }
+      }
+
+      // Return the customized instance
+      return (bean);
+
+  }
+
+}
+ +

In this example, we are unconditionally creating a new instance of + the com.mycompany.MyBean class, and populating its properties + based on the parameters included in the <ResourceParams> + element that configures this factory (see below). You should note that any + parameter named factory should be skipped - that parameter is + used to specify the name of the factory class itself (in this case, + com.mycompany.MyBeanFactory) rather than a property of the + bean being configured.

+ +

For more information about ObjectFactory, see the + + JNDI Service Provider Interface (SPI) Specification.

+ +

You will need to compile this class against a class path that includes + all of the JAR files in the $CATALINA_HOME/lib directory. When you are through, + place the factory class (and the corresponding bean class) unpacked under + $CATALINA_HOME/lib, or in a JAR file inside + $CATALINA_HOME/lib. In this way, the required class + files are visible to both Catalina internal resources and your web + application.

+ +

2. Declare Your Resource Requirements

+ +

Next, modify your web application deployment descriptor + (/WEB-INF/web.xml) to declare the JNDI name under which + you will request new instances of this bean. The simplest approach is + to use a <resource-env-ref> element, like this:

+ +
<resource-env-ref>
+  <description>
+    Object factory for MyBean instances.
+  </description>
+  <resource-env-ref-name>
+    bean/MyBeanFactory
+  </resource-env-ref-name>
+  <resource-env-ref-type>
+    com.mycompany.MyBean
+  </resource-env-ref-type>
+</resource-env-ref>
+ +

WARNING - Be sure you respect the element ordering + that is required by the DTD for web application deployment descriptors! + See the + Servlet + Specification for details.

+ +

3. Code Your Application's Use Of This Resource

+ +

A typical use of this resource environment reference might look + like this:

+ +
Context initCtx = new InitialContext();
+Context envCtx = (Context) initCtx.lookup("java:comp/env");
+MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
+
+writer.println("foo = " + bean.getFoo() + ", bar = " +
+               bean.getBar());
+ +

4. Configure Tomcat's Resource Factory

+ +

To configure Tomcat's resource factory, add an elements like this to the + <Context> element for + this web application.

+ +
<Context ...>
+  ...
+  <Resource name="bean/MyBeanFactory" auth="Container"
+            type="com.mycompany.MyBean"
+            factory="com.mycompany.MyBeanFactory"
+            singleton="false"
+            bar="23"/>
+  ...
+</Context>
+ +

Note that the resource name (here, bean/MyBeanFactory + must match the value specified in the web application deployment + descriptor. We are also initializing the value of the bar + property, which will cause setBar(23) to be called before + the new bean is returned. Because we are not initializing the + foo property (although we could have), the bean will + contain whatever default value is set up by its constructor.

+ +

You will also note that, from the application developer's perspective, + the declaration of the resource environment reference, and the programming + used to request new instances, is identical to the approach used for the + Generic JavaBean Resources example. This illustrates one of the + advantages of using JNDI resources to encapsulate functionality - you can + change the underlying implementation without necessarily having to + modify applications using the resources, as long as you maintain + compatible APIs.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/jspapi/index.html b/test.dockerapp/tomcat/webapps/docs/jspapi/index.html new file mode 100644 index 0000000..7626c06 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/jspapi/index.html @@ -0,0 +1,34 @@ + + + + + + API docs + + + + +The JSP Javadoc is not installed by default. Download and install +the "fulldocs" package to get it. + +You can also access the javadoc online in the Tomcat + +documentation bundle. + + + diff --git a/test.dockerapp/tomcat/webapps/docs/logging.html b/test.dockerapp/tomcat/webapps/docs/logging.html new file mode 100644 index 0000000..02c9420 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/logging.html @@ -0,0 +1,623 @@ + +Apache Tomcat 8 (8.0.53) - Logging in Tomcat

Logging in Tomcat

Table of Contents

Introduction

+

+ The internal logging for Apache Tomcat uses JULI, a packaged renamed fork + of Apache Commons Logging + that, by default, is hard-coded to use the java.util.logging + framework. This ensures that Tomcat's internal logging and any web + application logging will remain independent, even if a web application + uses Apache Commons Logging. +

+ +

+ To configure Tomcat to use an alternative logging framework for its + internal logging, one has to replace the JULI implementation that is + hard-coded to use java.util.logging with a JULI + implementation that retains the full Commons Logging discovery mechanism. + Such an implementation is provided as an extras + component. Instructions on how to configure Tomcat to use Log4j framework + for its internal logging may be found below. +

+ +

+ A web application running on Apache Tomcat can: +

+
    +
  • + Use any logging framework of its choice. +
  • +
  • + Use system logging API, java.util.logging. +
  • +
  • + Use the logging API provided by the Java Servlets specification, + javax.servlet.ServletContext.log(...) +
  • +
+ +

+ The logging frameworks used by different web applications are independent. + See class loading for more details. + The exception to this rule is java.util.logging. If it used + directly or indirectly by your logging library then elements of it will be + shared across web applications because it is loaded by the system class + loader. +

+ +

Java logging API — java.util.logging

+ +

+ Apache Tomcat has its own implementation of several key elements of + java.util.logging API. This implementation is called JULI. + The key component there is a custom LogManager implementation, + that is aware of different web applications running on Tomcat (and + their different class loaders). It supports private per-application + logging configurations. It is also notified by Tomcat when a web application + is unloaded from memory, so that the references to its classes can be + cleared, preventing memory leaks. +

+ +

+ This java.util.logging implementation is enabled by providing + certain system properties when starting Java. The Apache Tomcat startup + scripts do this for you, but if you are using different tools to run + Tomcat (such as jsvc, or running Tomcat from within an IDE), you should + take care of them by yourself. +

+ +

+ More details about java.util.logging may be found in the documentation + for your JDK and on its Javadoc pages for the java.util.logging + package. +

+ +

+ More details about Tomcat JULI may be found below. +

+ +
+ +

Servlets logging API

+ +

+ The calls to javax.servlet.ServletContext.log(...) to write + log messages are handled by internal Tomcat logging. Such messages are + logged to the category named +

+
org.apache.catalina.core.ContainerBase.[${engine}].[${host}].[${context}]
+

+ This logging is performed according to the Tomcat logging configuration. You + cannot overwrite it in a web application. +

+ +

+ The Servlets logging API predates the java.util.logging API + that is now provided by Java. As such, it does not offer you much options. + E.g., you cannot control the log levels. It can be noted, though, that + in Apache Tomcat implementation the calls to ServletContext.log(String) + or GenericServlet.log(String) are logged at the INFO level. + The calls to ServletContext.log(String, Throwable) or + GenericServlet.log(String, Throwable) + are logged at the SEVERE level. +

+ +
+ +

Console

+ +

+ When running Tomcat on unixes, the console output is usually redirected + to the file named catalina.out. The name is configurable + using an environment variable. (See the startup scripts). + Whatever is written to System.err/out will be caught into + that file. That may include: +

+ +
    +
  • Uncaught exceptions printed by java.lang.ThreadGroup.uncaughtException(..)
  • +
  • Thread dumps, if you requested them via a system signal
  • +
+ +

+ When running as a service on Windows, the console output is also caught + and redirected, but the file names are different. +

+ +

+ The default logging configuration in Apache Tomcat writes the same + messages to the console and to a log file. This is great when using + Tomcat for development, but usually is not needed in production. +

+ +

+ Old applications that still use System.out or System.err + can be tricked by setting swallowOutput attribute on a + Context. If the attribute is set to + true, the calls to System.out/err during request + processing will be intercepted, and their output will be fed to the + logging subsystem using the + javax.servlet.ServletContext.log(...) calls.
+ Note, that the swallowOutput feature is + actually a trick, and it has its limitations. + It works only with direct calls to System.out/err, + and only during request processing cycle. It may not work in other + threads that might be created by the application. It cannot be used to + intercept logging frameworks that themselves write to the system streams, + as those start early and may obtain a direct reference to the streams + before the redirection takes place. +

+ +
+ +

Access logging

+ +

+ Access logging is a related but different feature, which is + implemented as a Valve. It uses self-contained + logic to write its log files. The essential requirement for + access logging is to handle a large continuous stream of data + with low overhead, so it only uses Apache Commons Logging for + its own debug messages. This implementation approach avoids + additional overhead and potentially complex configuration. + Please refer to the Valves + documentation for more details on its configuration, including + the various report formats. +

+ +
+ +

Using java.util.logging (default)

+ +

+ The default implementation of java.util.logging provided in the JDK is too + limited to be useful. The key limitation is the inability to have per-web + application logging, as the configuration is per-VM. As a result, Tomcat + will, in the default configuration, replace the default LogManager + implementation with a container friendly implementation called JULI, which + addresses these shortcomings. +

+

+ JULI supports the same configuration mechanisms as the standard JDK + java.util.logging, using either a programmatic approach, or + properties files. The main difference is that per-classloader properties + files can be set (which enables easy redeployment friendly webapp + configuration), and the properties files support extended constructs which + allows more freedom for defining handlers and assigning them to loggers. +

+

+ JULI is enabled by default, and supports per classloader configuration, in + addition to the regular global java.util.logging configuration. This means + that logging can be configured at the following layers: +

+
    +
  • Globally. That is usually done in the + ${catalina.base}/conf/logging.properties file. + The file is specified by the java.util.logging.config.file + System property which is set by the startup scripts. + If it is not readable or is not configured, the default is to use the + ${java.home}/lib/logging.properties file in the JRE. +
  • +
  • In the web application. The file will be + WEB-INF/classes/logging.properties +
  • +
+

+ The default logging.properties in the JRE specifies a + ConsoleHandler that routes logging to System.err. + The default conf/logging.properties in Apache Tomcat also + adds several FileHandlers that write to files. +

+

+ A handler's log level threshold is INFO by default and can be set using + SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST or ALL. + You can also target specific packages to collect logging from and specify + a level. +

+

+ To enable debug logging for part of Tomcat's internals, you should + configure both the appropriate logger(s) and the appropriate handler(s) to + use the FINEST or ALL level. e.g.: +

+
org.apache.catalina.session.level=ALL
+java.util.logging.ConsoleHandler.level=ALL
+

+ When enabling debug logging it is recommended that it is enabled for the + narrowest possible scope as debug logging can generate large amounts of + information. +

+

+ The configuration used by JULI is the same as the one supported by plain + java.util.logging, but uses a few extensions to allow better + flexibility in configuring loggers and handlers. The main differences are: +

+
    +
  • A prefix may be added to handler names, so that multiple handlers of a + single class may be instantiated. A prefix is a String which starts with a + digit, and ends with '.'. For example, 22foobar. is a valid + prefix.
  • +
  • System property replacement is performed for property values which + contain ${systemPropertyName}.
  • +
  • If using a class loader that implements the + org.apache.juli.WebappProperties interface (Tomcat's + web application class loader does) then property replacement is also + performed for ${classloader.webappName}, + ${classloader.hostName} and + ${classloader.serviceName} which are replaced with the + web application name, the host name and the service name respectively. +
  • +
  • By default, loggers will not delegate to their parent if they have + associated handlers. This may be changed per logger using the + loggerName.useParentHandlers property, which accepts a + boolean value.
  • +
  • The root logger can define its set of handlers using the + .handlers property.
  • +
  • By default the log files will be kept on the file system forever. + This may be changed per handler using the + handlerName.maxDays property. If the specified value for the + property is <=0 then the log files will be kept on the + file system forever, otherwise they will be kept the specified maximum + days.
  • +
+

+ There are several additional implementation classes, that can be used + together with the ones provided by Java. The notable one is + org.apache.juli.FileHandler. +

+

+ org.apache.juli.FileHandler supports buffering of the + logs. The buffering is not enabled by default. To configure it, use the + bufferSize property of a handler. The value of 0 + uses system default buffering (typically an 8K buffer will be used). A + value of <0 forces a writer flush upon each log write. A + value >0 uses a BufferedOutputStream with the defined + value but note that the system default buffering will also be + applied. +

+

+ Example logging.properties file to be placed in $CATALINA_BASE/conf: +

+
handlers = 1catalina.org.apache.juli.FileHandler, \
+           2localhost.org.apache.juli.FileHandler, \
+           3manager.org.apache.juli.FileHandler, \
+           java.util.logging.ConsoleHandler
+
+.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+1catalina.org.apache.juli.FileHandler.level = FINE
+1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1catalina.org.apache.juli.FileHandler.prefix = catalina.
+
+2localhost.org.apache.juli.FileHandler.level = FINE
+2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+2localhost.org.apache.juli.FileHandler.prefix = localhost.
+
+3manager.org.apache.juli.FileHandler.level = FINE
+3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+3manager.org.apache.juli.FileHandler.prefix = manager.
+3manager.org.apache.juli.FileHandler.bufferSize = 16384
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = \
+   2localhost.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = \
+   3manager.org.apache.juli.FileHandler
+
+# For example, set the org.apache.catalina.util.LifecycleBase logger to log
+# each component that extends LifecycleBase changing state:
+#org.apache.catalina.util.LifecycleBase.level = FINE
+ +

+ Example logging.properties for the servlet-examples web application to be + placed in WEB-INF/classes inside the web application: +

+
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+org.apache.juli.FileHandler.level = FINE
+org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+org.apache.juli.FileHandler.prefix = ${classloader.webappName}.
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+ + +

Documentation references

+

See the following resources for additional information:

+ +
+ +

Considerations for production usage

+

You may want to take note of the following:

+
    +
  • Consider removing ConsoleHandler from configuration. By + default (thanks to the .handlers setting) logging goes both + to a FileHandler and to a ConsoleHandler. The + output of the latter one is usually captured into a file, such as + catalina.out. Thus you end up with two copies of the same + messages.
  • +
  • Consider removing FileHandlers for the applications + that you do not use. E.g., the one for host-manager.
  • +
  • The handlers by default use the system default encoding to write + the log files. It can be configured with encoding property. + See Javadoc for details.
  • +
  • Consider configuring an + Access log.
  • +
+
+ +

Using Log4j

+

+ This section explains how to configure Tomcat to use + log4j rather than + java.util.logging for all Tomcat's internal logging. +

+

Note: The steps described in this section are needed + when you want to reconfigure Tomcat to use Apache log4j for its own + logging. These steps are not needed if you just want + to use log4j in your own web application. — In that case, just + put log4j.jar and log4j.properties into + WEB-INF/lib and WEB-INF/classes + of your web application. +

+

+ The following steps describe configuring log4j to output Tomcat's + internal logging. +

+ +
    +
  1. Create a file called log4j.properties with the + following content and save it into $CATALINA_BASE/lib
  2. +
+

+log4j.rootLogger = INFO, CATALINA
+
+# Define all the appenders
+log4j.appender.CATALINA = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.CATALINA.File = ${catalina.base}/logs/catalina
+log4j.appender.CATALINA.Append = true
+log4j.appender.CATALINA.Encoding = UTF-8
+# Roll-over the log once per day
+log4j.appender.CATALINA.DatePattern = '.'yyyy-MM-dd'.log'
+log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout
+log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
+
+log4j.appender.LOCALHOST = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.LOCALHOST.File = ${catalina.base}/logs/localhost
+log4j.appender.LOCALHOST.Append = true
+log4j.appender.LOCALHOST.Encoding = UTF-8
+log4j.appender.LOCALHOST.DatePattern = '.'yyyy-MM-dd'.log'
+log4j.appender.LOCALHOST.layout = org.apache.log4j.PatternLayout
+log4j.appender.LOCALHOST.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
+
+log4j.appender.MANAGER = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.MANAGER.File = ${catalina.base}/logs/manager
+log4j.appender.MANAGER.Append = true
+log4j.appender.MANAGER.Encoding = UTF-8
+log4j.appender.MANAGER.DatePattern = '.'yyyy-MM-dd'.log'
+log4j.appender.MANAGER.layout = org.apache.log4j.PatternLayout
+log4j.appender.MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
+
+log4j.appender.HOST-MANAGER = org.apache.log4j.DailyRollingFileAppender
+log4j.appender.HOST-MANAGER.File = ${catalina.base}/logs/host-manager
+log4j.appender.HOST-MANAGER.Append = true
+log4j.appender.HOST-MANAGER.Encoding = UTF-8
+log4j.appender.HOST-MANAGER.DatePattern = '.'yyyy-MM-dd'.log'
+log4j.appender.HOST-MANAGER.layout = org.apache.log4j.PatternLayout
+log4j.appender.HOST-MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
+
+log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.Encoding = UTF-8
+log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
+
+# Configure which loggers log to which appenders
+log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost] = INFO, LOCALHOST
+log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager] =\
+  INFO, MANAGER
+log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager] =\
+  INFO, HOST-MANAGER
+
    +
  1. Download Log4J + (Tomcat requires v1.2.x).
  2. + +
  3. Download or build tomcat-juli.jar and + tomcat-juli-adapters.jar that are available as an "extras" + component for Tomcat. See Additional Components + documentation for details.

    +

    This tomcat-juli.jar differs from the default one. It + contains the full Apache Commons Logging implementation and thus is + able to discover the presence of log4j and configure itself.

    +
  4. + +
  5. If you want to configure Tomcat to use log4j globally:

    +
      +
    • Put log4j.jar and + tomcat-juli-adapters.jar from "extras" into + $CATALINA_HOME/lib.
    • +
    • Replace $CATALINA_HOME/bin/tomcat-juli.jar with + tomcat-juli.jar from "extras".
    • +
    +
  6. + +
  7. If you are running Tomcat with separate + $CATALINA_HOME and $CATALINA_BASE and want to + configure to use log4j in a single $CATALINA_BASE only:

    + +
      +
    • Create $CATALINA_BASE/bin and + $CATALINA_BASE/lib directories if they do not exist. +
    • +
    • Put log4j.jar and + tomcat-juli-adapters.jar from "extras" into + $CATALINA_BASE/lib
    • +
    • Put tomcat-juli.jar from "extras" as + $CATALINA_BASE/bin/tomcat-juli.jar
    • +
    • If you are running with a + security manager, you + would need to edit the + $CATALINA_BASE/conf/catalina.policy file to adjust + it to using a different copy of tomcat-juli.jar.
    • +
    + +

    Note: This works because libraries, if they exist in + $CATALINA_BASE, are loaded in preference to the same + library in $CATALINA_HOME.

    + +

    Note: tomcat-juli.jar is loaded from $CATALINA_BASE/bin + not $CATALINA_BASE/lib as it is loaded as part of the + bootstrap process and all the bootstrap classes are loaded from bin.

    +
  8. + +
  9. Delete $CATALINA_BASE/conf/logging.properties to + prevent java.util.logging generating zero length log files.

  10. + +
  11. Start Tomcat

  12. +
+ +

+ This log4j configuration mirrors the default java.util.logging setup + that ships with Tomcat: both the manager and host-manager apps get an + individual log file, and everything else goes to the "catalina.log" log + file. Each file is rolled-over once per day. +

+ +

+ You can (and should) be more picky about which packages to include + in the logging. Tomcat defines loggers by Engine and Host names. + For example, for a more detailed Catalina localhost log, add this to the + end of the log4j.properties above. Note that there are known issues with + using this naming convention (with square brackets) in log4j XML based + configuration files, so we recommend you use a properties file as + described until a future version of log4j allows this convention. +

+
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG
+log4j.logger.org.apache.catalina.core=DEBUG
+log4j.logger.org.apache.catalina.session=DEBUG
+ +

+ Be warned: a level of DEBUG will produce megabytes of logging and slow + startup of Tomcat. This level should be used sparingly when debugging of + internal Tomcat operations is required. +

+ +

+ Your web applications should certainly use their own log4j configuration. + This is valid with the above configuration. You would place a + similar log4j.properties file in your web application's WEB-INF/classes + directory, and log4jx.y.z.jar into WEB-INF/lib. Then specify your package + level logging. This is a basic setup of log4j which does *not* require + Commons-Logging, and you should consult the + log4j + documentation for more options. This page is intended only as a + bootstrapping guide. +

+ +

Additional notes

+
    +
  • This exposes log4j libraries to the web applications through the + Common classloader. See class loading + documentation for details.

    +

    Because of that, the web applications and libraries using + Apache Commons Logging + library are likely to automatically choose log4j as the underlying + logging implementation.

  • + +
  • The java.util.logging API is still available for + those web applications that use it directly. The + ${catalina.base}/conf/logging.properties file is still + referenced by Tomcat startup scripts. For more information, see the + subsections of the Introduction to + this page.

    +

    Removal of ${catalina.base}/conf/logging.properties + file, mentioned as one of the steps above, causes + java.util.logging to fallback to the default + configuration for the JRE, which is to use a ConsoleHandler + and therefore not create any standard log files. You should + confirm that all your log files are being created by log4j + before disabling the standard mechanism.

  • + +
  • The Access Log Valve and + ExtendedAccessLogValve use their own self-contained + logging implementation, so they + cannot be configured to use log4j. + Refer to Valves + for specific configuration details.

  • +
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/manager-howto.html b/test.dockerapp/tomcat/webapps/docs/manager-howto.html new file mode 100644 index 0000000..01d84f2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/manager-howto.html @@ -0,0 +1,1405 @@ + +Apache Tomcat 8 (8.0.53) - Manager App HOW-TO

Manager App HOW-TO

Table of Contents

Introduction

+ +

In many production environments, it is very useful to have the capability +to deploy a new web application, or undeploy an existing one, without having +to shut down and restart the entire container. In addition, you can request +an existing application to reload itself, even if you have not declared it +to be reloadable in the Tomcat server +configuration file.

+ +

To support these capabilities, Tomcat includes a web application +(installed by default on context path /manager) that supports +the following functions:

+
    +
  • Deploy a new web application from the uploaded contents of a WAR file.
  • +
  • Deploy a new web application, on a specified context path, from the + server file system.
  • +
  • List the currently deployed web applications, as well as the + sessions that are currently active for those web apps.
  • +
  • Reload an existing web application, to reflect changes in the + contents of /WEB-INF/classes or /WEB-INF/lib. +
  • +
  • List the OS and JVM property values.
  • +
  • List the available global JNDI resources, for use in deployment + tools that are preparing <ResourceLink> elements + nested in a <Context> deployment description.
  • +
  • Start a stopped application (thus making it available again).
  • +
  • Stop an existing application (so that it becomes unavailable), but + do not undeploy it.
  • +
  • Undeploy a deployed web application and delete its document base + directory (unless it was deployed from file system).
  • +
+ +

A default Tomcat installation includes the Manager. To add an instance of the +Manager web application Context to a new host install the +manager.xml context configuration file in the +$CATALINA_BASE/conf/[enginename]/[hostname] folder. Here is an +example:

+
<Context privileged="true" antiResourceLocking="false"
+         docBase="${catalina.home}/webapps/manager">
+  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
+         allow="127\.0\.0\.1" />
+</Context>
+ +

If you have Tomcat configured to support multiple virtual hosts +(websites) you would need to configure a Manager for each.

+ +

There are three ways to use the Manager web application.

+
    +
  • As an application with a user interface you use in your browser. +Here is an example URL where you can replace localhost with +your website host name: http://localhost:8080/manager/html .
  • +
  • A minimal version using HTTP requests only which is suitable for use +by scripts setup by system administrators. Commands are given as part of the +request URI, and responses are in the form of simple text that can be easily +parsed and processed. See +Supported Manager Commands for more information.
  • +
  • A convenient set of task definitions for the Ant +(version 1.4 or later) build tool. See +Executing Manager Commands +With Ant for more information.
  • +
+ +

Configuring Manager Application Access

+ + +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ + +

It would be quite unsafe to ship Tomcat with default settings that allowed +anyone on the Internet to execute the Manager application on your server. +Therefore, the Manager application is shipped with the requirement that anyone +who attempts to use it must authenticate themselves, using a username and +password that have one of manager-xxx roles associated with +them (the role name depends on what functionality is required). +Further, there is no username in the default users file +($CATALINA_BASE/conf/tomcat-users.xml) that is assigned to those +roles. Therefore, access to the Manager application is completely disabled +by default.

+ +

You can find the role names in the web.xml file of the Manager +web application. The available roles are:

+ +
    +
  • manager-gui — Access to the HTML interface.
  • +
  • manager-status — Access to the "Server Status" + page only.
  • +
  • manager-script — Access to the tools-friendly + plain text interface that is described in this document, + and to the "Server Status" page.
  • +
  • manager-jmx — Access to JMX proxy interface + and to the "Server Status" page.
  • +
+ +

The HTML interface is protected against CSRF (Cross-Site Request Forgery) +attacks, but the text and JMX interfaces cannot be protected. It means that +users who are allowed access to the text and JMX interfaces have to be cautious +when accessing the Manager application with a web browser. +To maintain the CSRF protection:

+ +
    +
  • If you use web browser to access the Manager application using + a user that has either manager-script or + manager-jmx roles (for example for testing + the plain text or JMX interfaces), you MUST close all windows + of the browser afterwards to terminate the session. + If you do not close the browser and visit other sites, you may become + victim of a CSRF attack.
  • +
  • It is recommended to never grant + the manager-script or manager-jmx + roles to users that have the manager-gui role.
  • +
+ +

Note that JMX proxy interface is effectively low-level root-like +administrative interface of Tomcat. One can do a lot, if he knows +what commands to call. You should be cautious when enabling the +manager-jmx role.

+ +

To enable access to the Manager web application, you must either create +a new username/password combination and associate one of the +manager-xxx roles with it, or add a +manager-xxx role +to some existing username/password combination. +As the majority of this document describes the using the text interface, this +example will use the role name manager-script. +Exactly how the usernames/passwords are configured depends on which +Realm implementation you are using:

+
    +
  • UserDatabaseRealm plus MemoryUserDatabase, or MemoryRealm + — The UserDatabaseRealm and MemoryUserDatabase are + configured in the default $CATALINA_BASE/conf/server.xml. + Both MemoryUserDatabase and MemoryRealm read an + XML-format file by default stored at + $CATALINA_BASE/conf/tomcat-users.xml, which can be + edited with any text editor. This file contains an XML + <user> for each individual user, which might + look something like this: +
    <user username="craigmcc" password="secret" roles="standard,manager-script" />
    + which defines the username and password used by this individual to + log on, and the role names he or she is associated with. You can + add the manager-script role to the comma-delimited + roles attribute for one or more existing users, and/or + create new users with that assigned role.
  • +
  • DataSourceRealm or JDBCRealm + — Your user and role information is stored in + a database accessed via JDBC. Add the manager-script role + to one or more existing users, and/or create one or more new users + with this role assigned, following the standard procedures for your + environment.
  • +
  • JNDIRealm — Your user and role information is stored in + a directory server accessed via LDAP. Add the + manager-script role to one or more existing users, + and/or create one or more new users with this role assigned, following + the standard procedures for your environment.
  • +
+ +

The first time you attempt to issue one of the Manager commands +described in the next section, you will be challenged to log on using +BASIC authentication. The username and password you enter do not matter, +as long as they identify a valid user in the users database who possesses +the role manager-script.

+ +

In addition to the password restrictions, access to the Manager web +application can be restricted by the remote IP address or host +by adding a RemoteAddrValve or RemoteHostValve. +See valves documentation +for details. Here is +an example of restricting access to the localhost by IP address:

+
<Context privileged="true">
+         <Valve className="org.apache.catalina.valves.RemoteAddrValve"
+                allow="127\.0\.0\.1"/>
+</Context>
+ +

HTML User-friendly Interface

+ +

The user-friendly HTML interface of Manager web application is located at

+ +
http://{host}:{port}/manager/html
+ +

As has already been mentioned above, you need manager-gui +role to be allowed to access it. There is a separate document that provides +help on this interface. See:

+ + + +

The HTML interface is protected against CSRF (Cross-Site Request Forgery) +attacks. Each access to the HTML pages generates a random token, which is +stored in your session and is included in all links on the page. If your next +action does not have correct value of the token, the action will be denied. +If the token has expired you can start again from the main page or +List Applications page of Manager.

+ +

Supported Manager Commands

+ +

All commands that the Manager application knows how to process are +specified in a single request URI like this:

+
http://{host}:{port}/manager/text/{command}?{parameters}
+

where {host} and {port} represent the hostname +and port number on which Tomcat is running, {command} +represents the Manager command you wish to execute, and +{parameters} represents the query parameters +that are specific to that command. In the illustrations below, customize +the host and port appropriately for your installation.

+ +

The commands are usually executed by HTTP GET requests. The +/deploy command has a form that is executed by an HTTP PUT request.

+ +

Common Parameters

+ +

Most commands accept one or more of the following query parameters:

+
    +
  • path - The context path (including the leading slash) + of the web application you are dealing with. To select the ROOT web + application, specify "/". NOTE: + It is not possible to perform administrative commands on the + Manager application itself.
  • +
  • version - The version of this web application as used by + the parallel deployment feature. If you + use parallel deployment wherever a path is required you must specify a + version in addition to the path and it is the combination of path and + version that must be unique rather than just the path.
  • +
  • war - URL of a web application archive (WAR) file, or + pathname of a directory which contains the web application, or a + Context configuration ".xml" file. You can use URLs in any of the + following formats: +
      +
    • file:/absolute/path/to/a/directory - The absolute + path of a directory that contains the unpacked version of a web + application. This directory will be attached to the context path + you specify without any changes.
    • +
    • file:/absolute/path/to/a/webapp.war - The absolute + path of a web application archive (WAR) file. This is valid + only for the /deploy command, and is + the only acceptable format to that command.
    • +
    • file:/absolute/path/to/a/context.xml - The + absolute path of a web application Context configuration ".xml" + file which contains the Context configuration element.
    • +
    • directory - The directory name for the web + application context in the Host's application base directory.
    • +
    • webapp.war - The name of a web application war file + located in the Host's application base directory.
    • +
  • +
+ +

Each command will return a response in text/plain format +(i.e. plain ASCII with no HTML markup), making it easy for both humans and +programs to read). The first line of the response will begin with either +OK or FAIL, indicating whether the requested +command was successful or not. In the case of failure, the rest of the first +line will contain a description of the problem that was encountered. Some +commands include additional lines of information as described below.

+ +

Internationalization Note - The Manager application looks up +its message strings in resource bundles, so it is possible that the strings +have been translated for your platform. The examples below show the English +version of the messages.

+ +
+ +

Deploy A New Application Archive (WAR) Remotely

+ +
http://localhost:8080/manager/text/deploy?path=/foo
+ +

Upload the web application archive (WAR) file that is specified as the +request data in this HTTP PUT request, install it into the appBase +directory of our corresponding virtual host, and start, deriving the name for +the WAR file added to the appBase from the specified path. The +application can later be undeployed (and the corresponding WAR file removed) by +use of the /undeploy command.

+ +

This command is executed by an HTTP PUT request.

+ +

The .WAR file may include Tomcat specific deployment configuration, by +including a Context configuration XML file in +/META-INF/context.xml.

+ +

URL parameters include:

+
    +
  • update: When set to true, any existing update will be + undeployed first. The default value is set to false.
  • +
  • tag: Specifying a tag name, this allows associating the + deployed webapp with a tag or label. If the web application is undeployed, + it can be later redeployed when needed using only the tag.
  • +
+ +

NOTE - This command is the logical +opposite of the /undeploy command.

+ +

If installation and startup is successful, you will receive a response +like this:

+
OK - Deployed application at context path /foo
+ +

Otherwise, the response will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Application already exists at path /foo +

    The context paths for all currently running web applications must be + unique. Therefore, you must undeploy the existing web + application using this context path, or choose a different context path + for the new one. The update parameter may be specified as + a parameter on the URL, with a value of true to avoid this + error. In that case, an undeploy will be performed on an existing + application before performing the deployment.

    +
  • +
  • Encountered exception +

    An exception was encountered trying to start the new web application. + Check the Tomcat logs for the details, but likely explanations include + problems parsing your /WEB-INF/web.xml file, or missing + classes encountered when initializing application event listeners and + filters.

    +
  • +
+ +
+ +

Deploy A New Application from a Local Path

+ +

Deploy and start a new web application, attached to the specified context +path (which must not be in use by any other web application). +This command is the logical opposite of the /undeploy command.

+ +

This command is executed by an HTTP GET request. +There are a number of different ways the deploy command can be used.

+ +

Deploy a previously deployed webapp

+ +
http://localhost:8080/manager/text/deploy?path=/footoo&tag=footag
+ +

This can be used to deploy a previously deployed web application, which +has been deployed using the tag attribute. Note that the work +directory of the Manager webapp will contain the previously deployed WARs; +removing it would make the deployment fail.

+ +
+ +

Deploy a Directory or WAR by URL

+ +

Deploy a web application directory or ".war" file located on the Tomcat +server. If no path is specified, the path and version are derived +from the directory name or the war file name. The war parameter +specifies a URL (including the file: scheme) for either +a directory or a web application archive (WAR) file. The supported syntax for +a URL referring to a WAR file is described on the Javadocs page for the +java.net.JarURLConnection class. Use only URLs that refer to +the entire WAR file.

+ +

In this example the web application located in the directory +/path/to/foo on the Tomcat server is deployed as the +web application context named /footoo.

+
http://localhost:8080/manager/text/deploy?path=/footoo&war=file:/path/to/foo
+ + +

In this example the ".war" file /path/to/bar.war on the +Tomcat server is deployed as the web application context named +/bar. Notice that there is no path parameter +so the context path defaults to the name of the web application archive +file without the ".war" extension.

+
http://localhost:8080/manager/text/deploy?war=file:/path/to/bar.war
+ +
+ +

Deploy a Directory or War from the Host appBase

+ +

Deploy a web application directory or ".war" file located in your Host +appBase directory. The path and optional version are derived from the directory +or war file name.

+ +

In this example the web application located in a sub directory named +foo in the Host appBase directory of the Tomcat server is +deployed as the web application context named /foo. Notice +that the context path used is the name of the web application directory.

+
http://localhost:8080/manager/text/deploy?war=foo
+ + +

In this example the ".war" file bar.war located in your +Host appBase directory on the Tomcat server is deployed as the web +application context named /bar.

+
http://localhost:8080/manager/text/deploy?war=bar.war
+ +
+ +

Deploy using a Context configuration ".xml" file

+ +

If the Host deployXML flag is set to true you can deploy a web +application using a Context configuration ".xml" file and an optional +".war" file or web application directory. The context path +is not used when deploying a web application using a context ".xml" +configuration file.

+ +

A Context configuration ".xml" file can contain valid XML for a +web application Context just as if it were configured in your +Tomcat server.xml configuration file. Here is an +example:

+
<Context path="/foobar" docBase="/path/to/application/foobar">
+</Context>
+ + +

When the optional war parameter is set to the URL +for a web application ".war" file or directory it overrides any +docBase configured in the context configuration ".xml" file.

+ +

Here is an example of deploying an application using a Context +configuration ".xml" file.

+
http://localhost:8080/manager/text/deploy?config=file:/path/context.xml
+ + +

Here is an example of deploying an application using a Context +configuration ".xml" file and a web application ".war" file located +on the server.

+
http://localhost:8080/manager/text/deploy
+ ?config=file:/path/context.xml&war=file:/path/bar.war
+ +
+ +

Deployment Notes

+ +

If the Host is configured with unpackWARs=true and you deploy a war +file, the war will be unpacked into a directory in your Host appBase +directory.

+ +

If the application war or directory is installed in your Host appBase +directory and either the Host is configured with autoDeploy=true or the +Context path must match the directory name or war file name without the +".war" extension.

+ +

For security when untrusted users can manage web applications, the +Host deployXML flag can be set to false. This prevents untrusted users +from deploying web applications using a configuration XML file and +also prevents them from deploying application directories or ".war" +files located outside of their Host appBase.

+ +
+ +

Deploy Response

+ +

If installation and startup is successful, you will receive a response +like this:

+
OK - Deployed application at context path /foo
+ +

Otherwise, the response will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Application already exists at path /foo +

    The context paths for all currently running web applications must be + unique. Therefore, you must undeploy the existing web + application using this context path, or choose a different context path + for the new one. The update parameter may be specified as + a parameter on the URL, with a value of true to avoid this + error. In that case, an undeploy will be performed on an existing + application before performing the deployment.

    +
  • +
  • Document base does not exist or is not a readable directory +

    The URL specified by the war parameter must identify a + directory on this server that contains the "unpacked" version of a + web application, or the absolute URL of a web application archive (WAR) + file that contains this application. Correct the value specified by + the war parameter.

    +
  • +
  • Encountered exception +

    An exception was encountered trying to start the new web application. + Check the Tomcat logs for the details, but likely explanations include + problems parsing your /WEB-INF/web.xml file, or missing + classes encountered when initializing application event listeners and + filters.

    +
  • +
  • Invalid application URL was specified +

    The URL for the directory or web application that you specified + was not valid. Such URLs must start with file:, and URLs + for a WAR file must end in ".war".

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character. To reference the + ROOT web application use "/".

    +
  • +
  • Context path must match the directory or WAR file name: +

    If the application war or directory is installed in your Host appBase + directory and either the Host is configured with autoDeploy=true the + Context path must match the directory name or war file name without + the ".war" extension.

    +
  • +
  • Only web applications in the Host web application directory can + be installed +

    + If the Host deployXML flag is set to false this error will happen + if an attempt is made to deploy a web application directory or + ".war" file outside of the Host appBase directory. +

  • +
+ +
+
+ +

List Currently Deployed Applications

+ +
http://localhost:8080/manager/text/list
+ +

List the context paths, current status (running or +stopped), and number of active sessions for all currently +deployed web applications. A typical response immediately +after starting Tomcat might look like this:

+
OK - Listed applications for virtual host localhost
+/webdav:running:0:webdav
+/examples:running:0:examples
+/manager:running:0:manager
+/:running:0:ROOT
+/test:running:0:test##2
+/test:running:0:test##1
+ +
+ +

Reload An Existing Application

+ +
http://localhost:8080/manager/text/reload?path=/examples
+ +

Signal an existing application to shut itself down and reload. This can +be useful when the web application context is not reloadable and you have +updated classes or property files in the /WEB-INF/classes +directory or when you have added or updated jar files in the +/WEB-INF/lib directory. +

+ +

If this command succeeds, you will see a response like this:

+
OK - Reloaded application at context path /examples
+ +

Otherwise, the response will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to restart the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character. To reference the + ROOT web application use "/".

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified +

    + The path parameter is required. +

  • +
  • Reload not supported on WAR deployed at path /foo +

    + Currently, application reloading (to pick up changes to the classes or + web.xml file) is not supported when a web application is + deployed directly from a WAR file. It only works when the web application + is deployed from an unpacked directory. If you are using a WAR file, + you should undeploy and then deploy or + deploy with the update parameter the + application again to pick up your changes. +

  • +
+ +
+ +

List OS and JVM Properties

+ +
http://localhost:8080/manager/text/serverinfo
+ +

Lists information about the Tomcat version, OS, and JVM properties.

+ +

If an error occurs, the response will start with FAIL and +include an error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to enumerate the system properties. + Check the Tomcat logs for the details.

    +
  • +
+ +
+ +

List Available Global JNDI Resources

+ +
http://localhost:8080/manager/text/resources[?type=xxxxx]
+ +

List the global JNDI resources that are available for use in resource +links for context configuration files. If you specify the type +request parameter, the value must be the fully qualified Java class name of +the resource type you are interested in (for example, you would specify +javax.sql.DataSource to acquire the names of all available +JDBC data sources). If you do not specify the type request +parameter, resources of all types will be returned.

+ +

Depending on whether the type request parameter is specified +or not, the first line of a normal response will be:

+
OK - Listed global resources of all types
+

or

+
OK - Listed global resources of type xxxxx
+

followed by one line for each resource. Each line is composed of fields +delimited by colon characters (":"), as follows:

+
    +
  • Global Resource Name - The name of this global JNDI resource, + which would be used in the global attribute of a + <ResourceLink> element.
  • +
  • Global Resource Type - The fully qualified Java class name of + this global JNDI resource.
  • +
+ +

If an error occurs, the response will start with FAIL and +include an error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to enumerate the global JNDI + resources. Check the Tomcat logs for the details.

    +
  • +
  • No global JNDI resources are available +

    The Tomcat server you are running has been configured without + global JNDI resources.

    +
  • +
+ + +
+ +

Session Statistics

+ +
http://localhost:8080/manager/text/sessions?path=/examples
+ +

Display the default session timeout for a web application, and the +number of currently active sessions that fall within one-minute ranges of +their actual timeout times. For example, after restarting Tomcat and then +executing one of the JSP samples in the /examples web app, +you might get something like this:

+ +
OK - Session information for application at context path /examples
+Default maximum session inactive interval 30 minutes
+<1 minutes: 1 sessions
+1 - <2 minutes: 1 sessions
+ +
+ +

Expire Sessions

+ +
http://localhost:8080/manager/text/expire?path=/examples&idle=num
+ +

Display the session statistics (like the above /sessions +command) and expire sessions that are idle for longer than num +minutes. To expire all sessions, use &idle=0 .

+ +
OK - Session information for application at context path /examples
+Default maximum session inactive interval 30 minutes
+1 - <2 minutes: 1 sessions
+3 - <4 minutes: 1 sessions
+>0 minutes: 2 sessions were expired
+ +

Actually /sessions and /expire are synonyms for +the same command. The difference is in the presence of idle +parameter.

+ +
+ +

Start an Existing Application

+ +
http://localhost:8080/manager/text/start?path=/examples
+ +

Signal a stopped application to restart, and make itself available again. +Stopping and starting is useful, for example, if the database required by +your application becomes temporarily unavailable. It is usually better to +stop the web application that relies on this database rather than letting +users continuously encounter database exceptions.

+ +

If this command succeeds, you will see a response like this:

+
OK - Started application at context path /examples
+ +

Otherwise, the response will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to start the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character. To reference the + ROOT web application use "/".

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified +

    + The path parameter is required. +

  • +
+ +
+ +

Stop an Existing Application

+ +
http://localhost:8080/manager/text/stop?path=/examples
+ +

Signal an existing application to make itself unavailable, but leave it +deployed. Any request that comes in while an application is +stopped will see an HTTP error 404, and this application will show as +"stopped" on a list applications command.

+ +

If this command succeeds, you will see a response like this:

+
OK - Stopped application at context path /examples
+ +

Otherwise, the response will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to stop the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character. To reference the + ROOT web application use "/".

    +
  • +
  • No context exists for path /foo +

    There is no deployed application on the context path + that you specified.

    +
  • +
  • No context path was specified + The path parameter is required. +
  • +
+ +
+ + +

Undeploy an Existing Application

+ +
http://localhost:8080/manager/text/undeploy?path=/examples
+ +

WARNING - This command will delete any web +application artifacts that exist within appBase directory +(typically "webapps") for this virtual host. +This will delete the application .WAR, if present, +the application directory resulting either from a deploy in unpacked form +or from .WAR expansion as well as the XML Context definition from +$CATALINA_BASE/conf/[enginename]/[hostname]/ directory. +If you simply want to take an application +out of service, you should use the /stop command instead.

+ +

Signal an existing application to gracefully shut itself down, and +remove it from Tomcat (which also makes this context path available for +reuse later). In addition, the document root directory is removed, if it +exists in the appBase directory (typically "webapps") for +this virtual host. This command is the logical opposite of the +/deploy command.

+ +

If this command succeeds, you will see a response like this:

+
OK - Undeployed application at context path /examples
+ +

Otherwise, the response will start with FAIL and include an +error message. Possible causes for problems include:

+
    +
  • Encountered exception +

    An exception was encountered trying to undeploy the web application. + Check the Tomcat logs for the details.

    +
  • +
  • Invalid context path was specified +

    The context path must start with a slash character. To reference the + ROOT web application use "/".

    +
  • +
  • No context exists named /foo +

    There is no deployed application with the name that you specified.

    +
  • +
  • No context path was specified + The path parameter is required. +
  • +
+ +
+ +

Finding memory leaks

+ +
http://localhost:8080/manager/text/findleaks[?statusLine=[true|false]]
+ +

The find leaks diagnostic triggers a full garbage collection. It +should be used with extreme caution on production systems.

+ +

The find leaks diagnostic attempts to identify web applications that have +caused memory leaks when they were stopped, reloaded or undeployed. Results +should always be confirmed +with a profiler. The diagnostic uses additional functionality provided by the +StandardHost implementation. It will not work if a custom host is used that +does not extend StandardHost.

+ +

Explicitly triggering a full garbage collection from Java code is documented +to be unreliable. Furthermore, depending on the JVM used, there are options to +disable explicit GC triggering, like -XX:+DisableExplicitGC. +If you want to make sure, that the diagnostics were successfully running a full +GC, you will need to check using tools like GC logging, JConsole or similar.

+ +

If this command succeeds, you will see a response like this:

+
/leaking-webapp
+ +

If you wish to see a status line included in the response then include the +statusLine query parameter in the request with a value of +true.

+ +

Each context path for a web application that was stopped, reloaded or +undeployed, but which classes from the previous runs are still loaded in memory, +thus causing a memory leak, will be listed on a new line. If an application +has been reloaded several times, it may be listed several times.

+ +

If the command does not succeed, the response will start with +FAIL and include an error message.

+ +
+ +

Connector SSL/TLS diagnostics

+ +
http://localhost:8080/manager/text/sslConnectorCiphers
+ +

The SSL Connector/Ciphers diagnostic lists the SSL/TLS ciphers that are currently +configured for each connector. For BIO and NIO, the names of the individual +cipher suites are listed. For APR, the value of SSLCipherSuite is returned.

+ +

The response will look something like this:

+
OK - Connector / SSL Cipher information
+Connector[HTTP/1.1-8080]
+  SSL is not enabled for this connector
+Connector[HTTP/1.1-8443]
+  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+  TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+  ...
+ +
+ +

Thread Dump

+ +
http://localhost:8080/manager/text/threaddump
+ +

Write a JVM thread dump.

+ +

The response will look something like this:

+
OK - JVM thread dump
+2014-12-08 07:24:40.080
+Full thread dump Java HotSpot(TM) Client VM (25.25-b02 mixed mode):
+
+"http-nio-8080-exec-2" Id=26 cpu=46800300 ns usr=46800300 ns blocked 0 for -1 ms waited 0 for -1 ms
+   java.lang.Thread.State: RUNNABLE
+        locks java.util.concurrent.ThreadPoolExecutor$Worker@1738ad4
+        at sun.management.ThreadImpl.dumpThreads0(Native Method)
+        at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
+        at org.apache.tomcat.util.Diagnostics.getThreadDump(Diagnostics.java:440)
+        at org.apache.tomcat.util.Diagnostics.getThreadDump(Diagnostics.java:409)
+        at org.apache.catalina.manager.ManagerServlet.threadDump(ManagerServlet.java:557)
+        at org.apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:371)
+        at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
+        at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
+...
+
+ +
+ +

VM Info

+ +
http://localhost:8080/manager/text/vminfo
+ +

Write some diagnostic information about Java Virtual Machine.

+ +

The response will look something like this:

+
OK - VM info
+2014-12-08 07:27:32.578
+Runtime information:
+  vmName: Java HotSpot(TM) Client VM
+  vmVersion: 25.25-b02
+  vmVendor: Oracle Corporation
+  specName: Java Virtual Machine Specification
+  specVersion: 1.8
+  specVendor: Oracle Corporation
+  managementSpecVersion: 1.2
+  name: ...
+  startTime: 1418012458849
+  uptime: 393855
+  isBootClassPathSupported: true
+
+OS information:
+...
+
+ +
+ +

Save Configuration

+ +
http://localhost:8080/manager/text/save
+ +

If specified without any parameters, this command saves the current +configuration of the server to server.xml. The existing file will be renamed as +a backup if required.

+ +

If specified with a path parameter that matches the path of +a deployed web application then the configuration for that web application will +be saved to an appropriately named context.xml file in the xmlBase +for the current Host.

+ +

To use the command a StoreConfig MBean must be present. Typically this is +configured using the StoreConfigLifecycleListener. +

+ +

If the command does not succeed, the response will start with +FAIL and include an error message.

+ +
+ +

Server Status

+ +

From the following links you can view Status information about the server. +Any one of manager-xxx roles allows access to this page.

+ +
http://localhost:8080/manager/status
+http://localhost:8080/manager/status/all
+ +

Displays server status information in HTML format.

+ +
http://localhost:8080/manager/status?XML=true
+http://localhost:8080/manager/status/all?XML=true
+ +

Displays server status information in XML format.

+ +

First, you have the server and JVM version number, JVM provider, OS name +and number followed by the architecture type.

+ +

Second, there is information about the memory usage of the JVM.

+ +

Then, there is information about the Tomcat AJP and HTTP connectors. +The same information is available for both of them : +

+
    +
  • Threads information : Max threads, min and max spare threads, + current thread count and current thread busy.

  • +
  • Request information : Max processing time and processing time, + request and error count, bytes received and sent.

  • +
  • A table showing Stage, Time, Bytes Sent, Bytes Receive, Client, + VHost and Request. All existing threads are listed in the table. + Here is the list of the possible thread stages :

    +
      +
    • "Parse and Prepare Request" : The request headers are + being parsed or the necessary preparation to read the request body (if + a transfer encoding has been specified) is taking place.

    • +
    • "Service" : The thread is processing a request and + generating the response. This stage follows the "Parse and Prepare + Request" stage and precedes the "Finishing" stage. There is always at + least one thread in this stage (the server-status page).

    • +
    • "Finishing" : The end of the request processing. Any + remainder of the response still in the output buffers is sent to the + client. This stage is followed by "Keep-Alive" if it is appropriate to + keep the connection alive or "Ready" if "Keep-Alive" is not + appropriate.

    • +
    • "Keep-Alive" : The thread keeps the connection open to + the client in case the client sends another request. If another request + is received, the next stage will be "Parse and Prepare Request". If no + request is received before the keep alive times out, the connection will + be closed and the next stage will be "Ready".

    • +
    • "Ready" : The thread is at rest and ready to be + used.

    • +
    +
  • +
+ +

If you are using /status/all command, additional information +on each of deployed web applications will be available.

+ +

Using the JMX Proxy Servlet

+ +

What is JMX Proxy Servlet

+ The JMX Proxy Servlet is a lightweight proxy to get and set the + tomcat internals. (Or any class that has been exposed via an MBean) + Its usage is not very user friendly but the UI is + extremely helpful for integrating command line scripts for monitoring + and changing the internals of tomcat. You can do two things with the proxy: + get information and set information. For you to really understand the + JMX Proxy Servlet, you should have a general understanding of JMX. + If you don't know what JMX is, then prepare to be confused. +
+ +

JMX Query command

+

This takes the form:

+
http://webserver/manager/jmxproxy/?qry=STUFF
+

Where STUFF is the JMX query you wish to perform. For example, + here are some queries you might wish to run:

+
    +
  • + qry=*%3Atype%3DRequestProcessor%2C* --> + type=RequestProcessor which will locate all + workers which can process requests and report + their state. +
  • +
  • + qry=*%3Aj2eeType=Servlet%2c* --> + j2eeType=Servlet which return all loaded servlets. +
  • +
  • + qry=Catalina%3Atype%3DEnvironment%2Cresourcetype%3DGlobal%2Cname%3DsimpleValue --> + Catalina:type=Environment,resourcetype=Global,name=simpleValue + which look for a specific MBean by the given name. +
  • +
+

+ You'll need to experiment with this to really understand its capabilities + If you provide no qry parameter, then all of the MBeans will + be displayed. We really recommend looking at the tomcat source code and + understand the JMX spec to get a better understanding of all the queries + you may run. +

+
+ +

JMX Get command

+

+ The JXMProxyServlet also supports a "get" command that you can use to + fetch the value of a specific MBean's attribute. The general form of + the get command is: +

+ +
http://webserver/manager/jmxproxy/?get=BEANNAME&att=MYATTRIBUTE&key=MYKEY
+ +

You must provide the following parameters:

+
    +
  1. get: The full bean name
  2. +
  3. att: The attribute you wish to fetch
  4. +
  5. key: (optional) The key into a CompositeData MBean attribute
  6. +
+

+ If all goes well, then it will say OK, otherwise an error message will + be shown. For example, let's say we wish to fetch the current heap memory + data: +

+ +
http://webserver/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage
+ +

Or, if you only want the "used" key:

+ +
http://webserver/manager/jmxproxy/
+ ?get=java.lang:type=Memory&att=HeapMemoryUsage&key=used
+
+ +

JMX Set command

+

+ Now that you can query an MBean, its time to muck with Tomcat's internals! + The general form of the set command is : +

+
http://webserver/manager/jmxproxy/?set=BEANNAME&att=MYATTRIBUTE&val=NEWVALUE
+

So you need to provide 3 request parameters:

+
    +
  1. set: The full bean name
  2. +
  3. att: The attribute you wish to alter
  4. +
  5. val: The new value
  6. +
+

+ If all goes ok, then it will say OK, otherwise an error message will be + shown. For example, lets say we wish to turn up debugging on the fly for the + ErrorReportValve. The following will set debugging to 10. +

+
http://localhost:8080/manager/jmxproxy/
+ ?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
+ &att=debug&val=10
+

and my result is (YMMV):

+
Result: ok
+ +

Here is what I see if I pass in a bad value. Here is the URL I used, + I try set debugging equal to 'cow':

+
http://localhost:8080/manager/jmxproxy/
+ ?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
+ &att=debug&val=cow
+

When I try that, my result is

+
Error: java.lang.NumberFormatException: For input string: "cow"
+
+ +

JMX Invoke command

+

The invoke command enables methods to be called on MBeans. The + general form of the command is:

+
http://webserver/manager/jmxproxy/
+ ?invoke=BEANNAME&op=METHODNAME&ps=COMMASEPARATEDPARAMETERS
+

For example, to call the findConnectors() method of the + Service use:

+
http://localhost:8080/manager/jmxproxy/
+ ?invoke=Catalina%3Atype%3DService&op=findConnectors&ps=
+
+

Executing Manager Commands With Ant

+ +

In addition to the ability to execute Manager commands via HTTP requests, +as documented above, Tomcat includes a convenient set of Task definitions +for the Ant (version 1.4 or later) build tool. In order to use these +commands, you must perform the following setup operations:

+
    +
  • Download the binary distribution of Ant from + https://ant.apache.org. + You must use version 1.4 or later.
  • +
  • Install the Ant distribution in a convenient directory (called + ANT_HOME in the remainder of these instructions).
  • +
  • Add the $ANT_HOME/bin directory to your PATH + environment variable.
  • +
  • Configure at least one username/password combination in your Tomcat + user database that includes the manager-script role.
  • +
+ +

To use custom tasks within Ant, you must declare them first with an +<import> element. Therefore, your build.xml +file might look something like this:

+ +
<project name="My Application" default="compile" basedir=".">
+
+  <!-- Configure the directory into which the web application is built -->
+  <property name="build"    value="${basedir}/build"/>
+
+  <!-- Configure the context path for this application -->
+  <property name="path"     value="/myapp"/>
+
+  <!-- Configure properties to access the Manager application -->
+  <property name="url"      value="http://localhost:8080/manager/text"/>
+  <property name="username" value="myusername"/>
+  <property name="password" value="mypassword"/>
+
+  <!-- Configure the path to the Tomcat installation -->
+  <property name="catalina.home" value="/usr/local/apache-tomcat"/>
+
+  <!-- Configure the custom Ant tasks for the Manager application -->
+  <import file="${catalina.home}/bin/catalina-tasks.xml"/>
+
+  <!-- Executable Targets -->
+  <target name="compile" description="Compile web application">
+    <!-- ... construct web application in ${build} subdirectory, and
+            generated a ${path}.war ... -->
+  </target>
+
+  <target name="deploy" description="Install web application"
+          depends="compile">
+    <deploy url="${url}" username="${username}" password="${password}"
+            path="${path}" war="file:${build}${path}.war"/>
+  </target>
+
+  <target name="reload" description="Reload web application"
+          depends="compile">
+    <reload  url="${url}" username="${username}" password="${password}"
+            path="${path}"/>
+  </target>
+
+  <target name="undeploy" description="Remove web application">
+    <undeploy url="${url}" username="${username}" password="${password}"
+            path="${path}"/>
+  </target>
+
+</project>
+ +

Note: The definition of the resources task via the import above will override +the resources datatype added in Ant 1.7. If you wish to use the resources +datatype you will need to use Ant's namespace support to modify +catalina-tasks.xml to assign the Tomcat tasks to their own +namespace.

+ +

Now, you can execute commands like ant deploy to deploy the +application to a running instance of Tomcat, or ant reload to +tell Tomcat to reload it. Note also that most of the interesting values in +this build.xml file are defined as replaceable properties, so +you can override their values from the command line. For example, you might +consider it a security risk to include the real manager password in your +build.xml file's source code. To avoid this, omit the password +property, and specify it from the command line:

+
ant -Dpassword=secret deploy
+ +

Tasks output capture

+ +

Using Ant version 1.6.2 or later, +the Catalina tasks offer the option to capture their output in +properties or external files. They support directly the following subset of the +<redirector> type attributes: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionRequired
outputName of a file to which to write the output. If +the error stream is not also redirected to a file or property, it will +appear in this output.No
errorThe file to which the standard error of the +command should be redirected.No
logErrorThis attribute is used when you wish to see +error output in Ant's log and you are redirecting output to a +file/property. The error output will not be included in the output +file/property. If you redirect error with the error or errorProperty +attributes, this will have no effect.No
appendWhether output and error files should be +appended to or overwritten. Defaults to false.No
createemptyfilesWhether output and error files should be created +even when empty. Defaults to true.No
outputpropertyThe name of a property in which the output of +the command should be stored. Unless the error stream is redirected to +a separate file or stream, this property will include the error output.No
errorpropertyThe name of a property in which the standard +error of the command should be stored.No
+ +

A couple of additional attributes can also be specified: +

+ + + + + + + + + + + + + + + + +
AttributeDescriptionRequired
alwaysLogThis attribute is used when you wish to see the +output you are capturing, appearing also in the Ant's log. It must not be +used unless you are capturing task output. +Defaults to false. +This attribute will be supported directly by <redirector> +in Ant 1.6.3No
failonerrorThis attribute is used when you wish to avoid that +any manager command processing error terminates the ant execution. Defaults to true. +It must be set to false, if you want to capture error output, +otherwise execution will terminate before anything can be captured. +
+This attribute acts only on manager command execution, +any wrong or missing command attribute will still cause Ant execution termination. +
No
+ +

They also support the embedded <redirector> element +in which you can specify +its full set of attributes, but input, inputstring and +inputencoding that, even if accepted, are not used because they have +no meaning in this context. +Refer to ant manual for details on +<redirector> element attributes. +

+ +

+Here is a sample build file extract that shows how this output redirection support +can be used: +

+ +
    <target name="manager.deploy"
+        depends="context.status"
+        if="context.notInstalled">
+        <deploy url="${mgr.url}"
+            username="${mgr.username}"
+            password="${mgr.password}"
+            path="${mgr.context.path}"
+            config="${mgr.context.descriptor}"/>
+    </target>
+
+    <target name="manager.deploy.war"
+        depends="context.status"
+        if="context.deployable">
+        <deploy url="${mgr.url}"
+            username="${mgr.username}"
+            password="${mgr.password}"
+            update="${mgr.update}"
+            path="${mgr.context.path}"
+            war="${mgr.war.file}"/>
+    </target>
+
+    <target name="context.status">
+        <property name="running" value="${mgr.context.path}:running"/>
+        <property name="stopped" value="${mgr.context.path}:stopped"/>
+
+        <list url="${mgr.url}"
+            outputproperty="ctx.status"
+            username="${mgr.username}"
+            password="${mgr.password}">
+        </list>
+
+        <condition property="context.running">
+            <contains string="${ctx.status}" substring="${running}"/>
+        </condition>
+        <condition property="context.stopped">
+            <contains string="${ctx.status}" substring="${stopped}"/>
+        </condition>
+        <condition property="context.notInstalled">
+            <and>
+                <isfalse value="${context.running}"/>
+                <isfalse value="${context.stopped}"/>
+            </and>
+        </condition>
+        <condition property="context.deployable">
+            <or>
+                <istrue value="${context.notInstalled}"/>
+                <and>
+                    <istrue value="${context.running}"/>
+                    <istrue value="${mgr.update}"/>
+                </and>
+                <and>
+                    <istrue value="${context.stopped}"/>
+                    <istrue value="${mgr.update}"/>
+                </and>
+            </or>
+        </condition>
+        <condition property="context.undeployable">
+            <or>
+                <istrue value="${context.running}"/>
+                <istrue value="${context.stopped}"/>
+            </or>
+        </condition>
+    </target>
+ +

WARNING: even if it doesn't make many sense, and is always a bad idea, +calling a Catalina task more than once, +badly set Ant tasks depends chains may cause that a task be called +more than once in the same Ant run, even if not intended to. A bit of caution should be exercised when you are +capturing output from that task, because this could lead to something unexpected:

+
    +
  • when capturing in a property you will find in it only the output from the first call, because +Ant properties are immutable and once set they cannot be changed, +
  • +
  • when capturing in a file, each run will overwrite it and you will find in it only the last call +output, unless you are using the append="true" attribute, in which case you will +see the output of each task call appended to the file. +
  • +
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/maven-jars.html b/test.dockerapp/tomcat/webapps/docs/maven-jars.html new file mode 100644 index 0000000..9cff38f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/maven-jars.html @@ -0,0 +1,69 @@ + +Apache Tomcat 8 (8.0.53) - Apache Tomcat - Using Tomcat libraries with Maven

Apache Tomcat - Using Tomcat libraries with Maven

Table of Contents

Using Tomcat libraries With Maven

+

Tomcat Snapshots

+ Tomcat snapshots are located in the + Apache Snapshot Repository. + The official URL is
https://repository.apache.org/content/repositories/snapshots/org/apache/tomcat/
+

+ Snapshots are done periodically, not on a regular basis, but when changes happen and the Tomcat team deems a new snapshot might + useful. +

+
+

Tomcat Releases

+

+ Stable releases are published to the + Central + Maven Repositories. The URL for this is +

+
https://repo2.maven.org/maven2/org/apache/tomcat/
+
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/mbeans-descriptors-howto.html b/test.dockerapp/tomcat/webapps/docs/mbeans-descriptors-howto.html new file mode 100644 index 0000000..f0105a4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/mbeans-descriptors-howto.html @@ -0,0 +1,94 @@ + +Apache Tomcat 8 (8.0.53) - MBeans Descriptors How To

MBeans Descriptors How To

Table of Contents

Introduction

+ +

Tomcat uses JMX MBeans as the technology for implementing +manageability of Tomcat.

+ +

The descriptions of JMX MBeans for Catalina are in the mbeans-descriptors.xml +file in each package.

+ +

You will need to add MBean descriptions for your custom components +in order to avoid a "ManagedBean is not found" exception.

+ +

Adding MBean descriptions

+ +

You may also add MBean descriptions for custom components in +a mbeans-descriptors.xml file, located in the same package as the class files +it describes.

+ +

The permitted syntax for the mbeans-descriptors.xml is defined by +the DTD file.

+ +

The entries for a custom LDAP authentication Realm may look like this:

+ +
  <mbean         name="LDAPRealm"
+            className="org.apache.catalina.mbeans.ClassNameMBean"
+          description="Custom LDAPRealm"
+               domain="Catalina"
+                group="Realm"
+                 type="com.myfirm.mypackage.LDAPRealm">
+
+    <attribute   name="className"
+          description="Fully qualified class name of the managed object"
+                 type="java.lang.String"
+            writeable="false"/>
+
+    <attribute   name="debug"
+          description="The debugging detail level for this component"
+                 type="int"/>
+    .
+    .
+    .
+
+  </mbean>
+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/mbeans-descriptors.dtd b/test.dockerapp/tomcat/webapps/docs/mbeans-descriptors.dtd new file mode 100644 index 0000000..14daed5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/mbeans-descriptors.dtd @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/docs/monitoring.html b/test.dockerapp/tomcat/webapps/docs/monitoring.html new file mode 100644 index 0000000..5527884 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/monitoring.html @@ -0,0 +1,1136 @@ + +Apache Tomcat 8 (8.0.53) - Monitoring and Managing Tomcat

Monitoring and Managing Tomcat

Table of Contents

Introduction

+ +

Monitoring is a key aspect of system administration. Looking inside a + running server, obtaining some statistics or reconfiguring some aspects of + an application are all daily administration tasks.

+ +

Enabling JMX Remote

+ +

Note: This configuration is needed only if you are + going to monitor Tomcat remotely. It is not needed if you are going + to monitor it locally, using the same user that Tomcat runs with.

+ +

The Oracle website includes the list of options and how to configure + JMX Remote on Java 6: + + http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html. +

+

The following is a quick configuration guide for Java 6:

+

Add the following parameters to setenv.bat script of your + Tomcat (see RUNNING.txt for details).
+ Note: This syntax is for Microsoft Windows. The command has + to be on the same line. It is wrapped to be more readable. If Tomcat is + running as a Windows service, use its configuration dialog to set + java options for the service. + For un*xes remove "set " from beginning of the line. +

+
set CATALINA_OPTS=-Dcom.sun.management.jmxremote
+  -Dcom.sun.management.jmxremote.port=%my.jmx.port%
+  -Dcom.sun.management.jmxremote.ssl=false
+  -Dcom.sun.management.jmxremote.authenticate=false
+ +
    +
  1. If you require authorization, add and change this: +
      -Dcom.sun.management.jmxremote.authenticate=true
    +  -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
    +  -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
    +
  2. +
  3. edit the access authorization file $CATALINA_BASE/conf/jmxremote.access: +
    monitorRole readonly
    +controlRole readwrite
    +
  4. +
  5. edit the password file $CATALINA_BASE/conf/jmxremote.password: +
    monitorRole tomcat
    +controlRole tomcat
    + Tip: The password file should be read-only and only accessible by the + operating system user Tomcat is running as. +
  6. +
+

Note: The JSR 160 JMX-Adaptor opens a second data channel + on a random port. That is a problem when you have a local firewall installed. + To fix it, configure a JmxRemoteLifecycleListener, as described + in listeners documentation. +

+ +

Manage Tomcat with JMX remote Ant Tasks

+

To simplify JMX usage with Ant 1.6.x, a set of tasks is provided that may + be used with antlib.

+

antlib: Copy your catalina-ant.jar from $CATALINA_HOME/lib to $ANT_HOME/lib.

+

The following example shows the JMX Accessor usage:
+ Note: The name attribute value was wrapped here to be + more readable. It has to be all on the same line, without spaces.

+
<project name="Catalina Ant JMX"
+      xmlns:jmx="antlib:org.apache.catalina.ant.jmx"
+      default="state"
+      basedir=".">
+  <property name="jmx.server.name" value="localhost" />
+  <property name="jmx.server.port" value="9012" />
+  <property name="cluster.server.address" value="192.168.1.75" />
+  <property name="cluster.server.port" value="9025" />
+
+  <target name="state" description="Show JMX Cluster state">
+    <jmx:open
+      host="${jmx.server.name}"
+      port="${jmx.server.port}"
+      username="controlRole"
+      password="tomcat"/>
+    <jmx:get
+      name=
+"Catalina:type=IDataSender,host=localhost,
+senderAddress=${cluster.server.address},senderPort=${cluster.server.port}"
+      attribute="connected"
+      resultproperty="IDataSender.backup.connected"
+      echo="false"
+    />
+    <jmx:get
+      name="Catalina:type=ClusterSender,host=localhost"
+      attribute="senderObjectNames"
+      resultproperty="senderObjectNames"
+      echo="false"
+    />
+    <!-- get current maxActiveSession from ClusterTest application
+       echo it to Ant output and store at
+       property <em>clustertest.maxActiveSessions.orginal</em>
+    -->
+    <jmx:get
+      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
+      attribute="maxActiveSessions"
+      resultproperty="clustertest.maxActiveSessions.orginal"
+      echo="true"
+    />
+    <!-- set maxActiveSession to 100
+    -->
+    <jmx:set
+      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
+      attribute="maxActiveSessions"
+      value="100"
+      type="int"
+    />
+    <!-- get all sessions and split result as delimiter <em>SPACE</em> for easy
+       access all session ids directly with Ant property sessions.[0..n].
+    -->
+    <jmx:invoke
+      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
+      operation="listSessionIds"
+      resultproperty="sessions"
+      echo="false"
+      delimiter=" "
+    />
+    <!-- Access session attribute <em>Hello</em> from first session.
+    -->
+    <jmx:invoke
+      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
+      operation="getSessionAttribute"
+      resultproperty="Hello"
+      echo="false"
+    >
+      <arg value="${sessions.0}"/>
+      <arg value="Hello"/>
+    </jmx:invoke>
+    <!-- Query for all application manager.of the server from all hosts
+       and bind all attributes from all found manager MBeans.
+    -->
+    <jmx:query
+      name="Catalina:type=Manager,*"
+      resultproperty="manager"
+      echo="true"
+      attributebinding="true"
+    />
+    <!-- echo the create properties -->
+<echo>
+senderObjectNames: ${senderObjectNames.0}
+IDataSender.backup.connected: ${IDataSender.backup.connected}
+session: ${sessions.0}
+manager.length: ${manager.length}
+manager.0.name: ${manager.0.name}
+manager.1.name: ${manager.1.name}
+hello: ${Hello}
+manager.ClusterTest.0.name: ${manager.ClusterTest.0.name}
+manager.ClusterTest.0.activeSessions: ${manager.ClusterTest.0.activeSessions}
+manager.ClusterTest.0.counterSend_EVT_SESSION_EXPIRED:
+ ${manager.ClusterTest.0.counterSend_EVT_SESSION_EXPIRED}
+manager.ClusterTest.0.counterSend_EVT_GET_ALL_SESSIONS:
+ ${manager.ClusterTest.0.counterSend_EVT_GET_ALL_SESSIONS}
+</echo>
+
+  </target>
+
+</project>
+

import: Import the JMX Accessor Project with + <import file="${CATALINA.HOME}/bin/catalina-tasks.xml" /> and + reference the tasks with jmxOpen, jmxSet, jmxGet, + jmxQuery, jmxInvoke, jmxEquals and jmxCondition.

+ +

JMXAccessorOpenTask - JMX open connection task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
urlSet JMX connection URL - service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi +
hostSet the host, shortcut the very long URL syntax. + localhost
portSet the remote connection port + 8050
usernameremote JMX connection user name. +
passwordremote JMX connection password. +
refName of the internal connection reference. With this attribute you can + configure more the one connection inside the same Ant project. + jmx.server
echoEcho the command usage (for access analysis or debugging) + false
ifOnly execute if a property of the given name exists in the current project. +
unlessOnly execute if a property of the given name not exists in the current project. +
+ +

+Example to open a new JMX connection +

+
  <jmx:open
+    host="${jmx.server.name}"
+    port="${jmx.server.port}"
+  />
+ +

+Example to open a JMX connection from URL, with authorization and +store at other reference +

+
  <jmx:open
+    url="service:jmx:rmi:///jndi/rmi://localhost:9024/jmxrmi"
+    ref="jmx.server.9024"
+    username="controlRole"
+    password="tomcat"
+  />
+ +

+Example to open a JMX connection from URL, with authorization and +store at other reference, but only when property jmx.if exists and +jmx.unless not exists +

+
  <jmx:open
+    url="service:jmx:rmi:///jndi/rmi://localhost:9024/jmxrmi"
+    ref="jmx.server.9024"
+    username="controlRole"
+    password="tomcat"
+    if="jmx.if"
+    unless="jmx.unless"
+  />
+ +

Note: All properties from jmxOpen task also exists at all +other tasks and conditions. +

+ +

JMXAccessorGetTask: get attribute value Ant task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
nameFull qualified JMX ObjectName -- Catalina:type=Server +
attributeExisting MBean attribute (see Tomcat MBean description above) +
refJMX Connection reference + jmx.server
echoEcho command usage (access and result) + false
resultpropertySave result at this project property +
delimiterSplit result with delimiter (java.util.StringTokenizer) + and use resultproperty as prefix to store tokens. +
separatearrayresultsWhen return value is an array, save result as property list + ($resultproperty.[0..N] and $resultproperty.length) + true
+ +

+Example to get remote MBean attribute from default JMX connection +

+
  <jmx:get
+    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
+    attribute="maxActiveSessions"
+    resultproperty="servlets-examples.maxActiveSessions"
+  />
+ +

+Example to get and result array and split it at separate properties +

+
  <jmx:get
+      name="Catalina:type=ClusterSender,host=localhost"
+      attribute="senderObjectNames"
+      resultproperty="senderObjectNames"
+  />
+

+Access the senderObjectNames properties with: +

+
  ${senderObjectNames.length} give the number of returned sender list.
+  ${senderObjectNames.[0..N]} found all sender object names
+ + +

+Example to get IDataSender attribute connected only when cluster is configured.
+Note: The name attribute value was wrapped here to be +more readable. It has to be all on the same line, without spaces. +

+

+  <jmx:query
+    failonerror="false"
+    name="Catalina:type=Cluster,host=${tomcat.application.host}"
+    resultproperty="cluster"
+  />
+  <jmx:get
+    name=
+"Catalina:type=IDataSender,host=${tomcat.application.host},
+senderAddress=${cluster.backup.address},senderPort=${cluster.backup.port}"
+    attribute="connected"
+    resultproperty="datasender.connected"
+    if="cluster.0.name" />
+ +

JMXAccessorSetTask: set attribute value Ant task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
nameFull qualified JMX ObjectName -- Catalina:type=Server +
attributeExisting MBean attribute (see Tomcat MBean description above) +
valuevalue that set to attribute +
typetype of the attribute. + java.lang.String
refJMX Connection reference + jmx.server
echoEcho command usage (access and result) + false
+ +

+Example to set remote MBean attribute value +

+
  <jmx:set
+    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
+    attribute="maxActiveSessions"
+    value="500"
+    type="int"
+  />
+ + +

JMXAccessorInvokeTask: invoke MBean operation Ant task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
nameFull qualified JMX ObjectName -- Catalina:type=Server +
operationExisting MBean operation (see Tomcat + funcspecs/fs-admin-opers.html). +
refJMX Connection reference + jmx.server
echoEcho command usage (access and result) + false
resultpropertySave result at this project property +
delimiterSplit result with delimiter (java.util.StringTokenizer) + and use resultproperty as prefix to store tokens. +
separatearrayresultsWhen return value is an array, save result as property list + ($resultproperty.[0..N] and $resultproperty.length) + true
+ +

+stop an application +

+
  <jmx:invoke
+    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
+    operation="stop"/>
+

+Now you can find the sessionid at ${sessions.[0..N} properties and access the count +with ${sessions.length} property. +

+

+Example to get all sessionids +

+
  <jmx:invoke
+    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
+    operation="listSessionIds"
+    resultproperty="sessions"
+    delimiter=" "
+  />
+

+Now you can find the sessionid at ${sessions.[0..N} properties and access the count +with ${sessions.length} property. +

+

+Example to get remote MBean session attribute from session ${sessionid.0} +

+
  <jmx:invoke
+    name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
+    operation="getSessionAttribute"
+    resultproperty="hello">
+     <arg value="${sessionid.0}"/>
+     <arg value="Hello" />
+  </jmx:invoke>
+ +

+Example to create a new access logger valve at vhost localhost +

+
 <jmx:invoke
+         name="Catalina:type=MBeanFactory"
+         operation="createAccessLoggerValve"
+         resultproperty="accessLoggerObjectName"
+ >
+     <arg value="Catalina:type=Host,host=localhost"/>
+ </jmx:invoke>
+

+Now you can find new MBean with name stored at ${accessLoggerObjectName} +property. +

+ +

JMXAccessorQueryTask: query MBean Ant task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
nameJMX ObjectName query string -- Catalina:type=Manager,* +
refJMX Connection reference + jmx.server
echoEcho command usage (access and result) + false
resultpropertyPrefix project property name to all founded MBeans (mbeans.[0..N].objectname) +
attributebindingbind ALL MBean attributes in addition to name + false
delimiterSplit result with delimiter (java.util.StringTokenizer) + and use resultproperty as prefix to store tokens. +
separatearrayresultsWhen return value is an array, save result as property list + ($resultproperty.[0..N] and $resultproperty.length) + true
+ +

+Get all Manager ObjectNames from all services and Hosts +

+
  <jmx:query
+    name="Catalina:type=Manager,*
+    resultproperty="manager" />
+

+Now you can find the Session Manager at ${manager.[0..N].name} +properties and access the result object counter with ${manager.length} property. +

+

+Example to get the Manager from servlet-examples application an bind all MBean properties +

+
  <jmx:query
+    name="Catalina:type=Manager,context=/servlet-examples,host=localhost*"
+    attributebinding="true"
+    resultproperty="manager.servletExamples" />
+

+Now you can find the manager at ${manager.servletExamples.0.name} property +and can access all properties from this manager with ${manager.servletExamples.0.[manager attribute names]}. +The result object counter from MBeans is stored ad ${manager.length} property. +

+ +

+Example to get all MBeans from a server and store inside an external XML property file +

+
<project name="jmx.query"
+            xmlns:jmx="antlib:org.apache.catalina.ant.jmx"
+            default="query-all" basedir=".">
+<property name="jmx.host" value="localhost"/>
+<property name="jmx.port" value="8050"/>
+<property name="jmx.username" value="controlRole"/>
+<property name="jmx.password" value="tomcat"/>
+
+<target name="query-all" description="Query all MBeans of a server">
+  <!-- Configure connection -->
+  <jmx:open
+    host="${jmx.host}"
+    port="${jmx.port}"
+    ref="jmx.server"
+    username="${jmx.username}"
+    password="${jmx.password}"/>
+
+  <!-- Query MBean list -->
+  <jmx:query
+    name="*:*"
+    resultproperty="mbeans"
+    attributebinding="false"/>
+
+  <echoproperties
+    destfile="mbeans.properties"
+    prefix="mbeans."
+    format="xml"/>
+
+  <!-- Print results -->
+  <echo message=
+    "Number of MBeans in server ${jmx.host}:${jmx.port} is ${mbeans.length}"/>
+</target>
+</project>
+

+Now you can find all MBeans inside the file mbeans.properties. +

+ +

JMXAccessorCreateTask: remote create MBean Ant task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
nameFull qualified JMX ObjectName -- Catalina:type=MBeanFactory +
classNameExisting MBean full qualified class name (see Tomcat MBean description above) +
classLoaderObjectName of server or web application classloader
+ ( Catalina:type=ServerClassLoader,name=[server,common,shared] or
+ Catalina:type=WebappClassLoader,context=/myapps,host=localhost) +
refJMX Connection reference + jmx.server
echoEcho command usage (access and result) + false
+ +

+Example to create remote MBean +

+
  <jmx:create
+    ref="${jmx.reference}"
+    name="Catalina:type=MBeanFactory"
+    className="org.apache.commons.modeler.BaseModelMBean"
+    classLoader="Catalina:type=ServerClassLoader,name=server">
+    <arg value="org.apache.catalina.mbeans.MBeanFactory" />
+  </jmx:create>
+ +

+ Warning: Many Tomcat MBeans can't be linked to their parent once
+ created. The Valve, Cluster and Realm MBeans are not automatically
+ connected with their parent. Use the MBeanFactory create
+ operation instead. +

+ +

JMXAccessorUnregisterTask: remote unregister MBean Ant task

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
nameFull qualified JMX ObjectName -- Catalina:type=MBeanFactory +
refJMX Connection reference + jmx.server
echoEcho command usage (access and result) + false
+ +

+Example to unregister remote MBean +

+
  <jmx:unregister
+    name="Catalina:type=MBeanFactory"
+  />
+ +

+ Warning: A lot of Tomcat MBeans can't be unregister.
+ The MBeans are not unlinked from their parent. Use MBeanFactory
+ remove operation instead. +

+ +

JMXAccessorCondition: express condition

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
urlSet JMX connection URL - service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi +
hostSet the host, shortcut the very long URL syntax. + localhost
portSet the remote connection port + 8050
usernameremote JMX connection user name. +
passwordremote JMX connection password. +
refName of the internal connection reference. With this attribute you can + configure more the one connection inside the same Ant project. + jmx.server
nameFull qualified JMX ObjectName -- Catalina:type=Server +
echoEcho condition usage (access and result) + false
ifOnly execute if a property of the given name exists in the current project. +
unlessOnly execute if a property of the given name not exists in the current project. +
value (required)Second arg for operation +
typeValue type to express operation (support long and double) + long
operation express one +
    +
  • == equals
  • +
  • != not equals
  • +
  • > greater than (&gt;)
  • +
  • >= greater than or equals (&gt;=)
  • +
  • < lesser than (&lt;)
  • +
  • <= lesser than or equals (&lt;=)
  • +
+
==
+ +

+Wait for server connection and that cluster backup node is accessable +

+
<target name="wait">
+  <waitfor maxwait="${maxwait}" maxwaitunit="second" timeoutproperty="server.timeout" >
+    <and>
+      <socket server="${server.name}" port="${server.port}"/>
+      <http url="${url}"/>
+      <jmx:condition
+        operation="=="
+        host="localhost"
+        port="9014"
+        username="controlRole"
+        password="tomcat"
+        name=
+"Catalina:type=IDataSender,host=localhost,senderAddress=192.168.111.1,senderPort=9025"
+        attribute="connected"
+        value="true"
+      />
+    </and>
+  </waitfor>
+  <fail if="server.timeout" message="Server ${url} don't answer inside ${maxwait} sec" />
+  <echo message="Server ${url} alive" />
+</target>
+ +

JMXAccessorEqualsCondition: equals MBean Ant condition

+

+List of Attributes +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault value
urlSet JMX connection URL - service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi +
hostSet the host, shortcut the very long URL syntax. + localhost
portSet the remote connection port + 8050
usernameremote JMX connection user name. +
passwordremote JMX connection password. +
refName of the internal connection reference. With this attribute you can + configure more the one connection inside the same Ant project. + jmx.server
nameFull qualified JMX ObjectName -- Catalina:type=Server +
echoEcho condition usage (access and result) + false
+ +

+Wait for server connection and that cluster backup node is accessible +

+
<target name="wait">
+  <waitfor maxwait="${maxwait}" maxwaitunit="second" timeoutproperty="server.timeout" >
+    <and>
+      <socket server="${server.name}" port="${server.port}"/>
+      <http url="${url}"/>
+      <jmx:equals
+        host="localhost"
+        port="9014"
+        username="controlRole"
+        password="tomcat"
+        name=
+"Catalina:type=IDataSender,host=localhost,senderAddress=192.168.111.1,senderPort=9025"
+        attribute="connected"
+        value="true"
+      />
+    </and>
+  </waitfor>
+  <fail if="server.timeout" message="Server ${url} don't answer inside ${maxwait} sec" />
+  <echo message="Server ${url} alive" />
+</target>
+ +

Using the JMXProxyServlet

+ +

+ Tomcat offers an alternative to using remote (or even local) JMX + connections while still giving you access to everything JMX has to offer: + Tomcat's + JMXProxyServlet. +

+ +

+ The JMXProxyServlet allows a client to issue JMX queries via an HTTP + interface. This technique offers the following advantages over using + JMX directly from a client program: +

+ +
    +
  • You don't have to launch a full JVM and make a remote JMX connection + just to ask for one small piece of data from a running server
  • +
  • You don't have to know how to work with JMX connections
  • +
  • You don't need any of the complex configuration covered in the rest + of this page
  • +
  • Your client program does not have to be written in Java
  • +
+ +

+ A perfect example of JMX overkill can be seen in the case of popular + server-monitoring software such as Nagios or Icinga: if you want to + monitor 10 items via JMX, you will have to launch 10 JVMs, make 10 JMX + connections, and then shut them all down every few minutes. With the + JMXProxyServlet, you can make 10 HTTP connections and be done with it. +

+ +

+ You can find out more information about the JMXProxyServlet in the + documentation for the + Tomcat + manager. +

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/proxy-howto.html b/test.dockerapp/tomcat/webapps/docs/proxy-howto.html new file mode 100644 index 0000000..9c145d1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/proxy-howto.html @@ -0,0 +1,155 @@ + +Apache Tomcat 8 (8.0.53) - Proxy Support HOW-TO

Proxy Support HOW-TO

Table of Contents

Introduction

+ +

Using standard configurations of Tomcat, web applications can ask for +the server name and port number to which the request was directed for +processing. When Tomcat is running standalone with the +HTTP/1.1 Connector, it will generally +report the server name specified in the request, and the port number on +which the Connector is listening. The servlet API +calls of interest, for this purpose, are:

+
    +
  • ServletRequest.getServerName(): Returns the host name of the server to which the request was sent.
  • +
  • ServletRequest.getServerPort(): Returns the port number of the server to which the request was sent.
  • +
  • ServletRequest.getLocalName(): Returns the host name of the Internet Protocol (IP) interface on which the request was received.
  • +
  • ServletRequest.getLocalPort(): Returns the Internet Protocol (IP) port number of the interface on which the request was received.
  • +
+ +

When you are running behind a proxy server (or a web server that is +configured to behave like a proxy server), you will sometimes prefer to +manage the values returned by these calls. In particular, you will +generally want the port number to reflect that specified in the original +request, not the one on which the Connector itself is +listening. You can use the proxyName and proxyPort +attributes on the <Connector> element to configure +these values.

+ +

Proxy support can take many forms. The following sections describe +proxy configurations for several common cases.

+ +

Apache 1.3 Proxy Support

+ +

Apache 1.3 supports an optional module (mod_proxy) that +configures the web server to act as a proxy server. This can be used to +forward requests for a particular web application to a Tomcat instance, +without having to configure a web connector such as mod_jk. +To accomplish this, you need to perform the following tasks:

+
    +
  1. Configure your copy of Apache so that it includes the + mod_proxy module. If you are building from source, + the easiest way to do this is to include the + --enable-module=proxy directive on the + ./configure command line.

  2. +
  3. If not already added for you, make sure that you are loading the + mod_proxy module at Apache startup time, by using the + following directives in your httpd.conf file:

    +
    LoadModule proxy_module  {path-to-modules}/mod_proxy.so
    +AddModule  mod_proxy.c
  4. +
  5. Include two directives in your httpd.conf file for + each web application that you wish to forward to Tomcat. For + example, to forward an application at context path /myapp:

    +
    ProxyPass         /myapp  http://localhost:8081/myapp
    +ProxyPassReverse  /myapp  http://localhost:8081/myapp
    +

    which tells Apache to forward URLs of the form + http://localhost/myapp/* to the Tomcat connector + listening on port 8081.

  6. +
  7. Configure your copy of Tomcat to include a special + <Connector> element, with appropriate + proxy settings, for example:

    +
    <Connector port="8081" ...
    +              proxyName="www.mycompany.com"
    +              proxyPort="80"/>
    +

    which will cause servlets inside this web application to think that + all proxied requests were directed to www.mycompany.com + on port 80.

  8. +
  9. It is legal to omit the proxyName attribute from the + <Connector> element. If you do so, the value + returned by request.getServerName() will by the host + name on which Tomcat is running. In the example above, it would be + localhost.

  10. +
  11. If you also have a <Connector> listening on port + 8080 (nested within the same Service + element), the requests to either port will share the same set of + virtual hosts and web applications.

  12. +
  13. You might wish to use the IP filtering features of your operating + system to restrict connections to port 8081 (in this example) to + be allowed only from the server that is running + Apache.

  14. +
  15. Alternatively, you can set up a series of web applications that are + only available via proxying, as follows:

    +
      +
    • Configure another <Service> that contains + only a <Connector> for the proxy port.
    • +
    • Configure appropriate Engine, + Host, and + Context elements for the virtual hosts + and web applications accessible via proxying.
    • +
    • Optionally, protect port 8081 with IP filters as described + earlier.
    • +
  16. +
  17. When requests are proxied by Apache, the web server will be recording + these requests in its access log. Therefore, you will generally want to + disable any access logging performed by Tomcat itself.

  18. +
+ +

When requests are proxied in this manner, all requests +for the configured web applications will be processed by Tomcat (including +requests for static content). You can improve performance by using the +mod_jk web connector instead of mod_proxy. +mod_jk can be configured so that the web server serves static +content that is not processed by filters or security constraints defined +within the web application's deployment descriptor +(/WEB-INF/web.xml).

+ +

Apache 2.0 Proxy Support

+The same instructions hold true as for 1.3. (Except in Apache 2.0, +you may omit AddModule mod_proxy.c) +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/realm-howto.html b/test.dockerapp/tomcat/webapps/docs/realm-howto.html new file mode 100644 index 0000000..a8a7ca3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/realm-howto.html @@ -0,0 +1,1221 @@ + +Apache Tomcat 8 (8.0.53) - Realm Configuration HOW-TO

Realm Configuration HOW-TO

Table of Contents

Quick Start

+ +

This document describes how to configure Tomcat to support container +managed security, by connecting to an existing "database" of usernames, +passwords, and user roles. You only need to care about this if you are using +a web application that includes one or more +<security-constraint> elements, and a +<login-config> element defining how users are required +to authenticate themselves. If you are not utilizing these features, you can +safely skip this document.

+ +

For fundamental background information about container managed security, +see the Servlet +Specification (Version 2.4), Section 12.

+ +

For information about utilizing the Single Sign On feature of +Tomcat (allowing a user to authenticate themselves once across the entire +set of web applications associated with a virtual host), see +here.

+ +

Overview

+ + +

What is a Realm?

+ +

A Realm is a "database" of usernames and passwords that +identify valid users of a web application (or set of web applications), plus +an enumeration of the list of roles associated with each valid user. +You can think of roles as similar to groups in Unix-like operating +systems, because access to specific web application resources is granted to +all users possessing a particular role (rather than enumerating the list of +associated usernames). A particular user can have any number of roles +associated with their username.

+ +

Although the Servlet Specification describes a portable mechanism for +applications to declare their security requirements (in the +web.xml deployment descriptor), there is no portable API +defining the interface between a servlet container and the associated user +and role information. In many cases, however, it is desirable to "connect" +a servlet container to some existing authentication database or mechanism +that already exists in the production environment. Therefore, Tomcat +defines a Java interface (org.apache.catalina.Realm) that +can be implemented by "plug in" components to establish this connection. +Six standard plug-ins are provided, supporting connections to various +sources of authentication information:

+
    +
  • JDBCRealm - Accesses authentication information + stored in a relational database, accessed via a JDBC driver.
  • +
  • DataSourceRealm - Accesses authentication + information stored in a relational database, accessed via a named JNDI + JDBC DataSource.
  • +
  • JNDIRealm - Accesses authentication information + stored in an LDAP based directory server, accessed via a JNDI provider. +
  • +
  • UserDatabaseRealm - Accesses authentication + information stored in an UserDatabase JNDI resource, which is typically + backed by an XML document (conf/tomcat-users.xml).
  • +
  • MemoryRealm - Accesses authentication + information stored in an in-memory object collection, which is initialized + from an XML document (conf/tomcat-users.xml).
  • +
  • JAASRealm - Accesses authentication information + through the Java Authentication & Authorization Service (JAAS) + framework.
  • +
+ +

It is also possible to write your own Realm implementation, +and integrate it with Tomcat. To do so, you need to:

+
    +
  • Implement org.apache.catalina.Realm,
  • +
  • Place your compiled realm in $CATALINA_HOME/lib,
  • +
  • Declare your realm as described in the "Configuring a Realm" section below,
  • +
  • Declare your realm to the MBeans Descriptors.
  • +
+ +
+ + +

Configuring a Realm

+ +

Before getting into the details of the standard Realm implementations, it is +important to understand, in general terms, how a Realm is configured. In +general, you will be adding an XML element to your conf/server.xml +configuration file, that looks something like this:

+ +
<Realm className="... class name for this implementation"
+       ... other attributes for this implementation .../>
+ +

The <Realm> element can be nested inside any one of +of the following Container elements. The location of the +Realm element has a direct impact on the "scope" of that Realm +(i.e. which web applications will share the same authentication information): +

+
    +
  • Inside an <Engine> element - This Realm will be shared + across ALL web applications on ALL virtual hosts, UNLESS it is overridden + by a Realm element nested inside a subordinate <Host> + or <Context> element.
  • +
  • Inside a <Host> element - This Realm will be shared across + ALL web applications for THIS virtual host, UNLESS it is overridden + by a Realm element nested inside a subordinate <Context> + element.
  • +
  • Inside a <Context> element - This Realm will be used ONLY + for THIS web application.
  • +
+ + +
+ + +

Common Features

+ + +

Digested Passwords

+ +

For each of the standard Realm implementations, the +user's password (by default) is stored in clear text. In many +environments, this is undesirable because casual observers of the +authentication data can collect enough information to log on +successfully, and impersonate other users. To avoid this problem, the +standard implementations support the concept of digesting +user passwords. This allows the stored version of the passwords to be +encoded (in a form that is not easily reversible), but that the +Realm implementation can still utilize for +authentication.

+ +

When a standard realm authenticates by retrieving the stored +password and comparing it with the value presented by the user, you +can select digested passwords by specifying the digest +attribute on your <Realm> element. The value for +this attribute must be one of the digest algorithms supported by the +java.security.MessageDigest class (SHA, MD2, or MD5). +When you select this option, the contents of the password that is +stored in the Realm must be the cleartext version of the +password, as digested by the specified algorithm.

+ +

When the authenticate() method of the Realm is called, the +(cleartext) password specified by the user is itself digested by the same +algorithm, and the result is compared with the value returned by the +Realm. An equal match implies that the cleartext version of the +original password is the same as the one presented by the user, so that this +user should be authorized.

+ +

To calculate the digested value of a cleartext password, two convenience +techniques are supported:

+
    +
  • If you are writing an application that needs to calculate digested + passwords dynamically, call the static Digest() method of the + org.apache.catalina.realm.RealmBase class, passing the + cleartext password, the digest algorithm name and the encoding as arguments. + This method will return the digested password.
  • +
  • If you want to execute a command line utility to calculate the digested + password, simply execute +
    CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}
    + and the digested version of this cleartext password will be returned to + standard output.
  • +
+ +

If using digested passwords with DIGEST authentication, the cleartext used + to generate the digest is different and the digest must use one iteration of + the MD5 algorithm with no salt. In the examples above + {cleartext-password} must be replaced with + {username}:{realm}:{cleartext-password}. For example, in a + development environment this might take the form + testUser:Authentication required:testPassword. The value for + {realm} is taken from the <realm-name> + element of the web application's <login-config>. If + not specified in web.xml, the default value of Authentication + required is used.

+ +

Usernames and/or passwords using encodings other than the platform default +are supported using

+
CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} -e {encoding} {input}
+

but care is required to ensure that the input is correctly passed to the +digester. The digester returns {input}:{digest}. If the input +appears corrupted in the return, the digest will be invalid.

+ +

The output format of the digest is {salt}${iterations}${digest}. +If the salt length is zero and the iteration count is one, the output is +simplified to {digest}.

+ +

The full syntax of CATALINA_HOME/bin/digest.[bat|sh] is:

+
CATALINA_HOME/bin/digest.[bat|sh] [-a <algorithm>] [-e <encoding>]
+        [-i <iterations>] [-s <salt-length>] [-k <key-length>]
+        [-h <handler-class-name>] <credentials>
+
+
    +
  • -a - The algorithm to use to generate the stored + credential. If not specified, the default for the handler will + be used. If neither handler nor algorithm is specified then a + default of SHA-512 will be used
  • +
  • -e - The encoding to use for any byte to/from character + conversion that may be necessary. If not specified, the + system encoding (Charset#defaultCharset()) will + be used.
  • +
  • -i - The number of iterations to use when generating the + stored credential. If not specified, the default for the + CredentialHandler will be used.
  • +
  • -s - The length (in bytes) of salt to generate and store as + part of the credential. If not specified, the default for + the CredentialHandler will be used.
  • +
  • -k - The length (in bits) of the key(s), if any, created while + generating the credential. If not specified, the default + for the CredentialHandler will be used.
  • +
  • -h - The fully qualified class name of the CredentialHandler + to use. If not specified, the built-in handlers will be + tested in turn (MessageDigestCredentialHandler then + SecretKeyCredentialHandler) and the first one to accept the + specified algorithm will be used.
  • +
+
+ + + +

Example Application

+ +

The example application shipped with Tomcat includes an area that is +protected by a security constraint, utilizing form-based login. To access it, +point your browser at +http://localhost:8080/examples/jsp/security/protected/ +and log on with one of the usernames and passwords described for the default +UserDatabaseRealm.

+ +
+ + +

Manager Application

+ +

If you wish to use the Manager Application +to deploy and undeploy applications in a running Tomcat installation, you +MUST add the "manager-gui" role to at least one username in your selected +Realm implementation. This is because the manager web application itself uses a +security constraint that requires role "manager-gui" to access ANY request URI +within the HTML interface of that application.

+ +

For security reasons, no username in the default Realm (i.e. using +conf/tomcat-users.xml is assigned the "manager-gui" role. +Therefore, no one will be able to utilize the features of this application +until the Tomcat administrator specifically assigns this role to one or more +users.

+ +
+ +

Realm Logging

+ +

Debugging and exception messages logged by a Realm will + be recorded by the logging configuration associated with the container + for the realm: its surrounding Context, + Host, or + Engine.

+ +
+ +

Standard Realm Implementations

+ +

JDBCRealm

+ +
Introduction
+ +

JDBCRealm is an implementation of the Tomcat +Realm interface that looks up users in a relational database +accessed via a JDBC driver. There is substantial configuration flexibility +that lets you adapt to existing table and column names, as long as your +database structure conforms to the following requirements:

+
    +
  • There must be a table, referenced below as the users table, + that contains one row for every valid user that this Realm + should recognize.
  • +
  • The users table must contain at least two columns (it may + contain more if your existing applications required it): +
      +
    • Username to be recognized by Tomcat when the user logs in.
    • +
    • Password to be recognized by Tomcat when the user logs in. + This value may in cleartext or digested - see below for more + information.
    • +
  • +
  • There must be a table, referenced below as the user roles table, + that contains one row for every valid role that is assigned to a + particular user. It is legal for a user to have zero, one, or more than + one valid role.
  • +
  • The user roles table must contain at least two columns (it may + contain more if your existing applications required it): +
      +
    • Username to be recognized by Tomcat (same value as is specified + in the users table).
    • +
    • Role name of a valid role associated with this user.
    • +
  • +
+ +
Quick Start
+ +

To set up Tomcat to use JDBCRealm, you will need to follow these steps:

+
    +
  1. If you have not yet done so, create tables and columns in your database + that conform to the requirements described above.
  2. +
  3. Configure a database username and password for use by Tomcat, that has + at least read only access to the tables described above. (Tomcat will + never attempt to write to these tables.)
  4. +
  5. Place a copy of the JDBC driver you will be using inside the + $CATALINA_HOME/lib directory. + Note that only JAR files are recognized!
  6. +
  7. Set up a <Realm> element, as described below, in your + $CATALINA_BASE/conf/server.xml file.
  8. +
  9. Restart Tomcat if it is already running.
  10. +
+ +
Realm Element Attributes
+ +

To configure JDBCRealm, you will create a <Realm> +element and nest it in your $CATALINA_BASE/conf/server.xml file, +as described above. The attributes for the +JDBCRealm are defined in the Realm configuration +documentation.

+ +
Example
+ +

An example SQL script to create the needed tables might look something +like this (adapt the syntax as required for your particular database):

+
create table users (
+  user_name         varchar(15) not null primary key,
+  user_pass         varchar(15) not null
+);
+
+create table user_roles (
+  user_name         varchar(15) not null,
+  role_name         varchar(15) not null,
+  primary key (user_name, role_name)
+);
+ +

Example Realm elements are included (commented out) in the +default $CATALINA_BASE/conf/server.xml file. Here's an example +for using a MySQL database called "authority", configured with the tables +described above, and accessed with username "dbuser" and password "dbpass":

+
<Realm className="org.apache.catalina.realm.JDBCRealm"
+      driverName="org.gjt.mm.mysql.Driver"
+   connectionURL="jdbc:mysql://localhost/authority?user=dbuser&amp;password=dbpass"
+       userTable="users" userNameCol="user_name" userCredCol="user_pass"
+   userRoleTable="user_roles" roleNameCol="role_name"/>
+ +
Additional Notes
+ +

JDBCRealm operates according to the following rules:

+
    +
  • When a user attempts to access a protected resource for the first time, + Tomcat will call the authenticate() method of this + Realm. Thus, any changes you have made to the database + directly (new users, changed passwords or roles, etc.) will be immediately + reflected.
  • +
  • Once a user has been authenticated, the user (and his or her associated + roles) are cached within Tomcat for the duration of the user's login. + (For FORM-based authentication, that means until the session times out or + is invalidated; for BASIC authentication, that means until the user + closes their browser). The cached user is not saved and + restored across sessions serialisations. Any changes to the database + information for an already authenticated user will not be + reflected until the next time that user logs on again.
  • +
  • Administering the information in the users and user roles + table is the responsibility of your own applications. Tomcat does not + provide any built-in capabilities to maintain users and roles.
  • +
+ +
+ + +

DataSourceRealm

+ +
Introduction
+ +

DataSourceRealm is an implementation of the Tomcat +Realm interface that looks up users in a relational database +accessed via a JNDI named JDBC DataSource. There is substantial configuration +flexibility that lets you adapt to existing table and column names, as long +as your database structure conforms to the following requirements:

+
    +
  • There must be a table, referenced below as the users table, + that contains one row for every valid user that this Realm + should recognize.
  • +
  • The users table must contain at least two columns (it may + contain more if your existing applications required it): +
      +
    • Username to be recognized by Tomcat when the user logs in.
    • +
    • Password to be recognized by Tomcat when the user logs in. + This value may in cleartext or digested - see below for more + information.
    • +
  • +
  • There must be a table, referenced below as the user roles table, + that contains one row for every valid role that is assigned to a + particular user. It is legal for a user to have zero, one, or more than + one valid role.
  • +
  • The user roles table must contain at least two columns (it may + contain more if your existing applications required it): +
      +
    • Username to be recognized by Tomcat (same value as is specified + in the users table).
    • +
    • Role name of a valid role associated with this user.
    • +
  • +
+ +
Quick Start
+ +

To set up Tomcat to use DataSourceRealm, you will need to follow these steps:

+
    +
  1. If you have not yet done so, create tables and columns in your database + that conform to the requirements described above.
  2. +
  3. Configure a database username and password for use by Tomcat, that has + at least read only access to the tables described above. (Tomcat will + never attempt to write to these tables.)
  4. +
  5. Configure a JNDI named JDBC DataSource for your database. Refer to the + JNDI DataSource Example + HOW-TO for information on how to configure a JNDI named JDBC DataSource. + Be sure to set the Realm's localDataSource + attribute appropriately, depending on where the JNDI DataSource is + defined.
  6. +
  7. Set up a <Realm> element, as described below, in your + $CATALINA_BASE/conf/server.xml file.
  8. +
  9. Restart Tomcat if it is already running.
  10. +
+ +
Realm Element Attributes
+ +

To configure DataSourceRealm, you will create a <Realm> +element and nest it in your $CATALINA_BASE/conf/server.xml file, +as described above. The attributes for the +DataSourceRealm are defined in the Realm +configuration documentation.

+ +
Example
+ +

An example SQL script to create the needed tables might look something +like this (adapt the syntax as required for your particular database):

+
create table users (
+  user_name         varchar(15) not null primary key,
+  user_pass         varchar(15) not null
+);
+
+create table user_roles (
+  user_name         varchar(15) not null,
+  role_name         varchar(15) not null,
+  primary key (user_name, role_name)
+);
+ +

Here is an example for using a MySQL database called "authority", configured +with the tables described above, and accessed with the JNDI JDBC DataSource with +name "java:/comp/env/jdbc/authority".

+
<Realm className="org.apache.catalina.realm.DataSourceRealm"
+   dataSourceName="jdbc/authority"
+   userTable="users" userNameCol="user_name" userCredCol="user_pass"
+   userRoleTable="user_roles" roleNameCol="role_name"/>
+ +
Additional Notes
+ +

DataSourceRealm operates according to the following rules:

+
    +
  • When a user attempts to access a protected resource for the first time, + Tomcat will call the authenticate() method of this + Realm. Thus, any changes you have made to the database + directly (new users, changed passwords or roles, etc.) will be immediately + reflected.
  • +
  • Once a user has been authenticated, the user (and his or her associated + roles) are cached within Tomcat for the duration of the user's login. + (For FORM-based authentication, that means until the session times out or + is invalidated; for BASIC authentication, that means until the user + closes their browser). The cached user is not saved and + restored across sessions serialisations. Any changes to the database + information for an already authenticated user will not be + reflected until the next time that user logs on again.
  • +
  • Administering the information in the users and user roles + table is the responsibility of your own applications. Tomcat does not + provide any built-in capabilities to maintain users and roles.
  • +
+ +
+ + +

JNDIRealm

+ +
Introduction
+ +

JNDIRealm is an implementation of the Tomcat +Realm interface that looks up users in an LDAP directory +server accessed by a JNDI provider (typically, the standard LDAP +provider that is available with the JNDI API classes). The realm +supports a variety of approaches to using a directory for +authentication.

+ +
Connecting to the directory
+ +

The realm's connection to the directory is defined by the +connectionURL configuration attribute. This is a URL +whose format is defined by the JNDI provider. It is usually an LDAP +URL that specifies the domain name of the directory server to connect +to, and optionally the port number and distinguished name (DN) of the +required root naming context.

+ +

If you have more than one provider you can configure an +alternateURL. If a socket connection can not be +made to the provider at the connectionURL an +attempt will be made to use the alternateURL.

+ +

When making a connection in order to search the directory and +retrieve user and role information, the realm authenticates itself to +the directory with the username and password specified by the +connectionName and +connectionPassword properties. If these properties +are not specified the connection is anonymous. This is sufficient in +many cases. +

+ + +
Selecting the user's directory entry
+ +

Each user that can be authenticated must be represented in the +directory by an individual entry that corresponds to an element in the +initial DirContext defined by the +connectionURL attribute. This user entry must have an +attribute containing the username that is presented for +authentication.

+ +

Often the distinguished name of the user's entry contains the +username presented for authentication but is otherwise the same for +all users. In this case the userPattern attribute may +be used to specify the DN, with "{0}" marking where +the username should be substituted.

+ +

Otherwise the realm must search the directory to find a unique entry +containing the username. The following attributes configure this +search:

+ +
    +
  • userBase - the entry that is the base of + the subtree containing users. If not specified, the search + base is the top-level context.
  • + +
  • userSubtree - the search scope. Set to + true if you wish to search the entire subtree + rooted at the userBase entry. The default value + of false requests a single-level search + including only the top level.
  • + +
  • userSearch - pattern specifying the LDAP + search filter to use after substitution of the username.
  • + +
+ + +
Authenticating the user
+ +
    +
  • +

    Bind mode

    + +

    By default the realm authenticates a user by binding to +the directory with the DN of the entry for that user and the password +presented by the user. If this simple bind succeeds the user is considered to +be authenticated.

    + +

    For security reasons a directory may store a digest of the user's +password rather than the clear text version (see +Digested Passwords for more information). In that case, +as part of the simple bind operation the directory automatically +computes the correct digest of the plaintext password presented by the +user before validating it against the stored value. In bind mode, +therefore, the realm is not involved in digest processing. The +digest attribute is not used, and will be ignored if +set.

    +
  • + +
  • +

    Comparison mode

    +

    Alternatively, the realm may retrieve the stored +password from the directory and compare it explicitly with the value +presented by the user. This mode is configured by setting the +userPassword attribute to the name of a directory +attribute in the user's entry that contains the password.

    + +

    Comparison mode has some disadvantages. First, the +connectionName and +connectionPassword attributes must be configured to +allow the realm to read users' passwords in the directory. For +security reasons this is generally undesirable; indeed many directory +implementations will not allow even the directory manager to read +these passwords. In addition, the realm must handle password digests +itself, including variations in the algorithms used and ways of +representing password hashes in the directory. However, the realm may +sometimes need access to the stored password, for example to support +HTTP Digest Access Authentication (RFC 2069). (Note that HTTP digest +authentication is different from the storage of password digests in +the repository for user information as discussed above). +

    +
  • +
+ +
Assigning roles to the user
+ +

The directory realm supports two approaches to the representation +of roles in the directory:

+ +
    +
  • +

    Roles as explicit directory entries

    + +

    Roles may be represented by explicit directory entries. A role +entry is usually an LDAP group entry with one attribute +containing the name of the role and another whose values are the +distinguished names or usernames of the users in that role. The +following attributes configure a directory search to +find the names of roles associated with the authenticated user:

    + +
      +
    • roleBase - the base entry for the role search. + If not specified, the search base is the top-level directory + context.
    • + +
    • roleSubtree - the search + scope. Set to true if you wish to search the entire + subtree rooted at the roleBase entry. The default + value of false requests a single-level search + including the top level only.
    • + +
    • roleSearch - the LDAP search filter for + selecting role entries. It optionally includes pattern + replacements "{0}" for the distinguished name and/or "{1}" for the + username and/or "{2}" for an attribute from user's directory entry, + of the authenticated user. Use userRoleAttribute to + specify the name of the attribute that provides the value for "{2}".
    • + +
    • roleName - the attribute in a role entry + containing the name of that role.
    • + +
    • roleNested - enable nested roles. Set to + true if you want to nest roles in roles. If configured, then + every newly found roleName and distinguished + Name will be recursively tried for a new role search. + The default value is false.
    • + +
    + +
  • +
+ +
    +
  • +

    Roles as an attribute of the user entry

    + +

    Role names may also be held as the values of an attribute in the +user's directory entry. Use userRoleName to specify +the name of this attribute.

    + +
  • +
+

A combination of both approaches to role representation may be used.

+ +
Quick Start
+ +

To set up Tomcat to use JNDIRealm, you will need to follow these steps:

+
    +
  1. Make sure your directory server is configured with a schema that matches + the requirements listed above.
  2. +
  3. If required, configure a username and password for use by Tomcat, that has + read only access to the information described above. (Tomcat will + never attempt to modify this information.)
  4. +
  5. Set up a <Realm> element, as described below, in your + $CATALINA_BASE/conf/server.xml file.
  6. +
  7. Restart Tomcat if it is already running.
  8. +
+ +
Realm Element Attributes
+ +

To configure JNDIRealm, you will create a <Realm> +element and nest it in your $CATALINA_BASE/conf/server.xml file, +as described above. The attributes for the +JNDIRealm are defined in the Realm configuration +documentation.

+ +
Example
+ +

Creation of the appropriate schema in your directory server is beyond the +scope of this document, because it is unique to each directory server +implementation. In the examples below, we will assume that you are using a +distribution of the OpenLDAP directory server (version 2.0.11 or later), which +can be downloaded from +https://www.openldap.org. Assume that +your slapd.conf file contains the following settings +(among others):

+
database ldbm
+suffix dc="mycompany",dc="com"
+rootdn "cn=Manager,dc=mycompany,dc=com"
+rootpw secret
+ +

We will assume for connectionURL that the directory +server runs on the same machine as Tomcat. See +http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html +for more information about configuring and using the JNDI LDAP +provider.

+ +

Next, assume that this directory server has been populated with elements +as shown below (in LDIF format):

+ +
# Define top-level entry
+dn: dc=mycompany,dc=com
+objectClass: dcObject
+dc:mycompany
+
+# Define an entry to contain people
+# searches for users are based on this entry
+dn: ou=people,dc=mycompany,dc=com
+objectClass: organizationalUnit
+ou: people
+
+# Define a user entry for Janet Jones
+dn: uid=jjones,ou=people,dc=mycompany,dc=com
+objectClass: inetOrgPerson
+uid: jjones
+sn: jones
+cn: janet jones
+mail: j.jones@mycompany.com
+userPassword: janet
+
+# Define a user entry for Fred Bloggs
+dn: uid=fbloggs,ou=people,dc=mycompany,dc=com
+objectClass: inetOrgPerson
+uid: fbloggs
+sn: bloggs
+cn: fred bloggs
+mail: f.bloggs@mycompany.com
+userPassword: fred
+
+# Define an entry to contain LDAP groups
+# searches for roles are based on this entry
+dn: ou=groups,dc=mycompany,dc=com
+objectClass: organizationalUnit
+ou: groups
+
+# Define an entry for the "tomcat" role
+dn: cn=tomcat,ou=groups,dc=mycompany,dc=com
+objectClass: groupOfUniqueNames
+cn: tomcat
+uniqueMember: uid=jjones,ou=people,dc=mycompany,dc=com
+uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
+
+# Define an entry for the "role1" role
+dn: cn=role1,ou=groups,dc=mycompany,dc=com
+objectClass: groupOfUniqueNames
+cn: role1
+uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
+ +

An example Realm element for the OpenLDAP directory +server configured as described above might look like this, assuming +that users use their uid (e.g. jjones) to login to the +application and that an anonymous connection is sufficient to search +the directory and retrieve role information:

+ +
<Realm   className="org.apache.catalina.realm.JNDIRealm"
+     connectionURL="ldap://localhost:389"
+       userPattern="uid={0},ou=people,dc=mycompany,dc=com"
+          roleBase="ou=groups,dc=mycompany,dc=com"
+          roleName="cn"
+        roleSearch="(uniqueMember={0})"
+/>
+ +

With this configuration, the realm will determine the user's +distinguished name by substituting the username into the +userPattern, authenticate by binding to the directory +with this DN and the password received from the user, and search the +directory to find the user's roles.

+ +

Now suppose that users are expected to enter their email address +rather than their userid when logging in. In this case the realm must +search the directory for the user's entry. (A search is also necessary +when user entries are held in multiple subtrees corresponding perhaps +to different organizational units or company locations).

+ +

Further, suppose that in addition to the group entries you want to +use an attribute of the user's entry to hold roles. Now the entry for +Janet Jones might read as follows:

+ +
dn: uid=jjones,ou=people,dc=mycompany,dc=com
+objectClass: inetOrgPerson
+uid: jjones
+sn: jones
+cn: janet jones
+mail: j.jones@mycompany.com
+memberOf: role2
+memberOf: role3
+userPassword: janet
+ +

This realm configuration would satisfy the new requirements:

+ +
<Realm   className="org.apache.catalina.realm.JNDIRealm"
+     connectionURL="ldap://localhost:389"
+          userBase="ou=people,dc=mycompany,dc=com"
+        userSearch="(mail={0})"
+      userRoleName="memberOf"
+          roleBase="ou=groups,dc=mycompany,dc=com"
+          roleName="cn"
+        roleSearch="(uniqueMember={0})"
+/>
+ +

Now when Janet Jones logs in as "j.jones@mycompany.com", the realm +searches the directory for a unique entry with that value as its mail +attribute and attempts to bind to the directory as +uid=jjones,ou=people,dc=mycompany,dc=com with the given +password. If authentication succeeds, she is assigned three roles: +"role2" and "role3", the values of the "memberOf" attribute in her +directory entry, and "tomcat", the value of the "cn" attribute in the +only group entry of which she is a member.

+ +

Finally, to authenticate the user by retrieving +the password from the directory and making a local comparison in the +realm, you might use a realm configuration like this:

+ +
<Realm   className="org.apache.catalina.realm.JNDIRealm"
+    connectionName="cn=Manager,dc=mycompany,dc=com"
+connectionPassword="secret"
+     connectionURL="ldap://localhost:389"
+      userPassword="userPassword"
+       userPattern="uid={0},ou=people,dc=mycompany,dc=com"
+          roleBase="ou=groups,dc=mycompany,dc=com"
+          roleName="cn"
+        roleSearch="(uniqueMember={0})"
+/>
+ +

However, as discussed above, the default bind mode for +authentication is usually to be preferred.

+ +
Additional Notes
+ +

JNDIRealm operates according to the following rules:

+
    +
  • When a user attempts to access a protected resource for the first time, + Tomcat will call the authenticate() method of this + Realm. Thus, any changes you have made to the directory + (new users, changed passwords or roles, etc.) will be immediately + reflected.
  • +
  • Once a user has been authenticated, the user (and his or her associated + roles) are cached within Tomcat for the duration of the user's login. + (For FORM-based authentication, that means until the session times out or + is invalidated; for BASIC authentication, that means until the user + closes their browser). The cached user is not saved and + restored across sessions serialisations. Any changes to the directory + information for an already authenticated user will not be + reflected until the next time that user logs on again.
  • +
  • Administering the information in the directory server + is the responsibility of your own applications. Tomcat does not + provide any built-in capabilities to maintain users and roles.
  • +
+ +
+ + +

UserDatabaseRealm

+ +
Introduction
+ +

UserDatabaseRealm is an implementation of the Tomcat +Realm interface that uses a JNDI resource to store user +information. By default, the JNDI resource is backed by an XML file. It is not +designed for large-scale production use. At startup time, the UserDatabaseRealm +loads information about all users, and their corresponding roles, from an XML +document (by default, this document is loaded from +$CATALINA_BASE/conf/tomcat-users.xml). The users, their passwords +and their roles may all be editing dynamically, typically via JMX. Changes may +be saved and will be reflected in the XML file.

+ +
Realm Element Attributes
+ +

To configure UserDatabaseRealm, you will create a <Realm> +element and nest it in your $CATALINA_BASE/conf/server.xml file, +as described above. The attributes for the +UserDatabaseRealm are defined in the Realm +configuration documentation.

+ +
User File Format
+ +

The users file uses the same format as the +MemoryRealm.

+ +
Example
+ +

The default installation of Tomcat is configured with a UserDatabaseRealm +nested inside the <Engine> element, so that it applies +to all virtual hosts and web applications. The default contents of the +conf/tomcat-users.xml file is:

+
<tomcat-users>
+  <user username="tomcat" password="tomcat" roles="tomcat" />
+  <user username="role1"  password="tomcat" roles="role1"  />
+  <user username="both"   password="tomcat" roles="tomcat,role1" />
+</tomcat-users>
+ +
Additional Notes
+ +

UserDatabaseRealm operates according to the following rules:

+
    +
  • When Tomcat first starts up, it loads all defined users and their + associated information from the users file. Changes made to the data in + this file will not be recognized until Tomcat is + restarted. Changes may be made via the UserDatabase resource. Tomcat + provides MBeans that may be accessed via JMX for this purpose.
  • +
  • When a user attempts to access a protected resource for the first time, + Tomcat will call the authenticate() method of this + Realm.
  • +
  • Once a user has been authenticated, the user (and his or her associated + roles) are cached within Tomcat for the duration of the user's login. + (For FORM-based authentication, that means until the session times out or + is invalidated; for BASIC authentication, that means until the user + closes their browser). The cached user is not saved and + restored across sessions serialisations.
  • +
+ + +
+ + +

MemoryRealm

+ +
Introduction
+ +

MemoryRealm is a simple demonstration implementation of the +Tomcat Realm interface. It is not designed for production use. +At startup time, MemoryRealm loads information about all users, and their +corresponding roles, from an XML document (by default, this document is loaded +from $CATALINA_BASE/conf/tomcat-users.xml). Changes to the data +in this file are not recognized until Tomcat is restarted.

+ +
Realm Element Attributes
+ +

To configure MemoryRealm, you will create a <Realm> +element and nest it in your $CATALINA_BASE/conf/server.xml file, +as described above. The attributes for the +MemoryRealm are defined in the Realm +configuration documentation.

+ +
User File Format
+ +

The users file (by default, conf/tomcat-users.xml must be an +XML document, with a root element <tomcat-users>. Nested +inside the root element will be a <user> element for each +valid user, consisting of the following attributes:

+
    +
  • name - Username this user must log on with.
  • +
  • password - Password this user must log on with (in + clear text if the digest attribute was not set on the + <Realm> element, or digested appropriately as + described here otherwise).
  • +
  • roles - Comma-delimited list of the role names + associated with this user.
  • +
+ +
Additional Notes
+ +

MemoryRealm operates according to the following rules:

+
    +
  • When Tomcat first starts up, it loads all defined users and their + associated information from the users file. Changes to the data in + this file will not be recognized until Tomcat is + restarted.
  • +
  • When a user attempts to access a protected resource for the first time, + Tomcat will call the authenticate() method of this + Realm.
  • +
  • Once a user has been authenticated, the user (and his or her associated + roles) are cached within Tomcat for the duration of the user's login. + (For FORM-based authentication, that means until the session times out or + is invalidated; for BASIC authentication, that means until the user + closes their browser). The cached user is not saved and + restored across sessions serialisations.
  • +
  • Administering the information in the users file is the responsibility + of your application. Tomcat does not + provide any built-in capabilities to maintain users and roles.
  • +
+ + +
+ + +

JAASRealm

+ +
Introduction
+ +

JAASRealm is an implementation of the Tomcat +Realm interface that authenticates users through the Java +Authentication & Authorization Service (JAAS) framework which is now +provided as part of the standard Java SE API.

+

Using JAASRealm gives the developer the ability to combine +practically any conceivable security realm with Tomcat's CMA.

+

JAASRealm is prototype for Tomcat of the JAAS-based +J2EE authentication framework for J2EE v1.4, based on the JCP Specification +Request 196 to enhance container-managed security and promote +'pluggable' authentication mechanisms whose implementations would be +container-independent. +

+

Based on the JAAS login module and principal (see javax.security.auth.spi.LoginModule +and javax.security.Principal), you can develop your own +security mechanism or wrap another third-party mechanism for +integration with the CMA as implemented by Tomcat. +

+ +
Quick Start
+

To set up Tomcat to use JAASRealm with your own JAAS login module, + you will need to follow these steps:

+
    +
  1. Write your own LoginModule, User and Role classes based +on JAAS (see + +the JAAS Authentication Tutorial and + +the JAAS Login Module Developer's Guide) to be managed by the JAAS Login +Context (javax.security.auth.login.LoginContext) +When developing your LoginModule, note that JAASRealm's built-in CallbackHandler +only recognizes the NameCallback and PasswordCallback at present. +
  2. +
  3. Although not specified in JAAS, you should create +separate classes to distinguish between users and roles, extending javax.security.Principal, +so that Tomcat can tell which Principals returned from your login +module are users and which are roles (see org.apache.catalina.realm.JAASRealm). +Regardless, the first Principal returned is always treated as the user Principal. +
  4. +
  5. Place the compiled classes on Tomcat's classpath +
  6. +
  7. Set up a login.config file for Java (see +JAAS LoginConfig file) and tell Tomcat where to find it by specifying +its location to the JVM, for instance by setting the environment +variable: JAVA_OPTS=$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config
  8. + +
  9. Configure your security-constraints in your web.xml for +the resources you want to protect
  10. +
  11. Configure the JAASRealm module in your server.xml
  12. +
  13. Restart Tomcat if it is already running.
  14. +
+
Realm Element Attributes
+

To configure JAASRealm as for step 6 above, you create +a <Realm> element and nest it in your +$CATALINA_BASE/conf/server.xml +file within your <Engine> node. The attributes for the +JAASRealm are defined in the Realm +configuration documentation.

+ +
Example
+ +

Here is an example of how your server.xml snippet should look.

+ +
<Realm className="org.apache.catalina.realm.JAASRealm"
+                appName="MyFooRealm"
+    userClassNames="org.foobar.realm.FooUser"
+     roleClassNames="org.foobar.realm.FooRole"/>
+ +

It is the responsibility of your login module to create and save User and +Role objects representing Principals for the user +(javax.security.auth.Subject). If your login module doesn't +create a user object but also doesn't throw a login exception, then the +Tomcat CMA will break and you will be left at the +http://localhost:8080/myapp/j_security_check URI or at some other +unspecified location.

+ +

The flexibility of the JAAS approach is two-fold:

+
    +
  • you can carry out whatever processing you require behind +the scenes in your own login module.
  • +
  • you can plug in a completely different LoginModule by changing the configuration +and restarting the server, without any code changes to your application.
  • +
+ +
Additional Notes
+
    +
  • When a user attempts to access a protected resource for + the first time, Tomcat will call the authenticate() + method of this Realm. Thus, any changes you have made in + the security mechanism directly (new users, changed passwords or + roles, etc.) will be immediately reflected.
  • +
  • Once a user has been authenticated, the user (and his or + her associated roles) are cached within Tomcat for the duration of + the user's login. For FORM-based authentication, that means until + the session times out or is invalidated; for BASIC authentication, + that means until the user closes their browser. Any changes to the + security information for an already authenticated user will not + be reflected until the next time that user logs on again.
  • +
  • As with other Realm implementations, digested passwords + are supported if the <Realm> element in server.xml + contains a digest attribute; JAASRealm's CallbackHandler + will digest the password prior to passing it back to the LoginModule
  • +
+ +
+ + +

CombinedRealm

+ +
Introduction
+ +

CombinedRealm is an implementation of the Tomcat + Realm interface that authenticates users through one or more + sub-Realms.

+ +

Using CombinedRealm gives the developer the ability to combine multiple + Realms of the same or different types. This can be used to authenticate + against different sources, provide fall back in case one Realm fails or for + any other purpose that requires multiple Realms.

+ +

Sub-realms are defined by nesting Realm elements inside the + Realm element that defines the CombinedRealm. Authentication + will be attempted against each Realm in the order they are + listed. Authentication against any Realm will be sufficient to authenticate + the user.

+ +
Realm Element Attributes
+

To configure a CombinedRealm, you create a <Realm> + element and nest it in your $CATALINA_BASE/conf/server.xml + file within your <Engine> or <Host>. + You can also nest inside a <Context> node in a + context.xml file.

+ +
Example
+ +

Here is an example of how your server.xml snippet should look to use a +UserDatabase Realm and a DataSource Realm.

+ +
<Realm className="org.apache.catalina.realm.CombinedRealm" >
+   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+             resourceName="UserDatabase"/>
+   <Realm className="org.apache.catalina.realm.DataSourceRealm"
+             dataSourceName="jdbc/authority"
+             userTable="users" userNameCol="user_name" userCredCol="user_pass"
+             userRoleTable="user_roles" roleNameCol="role_name"/>
+</Realm>
+ +
+ +

LockOutRealm

+ +
Introduction
+ +

LockOutRealm is an implementation of the Tomcat + Realm interface that extends the CombinedRealm to provide lock + out functionality to provide a user lock out mechanism if there are too many + failed authentication attempts in a given period of time.

+ +

To ensure correct operation, there is a reasonable degree of + synchronisation in this Realm.

+ +

This Realm does not require modification to the underlying Realms or the + associated user storage mechanisms. It achieves this by recording all failed + logins, including those for users that do not exist. To prevent a DOS by + deliberating making requests with invalid users (and hence causing this + cache to grow) the size of the list of users that have failed authentication + is limited.

+ +

Sub-realms are defined by nesting Realm elements inside the + Realm element that defines the LockOutRealm. Authentication + will be attempted against each Realm in the order they are + listed. Authentication against any Realm will be sufficient to authenticate + the user.

+ +
Realm Element Attributes
+

To configure a LockOutRealm, you create a <Realm> + element and nest it in your $CATALINA_BASE/conf/server.xml + file within your <Engine> or <Host>. + You can also nest inside a <Context> node in a + context.xml file. The attributes for the + LockOutRealm are defined in the Realm + configuration documentation.

+ +
Example
+ +

Here is an example of how your server.xml snippet should look to add lock out +functionality to a UserDatabase Realm.

+ +
<Realm className="org.apache.catalina.realm.LockOutRealm" >
+   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+             resourceName="UserDatabase"/>
+</Realm>
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/rewrite.html b/test.dockerapp/tomcat/webapps/docs/rewrite.html new file mode 100644 index 0000000..e984a9b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/rewrite.html @@ -0,0 +1,717 @@ + +Apache Tomcat 8 (8.0.53) - The rewrite Valve

The rewrite Valve

Introduction

+ +

The rewrite valve implements URL rewrite functionality in a way that is + very similar to mod_rewrite from Apache HTTP Server.

+ +

Configuration

+ +

The rewrite valve is configured as a valve using the org.apache.catalina.valves.rewrite.RewriteValve + class name.

+ +

The rewrite valve can be configured as a valve added in a Host. + See virtual-server documentation for + informations how to configure it. It will use a rewrite.config file + containing the rewrite directives, it must be placed in the Host configuration + folder. +

+ +

It can also be in the context.xml of a webapp. + The valve will then use a rewrite.config file containing the + rewrite directives, it must be placed in the WEB-INF folder of the web application +

+ +

Directives

+ +

The rewrite.config file contains a list of directives which closely + resemble the directives used by mod_rewrite, in particular the central + RewriteRule and RewriteCond directives. Lines that start with a + # character are treated as comments and will be ignored.

+ +

Note: This section is a modified version of the mod_rewrite documentation, + which is Copyright 1995-2006 The Apache Software Foundation, and licensed under the + under the Apache License, Version 2.0.

+ +

RewriteCond

+ +

Syntax: RewriteCond TestString CondPattern

+ +

The RewriteCond directive defines a rule condition. One or more RewriteCond + can precede a RewriteRule directive. The following rule is then only used if both + the current state of the URI matches its pattern, and if these conditions are met.

+ +

TestString is a string which can contain the + following expanded constructs in addition to plain text:

+ +
    +
  • + RewriteRule backreferences: These are + backreferences of the form $N + (0 <= N <= 9), which provide access to the grouped + parts (in parentheses) of the pattern, from the + RewriteRule which is subject to the current + set of RewriteCond conditions.. +
  • +
  • + RewriteCond backreferences: These are + backreferences of the form %N + (1 <= N <= 9), which provide access to the grouped + parts (again, in parentheses) of the pattern, from the last matched + RewriteCond in the current set + of conditions. +
  • +
  • + RewriteMap expansions: These are + expansions of the form ${mapname:key|default}. + See the documentation for + RewriteMap for more details. +
  • +
  • + Server-Variables: These are variables of + the form + %{ NAME_OF_VARIABLE + } + where NAME_OF_VARIABLE can be a string taken + from the following list: + +
      +
    • +

      HTTP headers:

      +

      + HTTP_USER_AGENT
      + HTTP_REFERER
      + HTTP_COOKIE
      + HTTP_FORWARDED
      + HTTP_HOST
      + HTTP_PROXY_CONNECTION
      + HTTP_ACCEPT
      +

      +
    • +
    • +

      connection & request:

      +

      + REMOTE_ADDR
      + REMOTE_HOST
      + REMOTE_PORT
      + REMOTE_USER
      + REMOTE_IDENT
      + REQUEST_METHOD
      + SCRIPT_FILENAME
      + REQUEST_PATH
      + CONTEXT_PATH
      + SERVLET_PATH
      + PATH_INFO
      + QUERY_STRING
      + AUTH_TYPE
      +

      +
    • +
    • +

      server internals:

      +

      + DOCUMENT_ROOT
      + SERVER_NAME
      + SERVER_ADDR
      + SERVER_PORT
      + SERVER_PROTOCOL
      + SERVER_SOFTWARE
      +

      +
    • +
    • +

      date and time:

      +

      + TIME_YEAR
      + TIME_MON
      + TIME_DAY
      + TIME_HOUR
      + TIME_MIN
      + TIME_SEC
      + TIME_WDAY
      + TIME
      +

      +
    • +
    • +

      specials:

      +

      + THE_REQUEST
      + REQUEST_URI
      + REQUEST_FILENAME
      + HTTPS
      +

      +
    • +
    + +

    These variables all + correspond to the similarly named HTTP + MIME-headers and Servlet API methods. + Most are documented elsewhere in the Manual or in + the CGI specification. Those that are special to + the rewrite valve include those below.

    + +
    + +
    REQUEST_PATH
    + +
    Corresponds to the full path that is used for mapping.
    + +
    CONTEXT_PATH
    + +
    Corresponds to the path of the mapped context.
    + +
    SERVLET_PATH
    + +
    Corresponds to the servlet path.
    + +
    THE_REQUEST
    + +
    The full HTTP request line sent by the + browser to the server (e.g., "GET + /index.html HTTP/1.1"). This does not + include any additional headers sent by the + browser.
    + +
    REQUEST_URI
    + +
    The resource requested in the HTTP request + line. (In the example above, this would be + "/index.html".)
    + +
    REQUEST_FILENAME
    + +
    The full local file system path to the file or + script matching the request.
    + +
    HTTPS
    + +
    Will contain the text "on" if the connection is + using SSL/TLS, or "off" otherwise.
    + +
    + +
  • +
+ +

Other things you should be aware of:

+ +
    +
  1. The variables SCRIPT_FILENAME and REQUEST_FILENAME + contain the same value - the value of the + filename field of the internal + request_rec structure of the Apache server. + The first name is the commonly known CGI variable name + while the second is the appropriate counterpart of + REQUEST_URI (which contains the value of the + uri field of request_rec).
  2. + +
  3. + %{ENV:variable}, where variable can be + any Java system property, is also available.
  4. + +
  5. + %{SSL:variable}, where variable is the + name of an SSL environment + variable, are not implemented yet. Example: + %{SSL:SSL_CIPHER_USEKEYSIZE} may expand to + 128.
  6. + +
  7. + %{HTTP:header}, where header can be + any HTTP MIME-header name, can always be used to obtain the + value of a header sent in the HTTP request. + Example: %{HTTP:Proxy-Connection} is + the value of the HTTP header + ``Proxy-Connection:''.
  8. + +
+ +

CondPattern is the condition pattern, + a regular expression which is applied to the + current instance of the TestString. + TestString is first evaluated, before being matched against + CondPattern.

+ +

Remember: CondPattern is a + perl compatible regular expression with some + additions:

+ +
    +
  1. You can prefix the pattern string with a + '!' character (exclamation mark) to specify a + non-matching pattern.
  2. + +
  3. + There are some special variants of CondPatterns. + Instead of real regular expression strings you can also + use one of the following: + +
      +
    • '<CondPattern' (lexicographically + precedes)
      + Treats the CondPattern as a plain string and + compares it lexicographically to TestString. True if + TestString lexicographically precedes + CondPattern.
    • + +
    • '>CondPattern' (lexicographically + follows)
      + Treats the CondPattern as a plain string and + compares it lexicographically to TestString. True if + TestString lexicographically follows + CondPattern.
    • + +
    • '=CondPattern' (lexicographically + equal)
      + Treats the CondPattern as a plain string and + compares it lexicographically to TestString. True if + TestString is lexicographically equal to + CondPattern (the two strings are exactly + equal, character for character). If CondPattern + is "" (two quotation marks) this + compares TestString to the empty string.
    • + +
    • '-d' (is + directory)
      + Treats the TestString as a pathname and tests + whether or not it exists, and is a directory.
    • + +
    • '-f' (is regular + file)
      + Treats the TestString as a pathname and tests + whether or not it exists, and is a regular file.
    • + +
    • '-s' (is regular file, with + size)
      + Treats the TestString as a pathname and tests + whether or not it exists, and is a regular file with size greater + than zero.
    • + +
    + +Note: + All of these tests can + also be prefixed by an exclamation mark ('!') to + negate their meaning. + +
  4. + +
  5. You can also set special flags for + CondPattern by appending + [flags] + as the third argument to the RewriteCond + directive, where flags is a comma-separated list of any of the + following flags: + +
      +
    • 'nocase|NC' + (no case)
      + This makes the test case-insensitive - differences + between 'A-Z' and 'a-z' are ignored, both in the + expanded TestString and the CondPattern. + This flag is effective only for comparisons between + TestString and CondPattern. It has no + effect on file system and subrequest checks.
    • + +
    • + 'ornext|OR' + (or next condition)
      + Use this to combine rule conditions with a local OR + instead of the implicit AND. Typical example: + +
      RewriteCond %{REMOTE_HOST}  ^host1.*  [OR]
      +RewriteCond %{REMOTE_HOST}  ^host2.*  [OR]
      +RewriteCond %{REMOTE_HOST}  ^host3.*
      +RewriteRule ...some special stuff for any of these hosts...
      + + Without this flag you would have to write the condition/rule + pair three times. +
    • +
    +
  6. +
+ +

Example:

+ +

To rewrite the Homepage of a site according to the + ``User-Agent:'' header of the request, you can + use the following:

+ +
RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
+RewriteRule  ^/$                 /homepage.max.html  [L]
+
+RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
+RewriteRule  ^/$                 /homepage.min.html  [L]
+
+RewriteRule  ^/$                 /homepage.std.html  [L]
+ +

Explanation: If you use a browser which identifies itself + as 'Mozilla' (including Netscape Navigator, Mozilla etc), then you + get the max homepage (which could include frames, or other special + features). + If you use the Lynx browser (which is terminal-based), then + you get the min homepage (which could be a version designed for + easy, text-only browsing). + If neither of these conditions apply (you use any other browser, + or your browser identifies itself as something non-standard), you get + the std (standard) homepage.

+ +
+ +

RewriteMap

+ +

Syntax: RewriteMap name rewriteMapClassName optionalParameters

+ +

The maps are implemented using an interface that users must implement. Its class + name is org.apache.catalina.valves.rewrite.RewriteMap, and its code is:

+ +
package org.apache.catalina.valves.rewrite;
+
+public interface RewriteMap {
+    public String setParameters(String params);
+    public String lookup(String key);
+}
+ +
+ +

RewriteRule

+ +

Syntax: RewriteRule Pattern Substitution

+ +

The RewriteRule directive is the real + rewriting workhorse. The directive can occur more than once, + with each instance defining a single rewrite rule. The + order in which these rules are defined is important - this is the order + in which they will be applied at run-time.

+ +

Pattern is a perl compatible regular + expression, which is applied to the current URL. + ``Current'' means the value of the URL when this rule is + applied. This may not be the originally requested URL, + which may already have matched a previous rule, and have been + altered.

+ +

Some hints on the syntax of regular + expressions:

+ + +
+Text:
+  .           Any single character
+  [chars]     Character class: Any character of the class ``chars''
+  [^chars]    Character class: Not a character of the class ``chars''
+  text1|text2 Alternative: text1 or text2
+
+Quantifiers:
+  ?           0 or 1 occurrences of the preceding text
+  *           0 or N occurrences of the preceding text (N > 0)
+  +           1 or N occurrences of the preceding text (N > 1)
+
+Grouping:
+  (text)      Grouping of text
+              (used either to set the borders of an alternative as above, or
+              to make backreferences, where the Nth group can
+              be referred to on the RHS of a RewriteRule as $N)
+
+Anchors:
+  ^           Start-of-line anchor
+  $           End-of-line anchor
+
+Escaping:
+  \char       escape the given char
+              (for instance, to specify the chars ".[]()" etc.)
+
+ +

For more information about regular expressions, have a look at the + perl regular expression manpage ("perldoc + perlre"). If you are interested in more detailed + information about regular expressions and their variants + (POSIX regex etc.) the following book is dedicated to this topic:

+ +

+ Mastering Regular Expressions, 2nd Edition
+ Jeffrey E.F. Friedl
+ O'Reilly & Associates, Inc. 2002
+ ISBN 978-0-596-00289-3
+

+ +

In the rules, the NOT character + ('!') is also available as a possible pattern + prefix. This enables you to negate a pattern; to say, for instance: + ``if the current URL does NOT match this + pattern''. This can be used for exceptional cases, where + it is easier to match the negative pattern, or as a last + default rule.

+ +

+Note: When using the NOT character to negate a pattern, you cannot include +grouped wildcard parts in that pattern. This is because, when the +pattern does NOT match (i.e., the negation matches), there are no +contents for the groups. Thus, if negated patterns are used, you +cannot use $N in the substitution string! +

+ +

The substitution of a + rewrite rule is the string which is substituted for (or + replaces) the original URL which Pattern + matched. In addition to plain text, it can include

+ +
    +
  1. back-references ($N) to the RewriteRule + pattern
  2. + +
  3. back-references (%N) to the last matched + RewriteCond pattern
  4. + +
  5. server-variables as in rule condition test-strings + (%{VARNAME})
  6. + +
  7. mapping-function calls + (${mapname:key|default})
  8. +
+

Back-references are identifiers of the form + $N + (N=0..9), which will be replaced + by the contents of the Nth group of the + matched Pattern. The server-variables are the same + as for the TestString of a RewriteCond + directive. The mapping-functions come from the + RewriteMap directive and are explained there. + These three types of variables are expanded in the order above.

+ +

As already mentioned, all rewrite rules are + applied to the Substitution (in the order in which + they are defined + in the config file). The URL is completely + replaced by the Substitution and the + rewriting process continues until all rules have been applied, + or it is explicitly terminated by a + L flag.

+ +

The special characters $ and % can + be quoted by prepending them with a backslash character + \.

+ +

There is a special substitution string named + '-' which means: NO + substitution! This is useful in providing + rewriting rules which only match + URLs but do not substitute anything for them. It is commonly used + in conjunction with the C (chain) flag, in order + to apply more than one pattern before substitution occurs.

+ +

Unlike newer mod_rewrite versions, the Tomcat rewrite valve does + not automatically support absolute URLs (the specific redirect flag + must be used to be able to specify an absolute URLs, see below) + or direct file serving.

+ +

Additionally you can set special flags for Substitution by + appending [flags] + as the third argument to the RewriteRule + directive. Flags is a comma-separated list of any of the + following flags:

+ +
    +
  • 'chain|C' + (chained with next rule)
    + This flag chains the current rule with the next rule + (which itself can be chained with the following rule, + and so on). This has the following effect: if a rule + matches, then processing continues as usual - + the flag has no effect. If the rule does + not match, then all following chained + rules are skipped. For instance, it can be used to remove the + ``.www'' part, inside a per-directory rule set, + when you let an external redirect happen (where the + ``.www'' part should not occur!).
  • + +
  • + 'cookie|CO=NAME:VAL:domain[:lifetime[:path]]' + (set cookie)
    + This sets a cookie in the client's browser. The cookie's name + is specified by NAME and the value is + VAL. The domain field is the domain of the + cookie, such as '.apache.org', the optional lifetime + is the lifetime of the cookie in minutes, and the optional + path is the path of the cookie
  • + +
  • + 'env|E=VAR:VAL' + (set environment variable)
    + This forces a request attribute named VAR to + be set to the value VAL, where VAL can + contain regexp backreferences ($N and + %N) which will be expanded. You can use this + flag more than once, to set more than one variable.
  • + +
  • 'forbidden|F' (force URL + to be forbidden)
    + This forces the current URL to be forbidden - it immediately + sends back a HTTP response of 403 (FORBIDDEN). + Use this flag in conjunction with + appropriate RewriteConds to conditionally block some + URLs.
  • + +
  • 'gone|G' (force URL to be + gone)
    + This forces the current URL to be gone - it + immediately sends back a HTTP response of 410 (GONE). Use + this flag to mark pages which no longer exist as gone.
  • + +
  • + 'host|H=Host' + (apply rewriting to host)
    + Rather that rewrite the URL, the virtual host will be + rewritten.
  • + +
  • 'last|L' + (last rule)
    + Stop the rewriting process here and don't apply any more + rewrite rules. This corresponds to the Perl + last command or the break command + in C. Use this flag to prevent the currently + rewritten URL from being rewritten further by following + rules. For example, use it to rewrite the root-path URL + ('/') to a real one, e.g., + '/e/www/'.
  • + +
  • 'next|N' + (next round)
    + Re-run the rewriting process (starting again with the + first rewriting rule). This time, the URL to match is no longer + the original URL, but rather the URL returned by the last rewriting rule. + This corresponds to the Perl next command or + the continue command in C. Use + this flag to restart the rewriting process - + to immediately go to the top of the loop.
    + Be careful not to create an infinite + loop!
  • + +
  • 'nocase|NC' + (no case)
    + This makes the Pattern case-insensitive, + ignoring difference between 'A-Z' and + 'a-z' when Pattern is matched against the current + URL.
  • + +
  • + 'noescape|NE' + (no URI escaping of + output)
    + This flag prevents the rewrite valve from applying the usual URI + escaping rules to the result of a rewrite. Ordinarily, + special characters (such as '%', '$', ';', and so on) + will be escaped into their hexcode equivalents ('%25', + '%24', and '%3B', respectively); this flag prevents this + from happening. This allows percent symbols to appear in + the output, as in +
    RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]
    + which would turn '/foo/zed' into a safe + request for '/bar?arg=P1=zed'. +
  • + + + +
  • 'qsappend|QSA' + (query string + append)
    + This flag forces the rewrite engine to append a query + string part of the substitution string to the existing string, + instead of replacing it. Use this when you want to add more + data to the query string via a rewrite rule.
  • + +
  • 'redirect|R + [=code]' (force + redirect)
    + Prefix Substitution with + http://thishost[:thisport]/ (which makes the + new URL a URI) to force a external redirection. If no + code is given, a HTTP response of 302 (FOUND, previously MOVED + TEMPORARILY) will be returned. If you want to use other response + codes in the range 300-399, simply specify the appropriate number + or use one of the following symbolic names: + temp (default), permanent, + seeother. Use this for rules to + canonicalize the URL and return it to the client - to + translate ``/~'' into + ``/u/'', or to always append a slash to + /u/user, etc.
    + Note: When you use this flag, make + sure that the substitution field is a valid URL! Otherwise, + you will be redirecting to an invalid location. Remember + that this flag on its own will only prepend + http://thishost[:thisport]/ to the URL, and rewriting + will continue. Usually, you will want to stop rewriting at this point, + and redirect immediately. To stop rewriting, you should add + the 'L' flag. +
  • + +
  • 'skip|S=num' + (skip next rule(s))
    + This flag forces the rewriting engine to skip the next + num rules in sequence, if the current rule + matches. Use this to make pseudo if-then-else constructs: + The last rule of the then-clause becomes + skip=N, where N is the number of rules in the + else-clause. (This is not the same as the + 'chain|C' flag!)
  • + +
  • + 'type|T=MIME-type' + (force MIME type)
    + Force the MIME-type of the target file to be + MIME-type. This can be used to + set up the content-type based on some conditions. + For example, the following snippet allows .php files to + be displayed by mod_php if they are called with + the .phps extension: +
    RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]
    +
  • +
+ +
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/security-howto.html b/test.dockerapp/tomcat/webapps/docs/security-howto.html new file mode 100644 index 0000000..309683d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/security-howto.html @@ -0,0 +1,526 @@ + +Apache Tomcat 8 (8.0.53) - Security Considerations

Security Considerations

Table of Contents

Introduction

+

Tomcat is configured to be reasonably secure for most use cases by + default. Some environments may require more, or less, secure configurations. + This page is to provide a single point of reference for configuration + options that may impact security and to offer some commentary on the + expected impact of changing those options. The intention is to provide a + list of configuration options that should be considered when assessing the + security of a Tomcat installation.

+ +

Note: Reading this page is not a substitute for reading + and understanding the detailed configuration documentation. Fuller + descriptions of these attributes may be found in the relevant documentation + pages.

+

Non-Tomcat settings

+

Tomcat configuration should not be the only line of defense. The other + components in the system (operating system, network, database, etc.) should + also be secured.

+

Tomcat should not be run under the root user. Create a dedicated user for + the Tomcat process and provide that user with the minimum necessary + permissions for the operating system. For example, it should not be possible + to log on remotely using the Tomcat user.

+

File permissions should also be suitably restricted. Taking the Tomcat + instances at the ASF as an example (where auto-deployment is disabled and + web applications are deployed as exploded directories), the standard + configuration is to have all Tomcat files owned by root with group Tomcat + and whilst owner has read/write privileges, group only has read and world + has no permissions. The exceptions are the logs, temp and work directory + that are owned by the Tomcat user rather than root. This means that even if + an attacker compromises the Tomcat process, they can't change the + Tomcat configuration, deploy new web applications or modify existing web + applications. The Tomcat process runs with a umask of 007 to maintain these + permissions.

+

At the network level, consider using a firewall to limit both incoming + and outgoing connections to only those connections you expect to be + present.

+ +

JMX

+

The security of the JMX connection is dependent on the implementation + provided by the JRE and therefore falls outside the control of Tomact.

+ +

Typically, access control is very limited (either read-only to + everything or read-write to everything). Tomcat exposes a large amount + of internal information and control via JMX to aid debugging, monitoring + and management. Give the limited access control available, JMX access + should be treated as equivalent to local root/admin access and restricted + accordingly.

+ +

The JMX access control provided by most (all?) JRE vendors does not + log failed authentication attempts, nor does it provide an account + lock-out feature after repeated failed authentications. This makes a + brute force attack easy to mount and difficult to detect.

+ +

Given all of the above, care should be taken to ensure that, if used, + the JMX interface is appropriately secured. Options you may wish to + consider to secure the JMX interface include:

+ +
    +
  • configuring a strong password for all JMX users;
  • +
  • binding the JMX listener only to an internal network;
  • +
  • limiting network access to the JMX port to trusted clients; and
  • +
  • providing an application specific health page for use by external + monitoring systems.
  • +
+
+ +

Default web applications

+ +

General

+

Tomcat ships with a number of web applications that are enabled by + default. Vulnerabilities have been discovered in these applications in the + past. Applications that are not required should be removed so the system + will not be at risk if another vulnerability is discovered.

+
+ +

ROOT

+

The ROOT web application presents a very low security risk but it does + include the version of Tomcat that is being used. The ROOT web application + should normally be removed from a publicly accessible Tomcat instance, not + for security reasons, but so that a more appropriate default page is shown + to users.

+
+ +

Documentation

+

The documentation web application presents a very low security risk but + it does identify the version of Tomcat that is being used. It should + normally be removed from a publicly accessible Tomcat instance.

+
+ +

Examples

+

The examples web application should always be removed from any security + sensitive installation. While the examples web application does not + contain any known vulnerabilities, it is known to contain features + (particularly the cookie examples that display the contents of all + received and allow new cookies to be set) that may be used by an attacker + in conjunction with a vulnerability in another application deployed on the + Tomcat instance to obtain additional information that would otherwise be + unavailable.

+
+ +

Manager

+

The Manager application allows the remote deployment of web + applications and is frequently targeted by attackers due to the widespread + use of weak passwords and publicly accessible Tomcat instances with the + Manager application enabled. The Manager application is not accessible by + default as no users are configured with the necessary access. If the + Manager application is enabled then guidance in the section + Securing Management Applications section should be + followed.

+
+ +

Host Manager

+

The Host Manager application allows the creation and management of + virtual hosts - including the enabling of the Manager application for a + virtual host. The Host Manager application is not accessible by default + as no users are configured with the necessary access. If the Host Manager + application is enabled then guidance in the section Securing + Management Applications section should be followed.

+
+ +

Securing Management Applications

+

When deploying a web application that provides management functions for + the Tomcat instance, the following guidelines should be followed:

+
    +
  • Ensure that any users permitted to access the management application + have strong passwords.
  • +
  • Do not remove the use of the LockOutRealm + which prevents brute force attacks against user passwords.
  • +
  • Uncomment the RemoteAddrValve + in /META-INF/context.xml which limits access to + localhost. If remote access is required, limit it to specific IP + addresses using this valve.
  • +
+
+

Security manager

+

Enabling the security manager causes web applications to be run in a + sandbox, significantly limiting a web application's ability to perform + malicious actions such as calling System.exit(), establishing network + connections or accessing the file system outside of the web application's + root and temporary directories. However, it should be noted that there are + some malicious actions, such as triggering high CPU consumption via an + infinite loop, that the security manager cannot prevent.

+ +

Enabling the security manager is usually done to limit the potential + impact, should an attacker find a way to compromise a trusted web + application . A security manager may also be used to reduce the risks of + running untrusted web applications (e.g. in hosting environments) but it + should be noted that the security manager only reduces the risks of + running untrusted web applications, it does not eliminate them. If running + multiple untrusted web applications, it is recommended that each web + application is deployed to a separate Tomcat instance (and ideally separate + hosts) to reduce the ability of a malicious web application impacting the + availability of other applications.

+ +

Tomcat is tested with the security manager enabled; but the majority of + Tomcat users do not run with a security manager, so Tomcat is not as well + user-tested in this configuration. There have been, and continue to be, + bugs reported that are triggered by running under a security manager.

+ +

The restrictions imposed by a security manager are likely to break most + applications if the security manager is enabled. The security manager should + not be used without extensive testing. Ideally, the use of a security + manager should be introduced at the start of the development cycle as it can + be time-consuming to track down and fix issues caused by enabling a security + manager for a mature application.

+ +

Enabling the security manager changes the defaults for the following + settings:

+
    +
  • The default value for the deployXML attribute of the + Host element is changed to false.
  • +
+

server.xml

+

General

+

The default server.xml contains a large number of comments, including + some example component definitions that are commented out. Removing these + comments makes it considerably easier to read and comprehend + server.xml.

+

If a component type is not listed, then there are no settings for that + type that directly impact security.

+
+ +

Server

+

Setting the port attribute to -1 disables + the shutdown port.

+

If the shutdown port is not disabled, a strong password should be + configured for shutdown.

+
+ +

Listeners

+

The APR Lifecycle Listener is not stable if compiled on Solaris using + gcc. If using the APR/native connector on Solaris, compile it with the + Sun Studio compiler.

+ +

The Security Listener should be enabled and configured as appropriate. +

+
+ +

Connectors

+

By default, an HTTP and an AJP connector are configured. Connectors + that will not be used should be removed from server.xml.

+ +

The address attribute may be used to control which IP + address the connector listens on for connections. By default, the + connector listens on all configured IP addresses.

+ +

The allowTrace attribute may be used to enable TRACE + requests which can be useful for debugging. Due to the way some browsers + handle the response from a TRACE request (which exposes the browser to an + XSS attack), support for TRACE requests is disabled by default.

+ +

The maxPostSize attribute controls the maximum size + of a POST request that will be parsed for parameters. The parameters are + cached for the duration of the request so this is limited to 2MB by + default to reduce exposure to a DOS attack.

+ +

The maxSavePostSize attribute controls the saving of + POST requests during FORM and CLIENT-CERT authentication. The parameters + are cached for the duration of the authentication (which may be many + minutes) so this is limited to 4KB by default to reduce exposure to a DOS + attack.

+ +

The maxParameterCount attribute controls the + maximum number of parameter and value pairs (GET plus POST) that can + be parsed and stored in the request. Excessive parameters are ignored. + If you want to reject such requests, configure a + FailedRequestFilter.

+ +

The xpoweredBy attribute controls whether or not the + X-Powered-By HTTP header is sent with each request. If sent, the value of + the header contains the Servlet and JSP specification versions, the full + Tomcat version (e.g. Apache Tomcat/8.0), the name of + the JVM vendor and + the version of the JVM. This header is disabled by default. This header + can provide useful information to both legitimate clients and attackers. +

+ +

The server attribute controls the value of the Server + HTTP header. The default value of this header for Tomcat 4.1.x to + 8.0.x is Apache-Coyote/1.1. This header can provide + limited information to both legitimate clients and attackers.

+ +

The SSLEnabled, scheme and + secure attributes may all be independently set. These are + normally used when Tomcat is located behind a reverse proxy and the proxy + is connecting to Tomcat via HTTP or HTTPS. They allow Tomcat to see the + SSL attributes of the connections between the client and the proxy rather + than the proxy and Tomcat. For example, the client may connect to the + proxy over HTTPS but the proxy connects to Tomcat using HTTP. If it is + necessary for Tomcat to be able to distinguish between secure and + non-secure connections received by a proxy, the proxy must use separate + connectors to pass secure and non-secure requests to Tomcat. If the + proxy uses AJP then the SSL attributes of the client connection are + passed via the AJP protocol and separate connectors are not needed.

+ +

The tomcatAuthentication and + tomcatAuthorization attributes are used with the + AJP connectors to determine if Tomcat should handle all authentication and + authorisation or if authentication should be delegated to the reverse + proxy (the authenticated user name is passed to Tomcat as part of the AJP + protocol) with the option for Tomcat to still perform authorization.

+ +

The allowUnsafeLegacyRenegotiation attribute provides + a workaround for + + CVE-2009-3555, a TLS man in the middle attack. This workaround applies + to the BIO connector. It is only necessary if the underlying SSL + implementation is vulnerable to CVE-2009-3555. For more information on the + current state of this vulnerability and the work-arounds available see the + Tomcat 8 security page.

+ +

The requiredSecret attribute in AJP connectors + configures shared secret between Tomcat and reverse proxy in front of + Tomcat. It is used to prevent unauthorized connections over AJP protocol.

+
+ +

Host

+

The host element controls deployment. Automatic deployment allows for + simpler management but also makes it easier for an attacker to deploy a + malicious application. Automatic deployment is controlled by the + autoDeploy and deployOnStartup + attributes. If both are false, only Contexts defined in + server.xml will be deployed and any changes will require a Tomcat restart. +

+ +

In a hosted environment where web applications may not be trusted, set + the deployXML attribute to false to ignore + any context.xml packaged with the web application that may try to assign + increased privileges to the web application. Note that if the security + manager is enabled that the deployXML attribute will + default to false.

+
+ +

Context

+

This applies to Context + elements in all places where they can be defined: + server.xml file, + default context.xml file, + per-host context.xml.default file, + web application context file in per-host configuration directory + or inside the web application.

+ +

The crossContext attribute controls if a context is + allowed to access the resources of another context. It is + false by default and should only be changed for trusted web + applications.

+ +

The privileged attribute controls if a context is + allowed to use container provided servlets like the Manager servlet. It is + false by default and should only be changed for trusted web + applications.

+ +

The allowLinking attribute of a nested + Resources element controls if a context + is allowed to use linked files. If enabled and the context is undeployed, + the links will be followed when deleting the context resources. Changing + this setting from the default of false on case insensitive + operating systems (this includes Windows) will disable a number of + security measures and allow, among other things, direct access to the + WEB-INF directory.

+ +

The sessionCookiePathUsesTrailingSlash can be used to + work around a bug in a number of browsers (Internet Explorer, Safari and + Edge) to prevent session cookies being exposed across applications when + applications share a common path prefix. However, enabling this option + can create problems for applications with Servlets mapped to + /*. It should also be noted the RFC6265 section 8.5 makes it + clear that different paths should not be considered sufficient to isolate + cookies from other applications.

+
+ +

Valves

+

It is strongly recommended that an AccessLogValve is configured. The + default Tomcat configuration includes an AccessLogValve. These are + normally configured per host but may also be configured per engine or per + context as required.

+ +

Any administrative application should be protected by a + RemoteAddrValve. (Note that this Valve is also available as a Filter.) + The allow attribute should be used to limit access to a + set of known trusted hosts.

+ +

The default ErrorReportValve includes the Tomcat version number in the + response sent to clients. To avoid this, custom error handling can be + configured within each web application. Alternatively, you can explicitly + configure an ErrorReportValve and set its + showServerInfo attribute to false. + Alternatively, the version number can be changed by creating the file + CATALINA_BASE/lib/org/apache/catalina/util/ServerInfo.properties with + content as follows:

+
server.info=Apache Tomcat/8.0.x
+

Modify the values as required. Note that this will also change the version + number reported in some of the management tools and may make it harder to + determine the real version installed. The CATALINA_HOME/bin/version.bat|sh + script will still report the version number.

+ +

The default ErrorReportValve can display stack traces and/or JSP + source code to clients when an error occurs. To avoid this, custom error + handling can be configured within each web application. Alternatively, you + can explicitly configure an ErrorReportValve + and set its showReport attribute to false.

+
+ +

Realms

+

The MemoryRealm is not intended for production use as any changes to + tomcat-users.xml require a restart of Tomcat to take effect.

+ +

The JDBCRealm is not recommended for production use as it is single + threaded for all authentication and authorization options. Use the + DataSourceRealm instead.

+ +

The UserDatabaseRealm is not intended for large-scale installations. It + is intended for small-scale, relatively static environments.

+ +

The JAASRealm is not widely used and therefore the code is not as + mature as the other realms. Additional testing is recommended before using + this realm.

+ +

By default, the realms do not implement any form of account lock-out. + This means that brute force attacks can be successful. To prevent a brute + force attack, the chosen realm should be wrapped in a LockOutRealm.

+
+ +

Manager

+

The manager component is used to generate session IDs.

+ +

The class used to generate random session IDs may be changed with + the randomClass attribute.

+ +

The length of the session ID may be changed with the + sessionIdLength attribute.

+
+ +

Cluster

+

The cluster implementation is written on the basis that a secure, + trusted network is used for all of the cluster related network traffic. It + is not safe to run a cluster on a insecure, untrusted network.

+
+

System Properties

+

Setting org.apache.catalina.connector.RECYCLE_FACADES + system property to true will cause a new facade object to be + created for each request. This reduces the chances of a bug in an + application exposing data from one request to another.

+ +

The + org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH and + org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH + system properties allow non-standard parsing of the request URI. Using + these options when behind a reverse proxy may enable an attacker to bypass + any security constraints enforced by the proxy.

+ +

The + org.apache.catalina.connector.Response.ENFORCE_ENCODING_IN_GET_WRITER + system property has security implications if disabled. Many user + agents, in breach of RFC2616, try to guess the character encoding of text + media types when the specification-mandated default of ISO-8859-1 should be + used. Some browsers will interpret as UTF-7 a response containing characters + that are safe for ISO-8859-1 but trigger an XSS vulnerability if interpreted + as UTF-7.

+

web.xml

+

This applies to the default conf/web.xml file and + WEB-INF/web.xml files in web applications if they define + the components mentioned here.

+ +

The DefaultServlet is configured + with readonly set to + true. Changing this to false allows clients to + delete or modify static resources on the server and to upload new + resources. This should not normally be changed without requiring + authentication.

+ +

The DefaultServlet is configured with listings set to + false. This isn't because allowing directory listings is + considered unsafe but because generating listings of directories with + thousands of files can consume significant CPU leading to a DOS attack. +

+ +

The DefaultServlet is configured with showServerInfo + set to true. When the directory listings is enabled the Tomcat + version number is included in the response sent to clients. To avoid this, + you can explicitly configure a DefaultServlet and set its + showServerInfo attribute to false. + Alternatively, the version number can be changed by creating the file + CATALINA_BASE/lib/org/apache/catalina/util/ServerInfo.properties with + content as follows:

+
server.info=Apache Tomcat/8.0.x
+

Modify the values as required. Note that this will also change the version + number reported in some of the management tools and may make it harder to + determine the real version installed. The CATALINA_HOME/bin/version.bat|sh + script will still report the version number. +

+ +

The CGI Servlet is disabled by default. If enabled, the debug + initialisation parameter should not be set to 10 or higher on a + production system because the debug page is not secure.

+ +

FailedRequestFilter + can be configured and used to reject requests that had errors during + request parameter parsing. Without the filter the default behaviour is + to ignore invalid or excessive parameters.

+ +

HttpHeaderSecurityFilter can be + used to add headers to responses to improve security. If clients access + Tomcat directly, then you probably want to enable this filter and all the + headers it sets unless your application is already setting them. If Tomcat + is accessed via a reverse proxy, then the configuration of this filter needs + to be co-ordinated with any headers that the reverse proxy sets.

+

General

+

BASIC and FORM authentication pass user names and passwords in clear + text. Web applications using these authentication mechanisms with clients + connecting over untrusted networks should use SSL.

+ +

The session cookie for a session with an authenticated user are nearly + as useful as the user's password to an attacker and in nearly all + circumstances should be afforded the same level of protection as the + password itself. This usually means authenticating over SSL and continuing + to use SSL until the session ends.

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/security-manager-howto.html b/test.dockerapp/tomcat/webapps/docs/security-manager-howto.html new file mode 100644 index 0000000..4518bc7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/security-manager-howto.html @@ -0,0 +1,525 @@ + +Apache Tomcat 8 (8.0.53) - Security Manager HOW-TO

Security Manager HOW-TO

Table of Contents

Background

+ +

The Java SecurityManager is what allows a web browser + to run an applet in its own sandbox to prevent untrusted code from + accessing files on the local file system, connecting to a host other + than the one the applet was loaded from, and so on. In the same way + the SecurityManager protects you from an untrusted applet running in + your browser, use of a SecurityManager while running Tomcat can protect + your server from trojan servlets, JSPs, JSP beans, and tag libraries. + Or even inadvertent mistakes.

+ +

Imagine if someone who is authorized to publish JSPs on your site + inadvertently included the following in their JSP:

+
<% System.exit(1); %>
+ +

Every time this JSP was executed by Tomcat, Tomcat would exit. + Using the Java SecurityManager is just one more line of defense a + system administrator can use to keep the server secure and reliable.

+ +

WARNING - A security audit + have been conducted using the Tomcat codebase. Most of the critical + package have been protected and a new security package protection mechanism + has been implemented. Still, make sure that you are satisfied with your SecurityManager + configuration before allowing untrusted users to publish web applications, + JSPs, servlets, beans, or tag libraries. However, running with a + SecurityManager is definitely better than running without one.

+ +

Permissions

+ +

Permission classes are used to define what Permissions a class loaded + by Tomcat will have. There are a number of Permission classes that are + a standard part of the JDK, and you can create your own Permission class + for use in your own web applications. Both techniques are used in + Tomcat.

+ + +

Standard Permissions

+ +

This is just a short summary of the standard system SecurityManager + Permission classes applicable to Tomcat. See + + http://docs.oracle.com/javase/7/docs/technotes/guides/security/ + for more information.

+ +
    +
  • java.util.PropertyPermission - Controls read/write + access to JVM properties such as java.home.
  • +
  • java.lang.RuntimePermission - Controls use of + some System/Runtime functions like exit() and + exec(). Also control the package access/definition.
  • +
  • java.io.FilePermission - Controls read/write/execute + access to files and directories.
  • +
  • java.net.SocketPermission - Controls use of + network sockets.
  • +
  • java.net.NetPermission - Controls use of + multicast network connections.
  • +
  • java.lang.reflect.ReflectPermission - Controls + use of reflection to do class introspection.
  • +
  • java.security.SecurityPermission - Controls access + to Security methods.
  • +
  • java.security.AllPermission - Allows access to all + permissions, just as if you were running Tomcat without a + SecurityManager.
  • +
+ +
+ +

Configuring Tomcat With A SecurityManager

+ +

Policy File Format

+ +

The security policies implemented by the Java SecurityManager are + configured in the $CATALINA_BASE/conf/catalina.policy file. + This file completely replaces the java.policy file present + in your JDK system directories. The catalina.policy file + can be edited by hand, or you can use the + policytool + application that comes with Java 1.2 or later.

+ +

Entries in the catalina.policy file use the standard + java.policy file format, as follows:

+
// Example policy file entry
+
+grant [signedBy <signer>,] [codeBase <code source>] {
+  permission  <class>  [<name> [, <action list>]];
+};
+ +

The signedBy and codeBase entries are + optional when granting permissions. Comment lines begin with "//" and + end at the end of the current line. The codeBase is in the + form of a URL, and for a file URL can use the ${java.home} + and ${catalina.home} properties (which are expanded out to + the directory paths defined for them by the JAVA_HOME, + CATALINA_HOME and CATALINA_BASE environment + variables).

+ +

The Default Policy File

+ +

The default $CATALINA_BASE/conf/catalina.policy file + looks like this:

+ + +
// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+
+// ============================================================================
+// catalina.policy - Security Policy Permissions for Tomcat
+//
+// This file contains a default set of security policies to be enforced (by the
+// JVM) when Catalina is executed with the "-security" option.  In addition
+// to the permissions granted here, the following additional permissions are
+// granted to each web application:
+//
+// * Read access to the web application's document root directory
+// * Read, write and delete access to the web application's working directory
+// ============================================================================
+
+
+// ========== SYSTEM CODE PERMISSIONS =========================================
+
+
+// These permissions apply to javac
+grant codeBase "file:${java.home}/lib/-" {
+        permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions
+grant codeBase "file:${java.home}/jre/lib/ext/-" {
+        permission java.security.AllPermission;
+};
+
+// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/../lib/-" {
+        permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions when
+// ${java.home} points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/lib/ext/-" {
+        permission java.security.AllPermission;
+};
+
+
+// ========== CATALINA CODE PERMISSIONS =======================================
+
+
+// These permissions apply to the daemon code
+grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
+        permission java.security.AllPermission;
+};
+
+// These permissions apply to the logging API
+// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home},
+// update this section accordingly.
+//  grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..}
+grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
+        permission java.io.FilePermission
+         "${java.home}${file.separator}lib${file.separator}logging.properties", "read";
+
+        permission java.io.FilePermission
+         "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
+        permission java.io.FilePermission
+         "${catalina.base}${file.separator}logs", "read, write";
+        permission java.io.FilePermission
+         "${catalina.base}${file.separator}logs${file.separator}*", "read, write, delete";
+
+        permission java.lang.RuntimePermission "shutdownHooks";
+        permission java.lang.RuntimePermission "getClassLoader";
+        permission java.lang.RuntimePermission "setContextClassLoader";
+
+        permission java.lang.management.ManagementPermission "monitor";
+
+        permission java.util.logging.LoggingPermission "control";
+
+        permission java.util.PropertyPermission "java.util.logging.config.class", "read";
+        permission java.util.PropertyPermission "java.util.logging.config.file", "read";
+        permission java.util.PropertyPermission "org.apache.juli.AsyncLoggerPollInterval", "read";
+        permission java.util.PropertyPermission "org.apache.juli.AsyncMaxRecordCount", "read";
+        permission java.util.PropertyPermission "org.apache.juli.AsyncOverflowDropType", "read";
+        permission java.util.PropertyPermission "org.apache.juli.ClassLoaderLogManager.debug", "read";
+        permission java.util.PropertyPermission "catalina.base", "read";
+
+        // Note: To enable per context logging configuration, permit read access to
+        // the appropriate file. Be sure that the logging configuration is
+        // secure before enabling such access.
+        // E.g. for the examples web application (uncomment and unwrap
+        // the following to be on a single line):
+        // permission java.io.FilePermission "${catalina.base}${file.separator}
+        //  webapps${file.separator}examples${file.separator}WEB-INF
+        //  ${file.separator}classes${file.separator}logging.properties", "read";
+};
+
+// These permissions apply to the server startup code
+grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
+        permission java.security.AllPermission;
+};
+
+// These permissions apply to the servlet API classes
+// and those that are shared across all class loaders
+// located in the "lib" directory
+grant codeBase "file:${catalina.home}/lib/-" {
+        permission java.security.AllPermission;
+};
+
+
+// If using a per instance lib directory, i.e. ${catalina.base}/lib,
+// then the following permission will need to be uncommented
+// grant codeBase "file:${catalina.base}/lib/-" {
+//         permission java.security.AllPermission;
+// };
+
+
+// ========== WEB APPLICATION PERMISSIONS =====================================
+
+
+// These permissions are granted by default to all web applications
+// In addition, a web application will be given a read FilePermission
+// for all files and directories in its document root.
+grant {
+    // Required for JNDI lookup of named JDBC DataSource's and
+    // javamail named MimePart DataSource used to send mail
+    permission java.util.PropertyPermission "java.home", "read";
+    permission java.util.PropertyPermission "java.naming.*", "read";
+    permission java.util.PropertyPermission "javax.sql.*", "read";
+
+    // OS Specific properties to allow read access
+    permission java.util.PropertyPermission "os.name", "read";
+    permission java.util.PropertyPermission "os.version", "read";
+    permission java.util.PropertyPermission "os.arch", "read";
+    permission java.util.PropertyPermission "file.separator", "read";
+    permission java.util.PropertyPermission "path.separator", "read";
+    permission java.util.PropertyPermission "line.separator", "read";
+
+    // JVM properties to allow read access
+    permission java.util.PropertyPermission "java.version", "read";
+    permission java.util.PropertyPermission "java.vendor", "read";
+    permission java.util.PropertyPermission "java.vendor.url", "read";
+    permission java.util.PropertyPermission "java.class.version", "read";
+    permission java.util.PropertyPermission "java.specification.version", "read";
+    permission java.util.PropertyPermission "java.specification.vendor", "read";
+    permission java.util.PropertyPermission "java.specification.name", "read";
+
+    permission java.util.PropertyPermission "java.vm.specification.version", "read";
+    permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+    permission java.util.PropertyPermission "java.vm.specification.name", "read";
+    permission java.util.PropertyPermission "java.vm.version", "read";
+    permission java.util.PropertyPermission "java.vm.vendor", "read";
+    permission java.util.PropertyPermission "java.vm.name", "read";
+
+    // Required for OpenJMX
+    permission java.lang.RuntimePermission "getAttribute";
+
+    // Allow read of JAXP compliant XML parser debug
+    permission java.util.PropertyPermission "jaxp.debug", "read";
+
+    // All JSPs need to be able to read this package
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat";
+
+    // Precompiled JSPs need access to these packages.
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
+    permission java.lang.RuntimePermission
+     "accessClassInPackage.org.apache.jasper.runtime.*";
+
+    // Precompiled JSPs need access to these system properties.
+
+    // The following two permissions are no longer needed since Tomcat 8.0.53
+    // They are here for historic reasons. There is no harm in keeping them.
+    permission java.util.PropertyPermission
+     "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
+    permission java.util.PropertyPermission
+     "org.apache.el.parser.COERCE_TO_ZERO", "read";
+
+    // The cookie code needs these.
+    permission java.util.PropertyPermission
+     "org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "read";
+    permission java.util.PropertyPermission
+     "org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING", "read";
+    permission java.util.PropertyPermission
+     "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR", "read";
+
+    // Applications using Comet need to be able to access this package
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.comet";
+
+    // Applications using WebSocket need to be able to access these packages
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket.server";
+};
+
+
+// The Manager application needs access to the following packages to support the
+// session display functionality. It also requires the custom Tomcat
+// DeployXmlPermission to enable the use of META-INF/context.xml
+// These settings support the following configurations:
+// - default CATALINA_HOME == CATALINA_BASE
+// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE
+// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME
+grant codeBase "file:${catalina.base}/webapps/manager/-" {
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util";
+    permission org.apache.catalina.security.DeployXmlPermission "manager";
+};
+grant codeBase "file:${catalina.home}/webapps/manager/-" {
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
+    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util";
+    permission org.apache.catalina.security.DeployXmlPermission "manager";
+};
+
+// The Host Manager application needs the custom Tomcat DeployXmlPermission to
+// enable the use of META-INF/context.xml
+// These settings support the following configurations:
+// - default CATALINA_HOME == CATALINA_BASE
+// - CATALINA_HOME != CATALINA_BASE, per instance Host Manager in CATALINA_BASE
+// - CATALINA_HOME != CATALINA_BASE, shared Host Manager in CATALINA_HOME
+grant codeBase "file:${catalina.base}/webapps/host-manager/-" {
+    permission org.apache.catalina.security.DeployXmlPermission "host-manager";
+};
+grant codeBase "file:${catalina.home}/webapps/host-manager/-" {
+    permission org.apache.catalina.security.DeployXmlPermission "host-manager";
+};
+
+
+// You can assign additional permissions to particular web applications by
+// adding additional "grant" entries here, based on the code base for that
+// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
+//
+// Different permissions can be granted to JSP pages, classes loaded from
+// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
+// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
+//
+// For instance, assume that the standard "examples" application
+// included a JDBC driver that needed to establish a network connection to the
+// corresponding database and used the scrape taglib to get the weather from
+// the NOAA web server.  You might create a "grant" entries like this:
+//
+// The permissions granted to the context root directory apply to JSP pages.
+// grant codeBase "file:${catalina.base}/webapps/examples/-" {
+//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+//
+// The permissions granted to the context WEB-INF/classes directory
+// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" {
+// };
+//
+// The permission granted to your JDBC driver
+// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
+//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// };
+// The permission granted to the scrape taglib
+// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
+//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+
+// To grant permissions for web applications using packed WAR files, use the
+// Tomcat specific WAR url scheme.
+//
+// The permissions granted to the entire web application
+// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/-" {
+// };
+//
+// The permissions granted to a specific JAR
+// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/WEB-INF/lib/foo.jar" {
+// };
+ +

Starting Tomcat With A SecurityManager

+ +

Once you have configured the catalina.policy file for use + with a SecurityManager, Tomcat can be started with a SecurityManager in + place by using the "-security" option:

+
$CATALINA_HOME/bin/catalina.sh start -security    (Unix)
+%CATALINA_HOME%\bin\catalina start -security      (Windows)
+ +

Permissions for packed WAR files

+ +

When using packed WAR files, it is necessary to use Tomcat's custom war + URL protocol to assign permissions to web application code.

+ +

To assign permissions to the entire web application the entry in the + policy file would look like this:

+ +
// Example policy file entry
+grant codeBase "war:file:${catalina.base}/webapps/examples.war*/-" {
+    ...
+};
+
+ +

To assign permissions to a single JAR within the web application the + entry in the policy file would look like this:

+ +
// Example policy file entry
+grant codeBase "war:file:${catalina.base}/webapps/examples.war*/WEB-INF/lib/foo.jar" {
+    ...
+};
+
+ +
+ +

Configuring Package Protection in Tomcat

+

Starting with Tomcat 5, it is now possible to configure which Tomcat + internal package are protected against package definition and access. See + + http://www.oracle.com/technetwork/java/seccodeguide-139067.html + for more information.

+ + +

WARNING: Be aware that removing the default package protection + could possibly open a security hole

+ +

The Default Properties File

+ +

The default $CATALINA_BASE/conf/catalina.properties file + looks like this:

+
#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageAccess unless the
+# corresponding RuntimePermission ("accessClassInPackage."+package) has
+# been granted.
+package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,
+org.apache.jasper.
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageDefinition unless the
+# corresponding RuntimePermission ("defineClassInPackage."+package) has
+# been granted.
+#
+# by default, no packages are restricted for definition, and none of
+# the class loaders supplied with the JDK call checkPackageDefinition.
+#
+package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,
+org.apache.tomcat.,org.apache.jasper.
+

Once you have configured the catalina.properties file for use + with a SecurityManager, remember to re-start Tomcat.

+

Troubleshooting

+ +

If your web application attempts to execute an operation that is + prohibited by lack of a required Permission, it will throw an + AccessControLException or a SecurityException + when the SecurityManager detects the violation. Debugging the permission + that is missing can be challenging, and one option is to turn on debug + output of all security decisions that are made during execution. This + is done by setting a system property before starting Tomcat. The easiest + way to do this is via the CATALINA_OPTS environment variable. + Execute this command:

+
export CATALINA_OPTS=-Djava.security.debug=all    (Unix)
+set CATALINA_OPTS=-Djava.security.debug=all       (Windows)
+ +

before starting Tomcat.

+ +

WARNING - This will generate many megabytes + of output! However, it can help you track down problems by searching + for the word "FAILED" and determining which permission was being checked + for. See the Java security documentation for more options that you can + specify here as well.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/servletapi/index.html b/test.dockerapp/tomcat/webapps/docs/servletapi/index.html new file mode 100644 index 0000000..1abf9c3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/servletapi/index.html @@ -0,0 +1,34 @@ + + + + + + API docs + + + + +The Servlet Javadoc is not installed by default. Download and install +the "fulldocs" package to get it. + +You can also access the javadoc online in the Tomcat + +documentation bundle. + + + diff --git a/test.dockerapp/tomcat/webapps/docs/setup.html b/test.dockerapp/tomcat/webapps/docs/setup.html new file mode 100644 index 0000000..3f162ef --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/setup.html @@ -0,0 +1,202 @@ + +Apache Tomcat 8 (8.0.53) - Tomcat Setup

Tomcat Setup

Table of Contents

Introduction

+

+ There are several ways to set up Tomcat for running on different + platforms. The main documentation for this is a file called + RUNNING.txt. We encourage you to refer to that + file if the information below does not answer some of your questions. +

+

Windows

+ +

+ Installing Tomcat on Windows can be done easily using the Windows + installer. Its interface and functionality is similar to other wizard + based installers, with only a few items of interest. +

+ + +
    +
  • Installation as a service: Tomcat will be + installed as a Windows service no matter what setting is selected. + Using the checkbox on the component page sets the service as "auto" + startup, so that Tomcat is automatically started when Windows + starts. For optimal security, the service should be run as a + separate user, with reduced permissions (see the Windows Services + administration tool and its documentation).
  • +
  • Java location: The installer will provide a default + JRE to use to run the service. The installer uses the registry to + determine the base path of a Java 7 or later JRE, including the JRE + installed as part of the full JDK. When running on a 64-bit + operating system, the installer will first look for a 64-bit JRE and + only look for a 32-bit JRE if a 64-bit JRE is not found. It is not + mandatory to use the default JRE detected by the installer. Any + installed Java 7 or later JRE (32-bit or 64-bit) may be used.
  • +
  • Tray icon: When Tomcat is run as a service, there + will not be any tray icon present when Tomcat is running. Note that + when choosing to run Tomcat at the end of installation, the tray + icon will be used even if Tomcat was installed as a service.
  • +
  • Defaults: The defaults used by the installer may be + overridden by use of the /C=<config file> command + line argument. The configuration file uses the format + name=value with each pair on a separate line. The names + of the available configuration options are: +
      +
    • JavaHome
    • +
    • TomcatPortShutdown
    • +
    • TomcatPortHttp
    • +
    • TomcatPortAjp
    • +
    • TomcatMenuEntriesEnable
    • +
    • TomcatShortcutAllUsers
    • +
    • TomcatServiceDefaultName
    • +
    • TomcatServiceName
    • +
    • TomcatServiceFileName
    • +
    • TomcatServiceManagerFileName
    • +
    • TomcatAdminEnable
    • +
    • TomcatAdminUsername
    • +
    • TomcatAdminPassword
    • +
    • TomcatAdminRoles
    • +
    + By using /C=... along with /S and + /D= it is possible to perform fully configured + unattended installs of Apache Tomact. +
  • +
  • Refer to the + Windows Service HOW-TO + for information on how to manage Tomcat as a Windows service. +
  • +
+ + +

The installer will create shortcuts allowing starting and configuring + Tomcat. It is important to note that the Tomcat administration web + application can only be used when Tomcat is running.

+ +

Unix daemon

+ +

Tomcat can be run as a daemon using the jsvc tool from the + commons-daemon project. Source tarballs for jsvc are included with the + Tomcat binaries, and need to be compiled. Building jsvc requires + a C ANSI compiler (such as GCC), GNU Autoconf, and a JDK.

+ +

Before running the script, the JAVA_HOME environment + variable should be set to the base path of the JDK. Alternately, when + calling the ./configure script, the path of the JDK may + be specified using the --with-java parameter, such as + ./configure --with-java=/usr/java.

+ +

Using the following commands should result in a compiled jsvc binary, + located in the $CATALINA_HOME/bin folder. This assumes + that GNU TAR is used, and that CATALINA_HOME is an + environment variable pointing to the base path of the Tomcat + installation.

+ +

Please note that you should use the GNU make (gmake) instead of + the native BSD make on FreeBSD systems.

+ +
cd $CATALINA_HOME/bin
+tar xvfz commons-daemon-native.tar.gz
+cd commons-daemon-1.1.x-native-src/unix
+./configure
+make
+cp jsvc ../..
+cd ../..
+ +

Tomcat can then be run as a daemon using the following commands.

+ +
CATALINA_BASE=$CATALINA_HOME
+cd $CATALINA_HOME
+./bin/jsvc \
+    -classpath $CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/tomcat-juli.jar \
+    -outfile $CATALINA_BASE/logs/catalina.out \
+    -errfile $CATALINA_BASE/logs/catalina.err \
+    -Dcatalina.home=$CATALINA_HOME \
+    -Dcatalina.base=$CATALINA_BASE \
+    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
+    -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \
+    org.apache.catalina.startup.Bootstrap
+ +

When runnong on Java 9 you will need to additionally specify the + following when starting jsvc to avoid warnings on shutdown.

+
...
+--add-opens=java.base/java.lang=ALL-UNNAMED \
+--add-opens=java.base/java.io=ALL-UNNAMED \
+--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED \
+...
+
+ +

You may also need to specify -jvm server if the JVM defaults + to using a server VM rather than a client VM. This has been observed on + OSX.

+ +

jsvc has other useful parameters, such as -user which + causes it to switch to another user after the daemon initialization is + complete. This allows, for example, running Tomcat as a non privileged + user while still being able to use privileged ports. Note that if you + use this option and start Tomcat as root, you'll need to disable the + org.apache.catalina.security.SecurityListener check that + prevents Tomcat starting when running as root.

+ +

jsvc --help will return the full jsvc usage + information. In particular, the -debug option is useful + to debug issues running jsvc.

+ +

The file $CATALINA_HOME/bin/daemon.sh can be used as a + template for starting Tomcat automatically at boot time from + /etc/init.d with jsvc.

+ +

Note that the Commons-Daemon JAR file must be on your runtime classpath + to run Tomcat in this manner. The Commons-Daemon JAR file is in the + Class-Path entry of the bootstrap.jar manifest, but if you get a + ClassNotFoundException or a NoClassDefFoundError for a Commons-Daemon + class, add the Commons-Daemon JAR to the -cp argument when launching + jsvc.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/ssi-howto.html b/test.dockerapp/tomcat/webapps/docs/ssi-howto.html new file mode 100644 index 0000000..a7f819c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/ssi-howto.html @@ -0,0 +1,398 @@ + +Apache Tomcat 8 (8.0.53) - SSI How To

SSI How To

Table of Contents

Introduction

+ +

SSI (Server Side Includes) are directives that are placed in HTML pages, +and evaluated on the server while the pages are being served. They let you +add dynamically generated content to an existing HTML page, without having +to serve the entire page via a CGI program, or other dynamic technology. +

+ +

Within Tomcat SSI support can be added when using Tomcat as your +HTTP server and you require SSI support. Typically this is done +during development when you don't want to run a web server like Apache.

+ +

Tomcat SSI support implements the same SSI directives as Apache. See the + +Apache Introduction to SSI for information on using SSI directives.

+ +

SSI support is available as a servlet and as a filter. You should use one +or the other to provide SSI support but not both.

+ +

Servlet based SSI support is implemented using the class +org.apache.catalina.ssi.SSIServlet. Traditionally, this servlet +is mapped to the URL pattern "*.shtml".

+ +

Filter based SSI support is implemented using the class +org.apache.catalina.ssi.SSIFilter. Traditionally, this filter +is mapped to the URL pattern "*.shtml", though it can be mapped to "*" as +it will selectively enable/disable SSI processing based on mime types. The +contentType init param allows you to apply SSI processing to JSP pages, +javascript, or any other content you wish.

+

By default SSI support is disabled in Tomcat.

+

Installation

+ +

CAUTION - SSI directives can be used to execute programs +external to the Tomcat JVM. If you are using the Java SecurityManager this +will bypass your security policy configuration in catalina.policy. +

+ +

To use the SSI servlet, remove the XML comments from around the SSI servlet +and servlet-mapping configuration in +$CATALINA_BASE/conf/web.xml.

+ +

To use the SSI filter, remove the XML comments from around the SSI filter +and filter-mapping configuration in +$CATALINA_BASE/conf/web.xml.

+ +

Only Contexts which are marked as privileged may use SSI features (see the +privileged property of the Context element).

+ +

Servlet Configuration

+ +

There are several servlet init parameters which can be used to +configure the behaviour of the SSI servlet.

+
    +
  • buffered - Should output from this servlet be buffered? +(0=false, 1=true) Default 0 (false).
  • +
  • debug - Debugging detail level for messages logged +by this servlet. Default 0.
  • +
  • expires - The number of seconds before a page with SSI +directives will expire. Default behaviour is for all SSI directives to be +evaluated for every request.
  • +
  • isVirtualWebappRelative - Should "virtual" SSI directive +paths be interpreted as relative to the context root, instead of the server +root? Default false.
  • +
  • inputEncoding - The encoding to be assumed for SSI +resources if one cannot be determined from the resource itself. Default is +the default platform encoding.
  • +
  • outputEncoding - The encoding to be used for the result +of the SSI processing. Default is UTF-8.
  • +
  • allowExec - Is the exec command enabled? Default is +false.
  • +
+ + +

Filter Configuration

+ +

There are several filter init parameters which can be used to +configure the behaviour of the SSI filter.

+
    +
  • contentType - A regex pattern that must be matched before +SSI processing is applied. When crafting your own pattern, don't forget that a +mime content type may be followed by an optional character set in the form +"mime/type; charset=set" that you must take into account. Default is +"text/x-server-parsed-html(;.*)?".
  • +
  • debug - Debugging detail level for messages logged +by this servlet. Default 0.
  • +
  • expires - The number of seconds before a page with SSI +directives will expire. Default behaviour is for all SSI directives to be +evaluated for every request.
  • +
  • isVirtualWebappRelative - Should "virtual" SSI directive +paths be interpreted as relative to the context root, instead of the server +root? Default false.
  • +
  • allowExec - Is the exec command enabled? Default is +false.
  • +
+ + +

Directives

+

Server Side Includes are invoked by embedding SSI directives in an HTML document + whose type will be processed by the SSI servlet. The directives take the form of an HTML + comment. The directive is replaced by the results of interpreting it before sending the + page to the client. The general form of a directive is:

+

<!--#directive [parm=value] -->

+

The directives are:

+
    +
  • +config - <!--#config timefmt="%B %Y" --> +Used to set the format of dates and other items processed by SSI +
  • +
  • +echo - <!--#echo var="VARIABLE_NAME" --> +will be replaced by the value of the variable. +
  • +
  • +exec - Used to run commands on the host system. +
  • +
  • +include - <!--#include virtual="file-name" --> +inserts the contents +
  • +
  • +flastmod - <!--#flastmod file="filename.shtml" --> +Returns the time that a file was lost modified. +
  • +
  • +fsize - <!--#fsize file="filename.shtml" --> +Returns the size of a file. +
  • +
  • +printenv - <!--#printenv --> +Returns the list of all the defined variables. +
  • +
  • +set - <!--#set var="foo" value="Bar" --> +is used to assign a value to a user-defined variable. +
  • +
  • +if elif endif else - Used to create conditional sections. For example: +
    <!--#config timefmt="%A" -->
    +<!--#if expr="$DATE_LOCAL = /Monday/" -->
    +<p>Meeting at 10:00 on Mondays</p>
    +<!--#elif expr="$DATE_LOCAL = /Friday/" -->
    +<p>Turn in your time card</p>
    +<!--#else -->
    +<p>Yoga class at noon.</p>
    +<!--#endif -->
    +
  • +
+

+See the + +Apache Introduction to SSI for more information on using SSI directives.

+

Variables

+

The SSI servlet currently implements the following variables: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable NameDescription
AUTH_TYPE + The type of authentication used for this user: BASIC, FORM, etc.
CONTENT_LENGTH + The length of the data (in bytes or the number of + characters) passed from a form.
CONTENT_TYPE + The MIME type of the query data, such as "text/html".
DATE_GMT +Current date and time in GMT
DATE_LOCAL +Current date and time in the local time zone
DOCUMENT_NAME +The current file
DOCUMENT_URI +Virtual path to the file
GATEWAY_INTERFACE + The revision of the Common Gateway Interface that the + server uses if enabled: "CGI/1.1".
HTTP_ACCEPT + A list of the MIME types that the client can accept.
HTTP_ACCEPT_ENCODING + A list of the compression types that the client can accept.
HTTP_ACCEPT_LANGUAGE + A list of the languages that the client can accept.
HTTP_CONNECTION + The way that the connection from the client is being managed: + "Close" or "Keep-Alive".
HTTP_HOST + The web site that the client requested.
HTTP_REFERER + The URL of the document that the client linked from.
HTTP_USER_AGENT + The browser the client is using to issue the request.
LAST_MODIFIED +Last modification date and time for current file
PATH_INFO + Extra path information passed to a servlet.
PATH_TRANSLATED + The translated version of the path given by the + variable PATH_INFO.
QUERY_STRING +The query string that follows the "?" in the URL. +
QUERY_STRING_UNESCAPED +Undecoded query string with all shell metacharacters escaped +with "\"
REMOTE_ADDR + The remote IP address of the user making the request.
REMOTE_HOST + The remote hostname of the user making the request.
REMOTE_PORT + The port number at remote IP address of the user making the request.
REMOTE_USER + The authenticated name of the user.
REQUEST_METHOD + The method with which the information request was + issued: "GET", "POST" etc.
REQUEST_URI + The web page originally requested by the client.
SCRIPT_FILENAME + The location of the current web page on the server.
SCRIPT_NAME + The name of the web page.
SERVER_ADDR + The server's IP address.
SERVER_NAME + The server's hostname or IP address.
SERVER_PORT + The port on which the server received the request.
SERVER_PROTOCOL + The protocol used by the server. E.g. "HTTP/1.1".
SERVER_SOFTWARE + The name and version of the server software that is + answering the client request.
UNIQUE_ID + A token used to identify the current session if one + has been established.
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/ssl-howto.html b/test.dockerapp/tomcat/webapps/docs/ssl-howto.html new file mode 100644 index 0000000..4948be2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/ssl-howto.html @@ -0,0 +1,664 @@ + +Apache Tomcat 8 (8.0.53) - SSL/TLS Configuration HOW-TO

SSL/TLS Configuration HOW-TO

Table of Contents

Quick Start

+ +

The description below uses the variable name $CATALINA_BASE to refer the + base directory against which most relative paths are resolved. If you have + not configured Tomcat for multiple instances by setting a CATALINA_BASE + directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, + the directory into which you have installed Tomcat.

+ +

To install and configure SSL/TLS support on Tomcat, you need to follow +these simple steps. For more information, read the rest of this HOW-TO.

+
    +
  1. Create a keystore file to store the server's private key and +self-signed certificate by executing the following command:

    +

    Windows:

    +
    "%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
    +

    Unix:

    +
    $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
    + +

    and specify a password value of "changeit".

  2. +
  3. Uncomment the "SSL HTTP/1.1 Connector" entry in + $CATALINA_BASE/conf/server.xml and modify as described in + the Configuration section below.

  4. + +
+ + +

Introduction to SSL/TLS

+ +

Transport Layer Security (TLS) and its predecessor, Secure Sockets Layer +(SSL), are technologies which allow web browsers and web servers to communicate +over a secured connection. This means that the data being sent is encrypted by +one side, transmitted, then decrypted by the other side before processing. +This is a two-way process, meaning that both the server AND the browser encrypt +all traffic before sending out data.

+ +

Another important aspect of the SSL/TLS protocol is Authentication. This means +that during your initial attempt to communicate with a web server over a secure +connection, that server will present your web browser with a set of +credentials, in the form of a "Certificate", as proof the site is who and what +it claims to be. In certain cases, the server may also request a Certificate +from your web browser, asking for proof that you are who you claim +to be. This is known as "Client Authentication," although in practice this is +used more for business-to-business (B2B) transactions than with individual +users. Most SSL-enabled web servers do not request Client Authentication.

+ +

SSL/TLS and Tomcat

+ +

It is important to note that configuring Tomcat to take advantage of +secure sockets is usually only necessary when running it as a stand-alone +web server. Details can be found in the +Security Considerations Document. +When running Tomcat primarily as a Servlet/JSP container behind +another web server, such as Apache or Microsoft IIS, it is usually necessary +to configure the primary web server to handle the SSL connections from users. +Typically, this server will negotiate all SSL-related functionality, then +pass on any requests destined for the Tomcat container only after decrypting +those requests. Likewise, Tomcat will return cleartext responses, that will +be encrypted before being returned to the user's browser. In this environment, +Tomcat knows that communications between the primary web server and the +client are taking place over a secure connection (because your application +needs to be able to ask about this), but it does not participate in the +encryption or decryption itself.

+ +

Certificates

+ +

In order to implement SSL, a web server must have an associated Certificate +for each external interface (IP address) that accepts secure connections. +The theory behind this design is that a server should provide some kind of +reasonable assurance that its owner is who you think it is, particularly +before receiving any sensitive information. While a broader explanation of +Certificates is beyond the scope of this document, think of a Certificate as a +"digital passport" for an Internet address. It states which organisation the +site is associated with, along with some basic contact information about the +site owner or administrator.

+ +

This certificate is cryptographically signed by its owner, and is +therefore extremely difficult for anyone else to forge. For the certificate to +work in the visitors browsers without warnings, it needs to be signed by a +trusted third party. These are called Certificate Authorities (CAs). To +obtain a signed certificate, you need to choose a CA and follow the instructions +your chosen CA provides to obtain your certificate. A range of CAs is available +including some that offer certificates at no cost.

+ +

Java provides a relatively simple command-line tool, called +keytool, which can easily create a "self-signed" Certificate. +Self-signed Certificates are simply user generated Certificates which have not +been signed by a well-known CA and are, therefore, not really guaranteed to be +authentic at all. While self-signed certificates can be useful for some testing +scenarios, they are not suitable for any form of production use.

+ +

General Tips on Running SSL

+ +

When securing a website with SSL it's important to make sure that all assets +that the site uses are served over SSL, so that an attacker can't bypass +the security by injecting malicious content in a javascript file or similar. To +further enhance the security of your website, you should evaluate to use the +HSTS header. It allows you to communicate to the browser that your site should +always be accessed over https.

+ +

Using name-based virtual hosts on a secured connection requires careful +configuration of the names specified in a single certificate or Tomcat 8.5 +onwards where Server Name Indication (SNI) support is available. SNI allows +multiple certificates with different names to be associated with a single TLS +connector.

+ +

Configuration

+ +

Prepare the Certificate Keystore

+ +

Tomcat currently operates only on JKS, PKCS11 or +PKCS12 format keystores. The JKS format +is Java's standard "Java KeyStore" format, and is the format created by the +keytool command-line utility. This tool is included in the JDK. +The PKCS12 format is an internet standard, and can be manipulated +via (among other things) OpenSSL and Microsoft's Key-Manager. +

+ +

Each entry in a keystore is identified by an alias string. Whilst many +keystore implementations treat aliases in a case insensitive manner, case +sensitive implementations are available. The PKCS11 specification, +for example, requires that aliases are case sensitive. To avoid issues related +to the case sensitivity of aliases, it is not recommended to use aliases that +differ only in case. +

+ +

To import an existing certificate into a JKS keystore, please read the +documentation (in your JDK documentation package) about keytool. +Note that OpenSSL often adds readable comments before the key, but +keytool does not support that. So if your certificate has +comments before the key data, remove them before importing the certificate with +keytool. +

+

To import an existing certificate signed by your own CA into a PKCS12 +keystore using OpenSSL you would execute a command like:

+
openssl pkcs12 -export -in mycert.crt -inkey mykey.key
+                       -out mycert.p12 -name tomcat -CAfile myCA.crt
+                       -caname root -chain
+

For more advanced cases, consult the +OpenSSL documentation.

+ +

To create a new JKS keystore from scratch, containing a single +self-signed Certificate, execute the following from a terminal command line:

+

Windows:

+
"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
+

Unix:

+
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
+ +

(The RSA algorithm should be preferred as a secure algorithm, and this +also ensures general compatibility with other servers and components.)

+ +

This command will create a new file, in the home directory of the user +under which you run it, named ".keystore". To specify a +different location or filename, add the -keystore parameter, +followed by the complete pathname to your keystore file, +to the keytool command shown above. You will also need to +reflect this new location in the server.xml configuration file, +as described later. For example:

+

Windows:

+
"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
+  -keystore \path\to\my\keystore
+

Unix:

+
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
+  -keystore /path/to/my/keystore
+ +

After executing this command, you will first be prompted for the keystore +password. The default password used by Tomcat is "changeit" +(all lower case), although you can specify a custom password if you like. +You will also need to specify the custom password in the +server.xml configuration file, as described later.

+ +

Next, you will be prompted for general information about this Certificate, +such as company, contact name, and so on. This information will be displayed +to users who attempt to access a secure page in your application, so make +sure that the information provided here matches what they will expect.

+ +

Finally, you will be prompted for the key password, which is the +password specifically for this Certificate (as opposed to any other +Certificates stored in the same keystore file). The keytool prompt +will tell you that pressing the ENTER key automatically uses the same password +for the key as the keystore. You are free to use the same password or to select +a custom one. If you select a different password to the keystore password, you +will also need to specify the custom password in the server.xml +configuration file.

+ +

If everything was successful, you now have a keystore file with a +Certificate that can be used by your server.

+ +
+ +

Edit the Tomcat Configuration File

+

+Tomcat can use two different implementations of SSL: +

+
    +
  • the JSSE implementation provided as part of the Java runtime (since 1.4)
  • +
  • the APR implementation, which uses the OpenSSL engine by default.
  • +
+

+The exact configuration details depend on which implementation is being used. +If you configured Connector by specifying generic +protocol="HTTP/1.1" then the implementation used by Tomcat is +chosen automatically. If the installation uses APR +- i.e. you have installed the Tomcat native library - +then it will use the APR SSL implementation, otherwise it will use the Java +JSSE implementation. +

+ +

+As configuration attributes for SSL support significantly differ between +APR vs. JSSE implementations, it is recommended to +avoid auto-selection of implementation. It is done by specifying a classname +in the protocol attribute of the Connector.

+ +

To define a Java (JSSE) connector, regardless of whether the APR library is +loaded or not, use one of the following:

+
<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO implementation -->
+<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
+           port="8443" .../>
+
+<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO2 implementation -->
+<Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
+           port="8443" .../>
+
+<!-- Define a HTTP/1.1 Connector on port 8443, JSSE BIO implementation -->
+<Connector protocol="org.apache.coyote.http11.Http11Protocol"
+           port="8443" .../>
+

Alternatively, to specify an APR connector (the APR library must be available) use:

+
<!-- Define a HTTP/1.1 Connector on port 8443, APR implementation -->
+<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
+           port="8443" .../>
+ + +

If you are using APR, you have the option of configuring an alternative engine to OpenSSL.

+
<Listener className="org.apache.catalina.core.AprLifecycleListener"
+          SSLEngine="someengine" SSLRandomSeed="somedevice" />
+

The default value is

+
<Listener className="org.apache.catalina.core.AprLifecycleListener"
+          SSLEngine="on" SSLRandomSeed="builtin" />
+

+So to use SSL under APR, make sure the SSLEngine attribute is set to something other than off. +The default value is on and if you specify another value, it has to be a valid engine name. +

+ +

+SSLRandomSeed allows to specify a source of entropy. Productive system needs a reliable source of entropy +but entropy may need a lot of time to be collected therefore test systems could use no blocking entropy +sources like "/dev/urandom" that will allow quicker starts of Tomcat. +

+ +

The final step is to configure the Connector in the +$CATALINA_BASE/conf/server.xml file, where +$CATALINA_BASE represents the base directory for the +Tomcat instance. An example <Connector> element +for an SSL connector is included in the default server.xml +file installed with Tomcat. To configure an SSL connector that uses JSSE, you +will need to remove the comments and edit it so it looks something like +this:

+
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
+<Connector
+           protocol="org.apache.coyote.http11.Http11NioProtocol"
+           port="8443" maxThreads="200"
+           scheme="https" secure="true" SSLEnabled="true"
+           keystoreFile="${user.home}/.keystore" keystorePass="changeit"
+           clientAuth="false" sslProtocol="TLS"/>
+

+ The APR connector uses different attributes for many SSL settings, + particularly keys and certificates. An example of an APR configuration is:

+
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
+<Connector
+           protocol="org.apache.coyote.http11.Http11AprProtocol"
+           port="8443" maxThreads="200"
+           scheme="https" secure="true" SSLEnabled="true"
+           SSLCertificateFile="/usr/local/ssl/server.crt"
+           SSLCertificateKeyFile="/usr/local/ssl/server.pem"
+           SSLVerifyClient="optional" SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"/>
+ + +

The configuration options and information on which attributes +are mandatory, are documented in the SSL Support section of the +HTTP connector configuration +reference. Make sure that you use the correct attributes for the connector you +are using. The BIO, NIO and NIO2 connectors use JSSE whereas the APR/native connector +uses APR.

+ +

The port attribute is the TCP/IP +port number on which Tomcat will listen for secure connections. You can +change this to any port number you wish (such as to the default port for +https communications, which is 443). However, special setup +(outside the scope of this document) is necessary to run Tomcat on port +numbers lower than 1024 on many operating systems.

+ +

If you change the port number here, you should also change the + value specified for the redirectPort attribute on the + non-SSL connector. This allows Tomcat to automatically redirect + users who attempt to access a page with a security constraint specifying + that SSL is required, as required by the Servlet Specification.

+ +

After completing these configuration changes, you must restart Tomcat as +you normally do, and you should be in business. You should be able to access +any web application supported by Tomcat via SSL. For example, try:

+
https://localhost:8443/
+

and you should see the usual Tomcat splash page (unless you have modified +the ROOT web application). If this does not work, the following section +contains some troubleshooting tips.

+ +
+ +

Installing a Certificate from a Certificate Authority

+

To obtain and install a Certificate from a Certificate Authority (like verisign.com, thawte.com +or trustcenter.de), read the previous section and then follow these instructions:

+ +

Create a local Certificate Signing Request (CSR)

+

In order to obtain a Certificate from the Certificate Authority of your choice +you have to create a so called Certificate Signing Request (CSR). That CSR will be used +by the Certificate Authority to create a Certificate that will identify your website +as "secure". To create a CSR follow these steps:

+
    +
  • Create a local self-signed Certificate (as described in the previous section): +
    keytool -genkey -alias tomcat -keyalg RSA
    +    -keystore <your_keystore_filename>
    + Note: In some cases you will have to enter the domain of your website (i.e. www.myside.org) + in the field "first- and lastname" in order to create a working Certificate. +
  • +
  • The CSR is then created with: +
    keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr
    +    -keystore <your_keystore_filename>
    +
  • +
+

Now you have a file called certreq.csr that you can submit to the Certificate Authority (look at the +documentation of the Certificate Authority website on how to do this). In return you get a Certificate.

+
+ +

Importing the Certificate

+

Now that you have your Certificate you can import it into you local keystore. +First of all you have to import a so called Chain Certificate or Root Certificate into your keystore. +After that you can proceed with importing your Certificate.

+ +
    +
  • Download a Chain Certificate from the Certificate Authority you obtained the Certificate from.
    + For Verisign.com commercial certificates go to: + http://www.verisign.com/support/install/intermediate.html
    + For Verisign.com trial certificates go to: + http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.html
    + For Trustcenter.de go to: + http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
    + For Thawte.com go to: + http://www.thawte.com/certs/trustmap.html
    +
  • +
  • Import the Chain Certificate into your keystore +
    keytool -import -alias root -keystore <your_keystore_filename>
    +    -trustcacerts -file <filename_of_the_chain_certificate>
    +
  • +
  • And finally import your new Certificate +
    keytool -import -alias tomcat -keystore <your_keystore_filename>
    +    -file <your_certificate_filename>
    +
  • +
+
+

Using OCSP Certificates

+

To use Online Certificate Status Protocol (OCSP) with Apache Tomcat, ensure + you have downloaded, installed, and configured the + + Tomcat Native Connector. +Furthermore, if you use the Windows platform, ensure you download the +ocsp-enabled connector.

+

To use OCSP, you require the following:

+ +
    +
  • OCSP-enabled certificates
  • +
  • Tomcat with SSL APR connector
  • +
  • Configured OCSP responder
  • +
+ +

Generating OCSP-Enabled Certificates

+

Apache Tomcat requires the OCSP-enabled certificate to have the OCSP + responder location encoded in the certificate. The basic OCSP-related + certificate authority settings in the openssl.cnf file could look + as follows:

+ +

+#... omitted for brevity
+
+[x509]
+x509_extensions = v3_issued
+
+[v3_issued]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+# The address of your responder
+authorityInfoAccess = OCSP;URI:http://127.0.0.1:8088
+keyUsage = critical,digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly
+basicConstraints=critical,CA:FALSE
+nsComment="Testing OCSP Certificate"
+
+#... omitted for brevity
+
+ +

The settings above encode the OCSP responder address + 127.0.0.1:8088 into the certificate. Note that for the following + steps, you must have openssl.cnf and other configuration of + your CA ready. To generate an OCSP-enabled certificate:

+ +
    +
  • + Create a private key: +
    openssl genrsa -aes256 -out ocsp-cert.key 4096
    +
  • +
  • + Create a signing request (CSR): +
    openssl req -config openssl.cnf -new -sha256 \
    +  -key ocsp-cert.key -out ocsp-cert.csr
  • +
  • + Sign the CSR: +
    openssl ca -openssl.cnf -extensions ocsp -days 375 -notext \
    +  -md sha256 -in ocsp-cert.csr -out ocsp-cert.crt
    +
  • +
  • + You may verify the certificate: +
    openssl x509 -noout -text -in ocsp-cert.crt
    +
  • +
+
+ +

Configuring OCSP Connector

+ +

To configure the OCSP connector, first verify that you are loading the Tomcat + APR library. Check the + Apache Portable Runtime (APR) based Native library for Tomcat +for more information about installation of APR. A basic OCSP-enabled connector + definition in the server.xml file looks as follows:

+

+<Connector port="8443"
+   protocol="org.apache.coyote.http11.Http11AprProtocol"
+   secure="true" scheme="https"
+   SSLEnabled="true" SSLCertificateFile="/path/to/ocsp-cert.crt"
+   SSLCertificateKeyFile="/path/to/ocsp-cert.key"
+   SSLCACertificateFile="/path/to/ca.pem"
+   SSLVerifyClient="require"
+   SSLVerifyDepth="10"
+   clientAuth="true"/>
+
+
+ +

Starting OCSP Responder

+

Apache Tomcat will query an OCSP responder server to get the certificate + status. When testing, an easy way to create an OCSP responder is by executing + the following: +

openssl ocsp -port 127.0.0.1:8088 \
+    -text -sha256 -index index.txt \
+    -CA ca-chain.cert.pem -rkey ocsp-cert.key \
+    -rsigner ocsp-cert.crt

+ +

Do note that when using OCSP, the responder encoded in the connector + certificate must be running. For further information, see + + OCSP documentation + . +

+ +
+ +

Troubleshooting

+ +

Here is a list of common problems that you may encounter when setting up +SSL communications, and what to do about them.

+ +
    + +
  • When Tomcat starts up, I get an exception like + "java.io.FileNotFoundException: {some-directory}/{some-file} not found". + +

    A likely explanation is that Tomcat cannot find the keystore file + where it is looking. By default, Tomcat expects the keystore file to + be named .keystore in the user home directory under which + Tomcat is running (which may or may not be the same as yours :-). If + the keystore file is anywhere else, you will need to add a + keystoreFile attribute to the <Connector> + element in the Tomcat + configuration file.

    +
  • + +
  • When Tomcat starts up, I get an exception like + "java.io.FileNotFoundException: Keystore was tampered with, or + password was incorrect". + +

    Assuming that someone has not actually tampered with + your keystore file, the most likely cause is that Tomcat is using + a different password than the one you used when you created the + keystore file. To fix this, you can either go back and + recreate the keystore + file, or you can add or update the keystorePass + attribute on the <Connector> element in the + Tomcat configuration + file. REMINDER - Passwords are case sensitive!

    +
  • + +
  • When Tomcat starts up, I get an exception like + "java.net.SocketException: SSL handshake error javax.net.ssl.SSLException: No + available certificate or key corresponds to the SSL cipher suites which are + enabled." + +

    A likely explanation is that Tomcat cannot find the alias for the server + key within the specified keystore. Check that the correct + keystoreFile and keyAlias are specified in the + <Connector> element in the + Tomcat configuration file. + REMINDER - keyAlias values may be case + sensitive!

    +
  • + +
  • My Java-based client aborts handshakes with exceptions such as + "java.lang.RuntimeException: Could not generate DH keypair" and + "java.security.InvalidAlgorithmParameterException: Prime size must be multiple + of 64, and can only range from 512 to 1024 (inclusive)" + +

    If you are using the APR/native connector, starting with version 1.1.34 + it will determine the strength of ephemeral DH keys from the key size of + your RSA certificate. For example a 2048 bit RSA key will result in + using a 2048 bit prime for the DH keys. Unfortunately Java 6 only supports + 768 bit and Java 7 only supports 1024 bit. So if your certificate has a + stronger key, old Java clients might produce such handshake failures. + As a mitigation you can either try to force them to use another cipher by + configuring an appropriate SSLCipherSuite and activate + SSLHonorCipherOrder, or embed weak DH params in your + certificate file. The latter approach is not recommended because it weakens + the SSL security (logjam attack).

    +
  • + +
+ +

If you are still having problems, a good source of information is the +TOMCAT-USER mailing list. You can find pointers to archives +of previous messages on this list, as well as subscription and unsubscription +information, at +https://tomcat.apache.org/lists.html.

+ +

Using the SSL for session tracking in your application

+

This is a new feature in the Servlet 3.0 specification. Because it uses the + SSL session ID associated with the physical client-server connection there + are some limitations. They are:

+
    +
  • Tomcat must have a connector with the attribute + isSecure set to true.
  • +
  • If SSL connections are managed by a proxy or a hardware accelerator + they must populate the SSL request headers (see the + SSLValve) so that + the SSL session ID is visible to Tomcat.
  • +
  • If Tomcat terminates the SSL connection, it will not be possible to use + session replication as the SSL session IDs will be different on each + node.
  • +
+ +

+ To enable SSL session tracking you need to use a context listener to set the + tracking mode for the context to be just SSL (if any other tracking mode is + enabled, it will be used in preference). It might look something like:

+
package org.apache.tomcat.example;
+
+import java.util.EnumSet;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.SessionTrackingMode;
+
+public class SessionTrackingModeListener implements ServletContextListener {
+
+    @Override
+    public void contextDestroyed(ServletContextEvent event) {
+        // Do nothing
+    }
+
+    @Override
+    public void contextInitialized(ServletContextEvent event) {
+        ServletContext context = event.getServletContext();
+        EnumSet<SessionTrackingMode> modes =
+            EnumSet.of(SessionTrackingMode.SSL);
+
+        context.setSessionTrackingModes(modes);
+    }
+
+}
+ +

Note: SSL session tracking is implemented for the BIO, NIO and NIO2 connectors. + It is not yet implemented for the APR connector.

+ +

Miscellaneous Tips and Bits

+ +

To access the SSL session ID from the request, use:

+ +
String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session_id");
+

+For additional discussion on this area, please see +Bugzilla. +

+ +

To terminate an SSL session, use:

+
// Standard HTTP session invalidation
+session.invalidate();
+
+// Invalidate the SSL Session
+org.apache.tomcat.util.net.SSLSessionManager mgr =
+    (org.apache.tomcat.util.net.SSLSessionManager)
+    request.getAttribute("javax.servlet.request.ssl_session_mgr");
+mgr.invalidateSession();
+
+// Close the connection since the SSL session will be active until the connection
+// is closed
+response.setHeader("Connection", "close");
+

+ Note that this code is Tomcat specific due to the use of the + SSLSessionManager class. This is currently only available for the BIO, NIO + and NIO2 connectors, not the APR/native connector. +

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/developers.html b/test.dockerapp/tomcat/webapps/docs/tribes/developers.html new file mode 100644 index 0000000..424ed10 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/developers.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Developers

Apache Tribes - Developers

Developers

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/faq.html b/test.dockerapp/tomcat/webapps/docs/tribes/faq.html new file mode 100644 index 0000000..e7e12f1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/faq.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Frequently Asked Questions

Apache Tribes - Frequently Asked Questions

Frequently Asked Questions

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/interceptors.html b/test.dockerapp/tomcat/webapps/docs/tribes/interceptors.html new file mode 100644 index 0000000..33dc89e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/interceptors.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Interceptors

Apache Tribes - Interceptors

Interceptors

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/introduction.html b/test.dockerapp/tomcat/webapps/docs/tribes/introduction.html new file mode 100644 index 0000000..bbb8c12 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/introduction.html @@ -0,0 +1,274 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Introduction

Apache Tribes - Introduction

Table of Contents

Quick Start

+ +

Apache Tribes is a group or peer-to-peer communication framework that enables you to easily connect + your remote objects to communicate with each other. +

+
    +
  • Import: org.apache.catalina.tribes.Channel
  • +
  • Import: org.apache.catalina.tribes.Member
  • +
  • Import: org.apache.catalina.tribes.MembershipListener
  • +
  • Import: org.apache.catalina.tribes.ChannelListener
  • +
  • Import: org.apache.catalina.tribes.group.GroupChannel
  • +
  • Create a class that implements: org.apache.catalina.tribes.ChannelListener
  • +
  • Create a class that implements: org.apache.catalina.tribes.MembershipListener
  • +
  • Simple class to demonstrate how to send a message: +
    //create a channel
    +Channel myChannel = new GroupChannel();
    +
    +//create my listeners
    +ChannelListener msgListener = new MyMessageListener();
    +MembershipListener mbrListener = new MyMemberListener();
    +
    +//attach the listeners to the channel
    +myChannel.addMembershipListener(mbrListener);
    +myChannel.addChannelListener(msgListener);
    +
    +//start the channel
    +myChannel.start(Channel.DEFAULT);
    +
    +//create a message to be sent, message must implement java.io.Serializable
    +//for performance reasons you probably want them to implement java.io.Externalizable
    +Serializable myMsg = new MyMessage();
    +
    +//retrieve my current members
    +Member[] group = myChannel.getMembers();
    +
    +//send the message
    +myChannel.send(group,myMsg,Channel.SEND_OPTIONS_DEFAULT);
    +
  • +
+

+ Simple yeah? There is a lot more to Tribes than we have shown, hopefully the docs will be able + to explain more to you. Remember, that we are always interested in suggestions, improvements, bug fixes + and anything that you think would help this project. +

+

What is Tribes

+

+ Tribes is a messaging framework with group communication abilities. Tribes allows you to send and receive + messages over a network, it also allows for dynamic discovery of other nodes in the network.
+ And that is the short story, it really is as simple as that. What makes Tribes useful and unique will be + described in the section below.
+

+

+ The Tribes module was started early 2006 and a small part of the code base comes from the clustering module + that has been existing since 2003 or 2004. + The current cluster implementation has several short comings and many workarounds were created due + to the complexity in group communication. Long story short, what should have been two modules a long time + ago, will be now. Tribes takes out the complexity of messaging from the replication module and becomes + a fully independent and highly flexible group communication module.
+

+

+ In Tomcat the old modules/cluster has now become modules/groupcom(Tribes) and + modules/ha (replication). This will allow development to proceed and let the developers + focus on the issues they are actually working on rather than getting boggled down in details of a module + they are not interested in. The understanding is that both communication and replication are complex enough, + and when trying to develop them in the same module, well you know, it becomes a cluster :)
+

+

+ Tribes allows for guaranteed messaging, and can be customized in many ways. Why is this important?
+ Well, you as a developer want to know that the messages you are sending are reaching their destination. + More than that, if a message doesn't reach its destination, the application on top of Tribes will be notified + that the message was never sent, and what node it failed. +

+ +

Why another messaging framework

+

+ I am a big fan of reusing code and would never dream of developing something if someone else has already + done it and it was available to me and the community I try to serve.
+ When I did my research to improve the clustering module I was constantly faced with a few obstacles:
+ 1. The framework wasn't flexible enough
+ 2. The framework was licensed in a way that neither I nor the community could use it
+ 3. Several features that I needed were missing
+ 4. Messaging was guaranteed, but no feedback was reported to me
+ 5. The semantics of my message delivery had to be configured before runtime
+ And the list continues... +

+

+ So I came up with Tribes, to address these issues and other issues that came along. + When designing Tribes I wanted to make sure I didn't lose any of the flexibility and + delivery semantics that the existing frameworks already delivered. The goal was to create a framework + that could do everything that the others already did, but to provide more flexibility for the application + developer. In the next section will give you the high level overview of what features tribes offers or will offer. +

+

Feature Overview

+

+ To give you an idea of the feature set I will list it out here. + Some of the features are not yet completed, if that is the case they are marked accordingly. +

+

+ Pluggable modules
+ Tribes is built using interfaces. Any of the modules or components that are part of Tribes can be swapped out + to customize your own Tribes implementation. +

+

+ Guaranteed Messaging
+ In the default implementation of Tribes uses TCP or UDP for messaging. TCP already has guaranteed message delivery + and flow control built in. I believe that the performance of Java TCP, will outperform an implementation of + Java/UDP/flow-control/message guarantee since the logic happens further down the stack. UDP messaging has been added in for + sending messages over UDP instead of TCP when desired. The same guarantee scenarios as described below are still available + over UDP, however, when a UDP message is lost, it's considered failed.
+ Tribes supports both non-blocking and blocking IO operations. The recommended setting is to use non blocking + as it promotes better parallelism when sending and receiving messages. The blocking implementation is available + for those platforms where NIO is still a trouble child. +

+

+ Different Guarantee Levels
+ There are three different levels of delivery guarantee when a message is sent. +

+
    +
  1. IO Based send guarantee. - fastest, least reliable
    + This means that Tribes considers the message transfer to be successful + if the message was sent to the socket send buffer and accepted.
    + On blocking IO, this would be socket.getOutputStream().write(msg)
    + On non blocking IO, this would be socketChannel.write(), and the buffer byte buffer gets emptied + followed by a socketChannel.read() to ensure the channel still open. + The read() has been added since write() will succeed if the connection has been "closed" + when using NIO. +
  2. +
  3. ACK based. - recommended, guaranteed delivery
    + When the message has been received on a remote node, an ACK is sent back to the sender, + indicating that the message was received successfully. +
  4. +
  5. SYNC_ACK based. - guaranteed delivery, guaranteed processed, slowest
    + When the message has been received on a remote node, the node will process + the message and if the message was processed successfully, an ACK is sent back to the sender + indicating that the message was received and processed successfully. + If the message was received, but processing it failed, an ACK_FAIL will be sent back + to the sender. This is a unique feature that adds an incredible amount value to the application + developer. Most frameworks here will tell you that the message was delivered, and the application + developer has to build in logic on whether the message was actually processed properly by the application + on the remote node. If configured, Tribes will throw an exception when it receives an ACK_FAIL + and associate that exception with the member that didn't process the message. +
  6. +
+

+ You can of course write even more sophisticated guarantee levels, and some of them will be mentioned later on + in the documentation. One mentionable level would be a 2-Phase-Commit, where the remote applications don't receive + the message until all nodes have received the message. Sort of like a all-or-nothing protocol. +

+

+ Per Message Delivery Attributes
+ Perhaps the feature that makes Tribes stand out from the crowd of group communication frameworks. + Tribes enables you to send to decide what delivery semantics a message transfer should have on a per + message basis. Meaning, that your messages are not delivered based on some static configuration + that remains fixed after the message framework has been started.
+ To give you an example of how powerful this feature is, I'll try to illustrate it with a simple example. + Imagine you need to send 10 different messages, you could send them the following way: +

+
Message_1 - asynchronous and fast, no guarantee required, fire and forget
+Message_2 - all-or-nothing, either all receivers get it, or none.
+Message_3 - encrypted and SYNC_ACK based
+Message_4 - asynchronous, SYNC_ACK and call back when the message is processed on the remote nodes
+Message_5 - totally ordered, this message should be received in the same order on all nodes that have been
+            send totally ordered
+Message_6 - asynchronous and totally ordered
+Message_7 - RPC message, send a message, wait for all remote nodes to reply before returning
+Message_8 - RPC message, wait for the first reply
+Message_9 - RPC message, asynchronous, don't wait for a reply, collect them via a callback
+Message_10- sent to a member that is not part of this group
+

+ As you can imagine by now, these are just examples. The number of different semantics you can apply on a + per-message-basis is almost limitless. Tribes allows you to set up to 28 different on a message + and then configure Tribes to what flag results in what action on the message.
+ Imagine a shared transactional cache, probably >90% are reads, and the dirty reads should be completely + unordered and delivered as fast as possible. But transactional writes on the other hand, have to + be ordered so that no cache gets corrupted. With tribes you would send the write messages totally ordered, + while the read messages you simple fire to achieve highest throughput.
+ There are probably better examples on how this powerful feature can be used, so use your imagination and + your experience to think of how this could benefit you in your application. +

+

+ Interceptor based message processing
+ Tribes uses a customizable interceptor stack to process messages that are sent and received.
+ So what, all frameworks have this!
+ Yes, but in Tribes interceptors can react to a message based on the per-message-attributes + that are sent runtime. Meaning, that if you add a encryption interceptor that encrypts message + you can decide if this interceptor will encrypt all messages, or only certain messages that are decided + by the applications running on top of Tribes.
+ This is how Tribes is able to send some messages totally ordered and others fire and forget style + like the example above.
+ The number of interceptors that are available will keep growing, and we would appreciate any contributions + that you might have. +

+

+ Threadless Interceptor stack + The interceptor don't require any separate threads to perform their message manipulation.
+ Messages that are sent will piggy back on the thread that is sending them all the way through transmission. + The exception is the MessageDispatchInterceptor that will queue up the message + and send it on a separate thread for asynchronous message delivery. + Messages received are controlled by a thread pool in the receiver component.
+ The channel object can send a heartbeat() through the interceptor stack to allow + for timeouts, cleanup and other events.
+ The MessageDispatchInterceptor is the only interceptor that is configured by default. +

+

+ Parallel Delivery
+ Tribes support parallel delivery of messages. Meaning that node_A could send three messages to node_B in + parallel. This feature becomes useful when sending messages with different delivery semantics. + Otherwise if Message_1 was sent totally ordered, Message_2 would have to wait for that message to complete.
+ Through NIO, Tribes is also able to send a message to several receivers at the same time on the same thread. +

+

+ Silent Member Messaging
+ With Tribes you are able to send messages to members that are not in your group. + So by default, you can already send messages over a wide area network, even though the dynamic discover + module today is limited to local area networks by using multicast for dynamic node discovery. + Of course, the membership component will be expanded to support WAN memberships in the future. + But this is very useful, when you want to hide members from the rest of the group and only communicate with them +

+

Where can I get Tribes

+

+ Tribes ships as a module with Tomcat, and is released as part of the Apache Tomcat release. +

+ + +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/membership.html b/test.dockerapp/tomcat/webapps/docs/tribes/membership.html new file mode 100644 index 0000000..bd555c6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/membership.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Membership

Apache Tribes - Membership

Membership

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/setup.html b/test.dockerapp/tomcat/webapps/docs/tribes/setup.html new file mode 100644 index 0000000..15efe6f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/setup.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Configuration

Apache Tribes - Configuration

Configuration Overview

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/status.html b/test.dockerapp/tomcat/webapps/docs/tribes/status.html new file mode 100644 index 0000000..6356d84 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/status.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Status

Apache Tribes - Status

Status

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/tribes/transport.html b/test.dockerapp/tomcat/webapps/docs/tribes/transport.html new file mode 100644 index 0000000..fa81057 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/tribes/transport.html @@ -0,0 +1,50 @@ + +Apache Tribes - The Tomcat Cluster Communication Module (8.0.53) - Apache Tribes - Transport

Apache Tribes - Transport

Transport

+

TODO

+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/virtual-hosting-howto.html b/test.dockerapp/tomcat/webapps/docs/virtual-hosting-howto.html new file mode 100644 index 0000000..2add0b2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/virtual-hosting-howto.html @@ -0,0 +1,140 @@ + +Apache Tomcat 8 (8.0.53) - Virtual Hosting and Tomcat

Virtual Hosting and Tomcat

Table of Contents

Assumptions

+

+ For the sake of this how-to, assume you have a development host with two + host names, ren and stimpy. Let's also assume + one instance of Tomcat running, so $CATALINA_HOME refers to + wherever it's installed, perhaps /usr/local/tomcat. +

+

+ Also, this how-to uses Unix-style path separators and commands; if you're + on Windows modify accordingly. +

+

server.xml

+

+ At the simplest, edit the Engine portion + of your server.xml file to look like this: +

+
<Engine name="Catalina" defaultHost="ren">
+    <Host name="ren"    appBase="renapps"/>
+    <Host name="stimpy" appBase="stimpyapps"/>
+</Engine>
+

+ Note that the directory structures under the appBase for each host should + not overlap each other. +

+

+ Consult the configuration documentation for other attributes of the + Engine and + Host elements. +

+

Webapps Directory

+

+ Create directories for each of the virtual hosts: +

+
mkdir $CATALINA_HOME/renapps
+mkdir $CATALINA_HOME/stimpyapps
+

Configuring Your Contexts

+

General

+

Contexts are normally located underneath the appBase directory. For + example, to deploy the foobar context as a war file in + the ren host, use + $CATALINA_HOME/renapps/foobar.war. Note that the + default or ROOT context for ren would be deployed as + $CATALINA_HOME/renapps/ROOT.war (WAR) or + $CATALINA_HOME/renapps/ROOT (directory). +

+

NOTE: The docBase for a context should never be + the same as the appBase for a host. +

+
+

context.xml - approach #1

+

+ Within your Context, create a META-INF directory and then + place your Context definition in it in a file named + context.xml. i.e. + $CATALINA_HOME/renapps/ROOT/META-INF/context.xml + This makes deployment easier, particularly if you're distributing a WAR + file. +

+
+

context.xml - approach #2

+

+ Create a structure under $CATALINA_HOME/conf/Catalina + corresponding to your virtual hosts, e.g.: +

+
mkdir $CATALINA_HOME/conf/Catalina/ren
+mkdir $CATALINA_HOME/conf/Catalina/stimpy
+

+ Note that the ending directory name "Catalina" represents the + name attribute of the + Engine element as shown above. +

+

+ Now, for your default webapps, add: +

+
$CATALINA_HOME/conf/Catalina/ren/ROOT.xml
+$CATALINA_HOME/conf/Catalina/stimpy/ROOT.xml
+

+ If you want to use the Tomcat manager webapp for each host, you'll also + need to add it here: +

+
cd $CATALINA_HOME/conf/Catalina
+cp localhost/manager.xml ren/
+cp localhost/manager.xml stimpy/
+
+

Further Information

+

+ Consult the configuration documentation for other attributes of the + Context element. +

+
+

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/web-socket-howto.html b/test.dockerapp/tomcat/webapps/docs/web-socket-howto.html new file mode 100644 index 0000000..d8dfa95 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/web-socket-howto.html @@ -0,0 +1,178 @@ + +Apache Tomcat 8 (8.0.53) - WebSocket How-To

WebSocket How-To

Table of Contents

Overview

+

Tomcat provides support for WebSocket as defined by + RFC 6455.

+

Application development

+

Tomcat implements the Java WebSocket 1.1 API defined by JSR-356.

+ +

There are several example applications that demonstrate how the WebSocket API + can be used. You will need to look at both the client side + HTML and the server side + code.

+

Production usage

+

Although the WebSocket implementation does work with any of the HTTP +connectors, it is not recommended to the WebSocket with the BIO HTTP connector +as the typical uses of WebSocket (large numbers of mostly idle connections) is +not a good fit for the HTTP BIO connector which requires that one thread is +allocated per connection regardless of whether or not the connection is idle. +

+ +

It has been reported (56304) that Linux can take large numbers of +minutes to report dropped connections. When using WebSocket with the BIO HTTP +connector this can result in threads blocking on writes for this period. This is +likely to be undesirable. The time taken for the connection to be reported as +dropped can be reduced by using the kernel network parameter +/proc/sys/net/ipv4/tcp_retries2. Alternatively, one of the other +HTTP connectors may be used as they utilise non-blocking IO enabling Tomcat to +implement its own timeout mechanism to handle these cases.

+

Tomcat WebSocket specific configuration

+ +

Tomcat provides a number of Tomcat specific configuration options for + WebSocket. It is anticipated that these will be absorbed into the WebSocket + specification over time.

+ +

The write timeout used when sending WebSocket messages in blocking mode + defaults to 20000 milliseconds (20 seconds). This may be changed by setting + the property org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT + in the user properties collection attached to the WebSocket session. The + value assigned to this property should be a Long and represents + the timeout to use in milliseconds. For an infinite timeout, use + -1.

+ +

If the application does not define a MessageHandler.Partial for + incoming binary messages, any incoming binary messages must be buffered so + the entire message can be delivered in a single call to the registered + MessageHandler.Whole for binary messages. The default buffer + size for binary messages is 8192 bytes. This may be changed for a web + application by setting the servlet context initialization parameter + org.apache.tomcat.websocket.binaryBufferSize to the desired + value in bytes.

+ +

If the application does not define a MessageHandler.Partial for + incoming text messages, any incoming text messages must be buffered so the + entire message can be delivered in a single call to the registered + MessageHandler.Whole for text messages. The default buffer size + for text messages is 8192 bytes. This may be changed for a web application by + setting the servlet context initialization parameter + org.apache.tomcat.websocket.textBufferSize to the desired value + in bytes.

+ +

The Java WebSocket specification 1.0 does not permit programmatic deployment + after the first endpoint has started a WebSocket handshake. By default, + Tomcat continues to permit additional programmatic deployment. This + behavior is controlled by the + org.apache.tomcat.websocket.noAddAfterHandshake servlet context + initialization parameter. The default may be changed by setting the + org.apache.tomcat.websocket.STRICT_SPEC_COMPLIANCE system + property to true but any explicit setting on the servlet context + will always take priority.

+ +

The Java WebSocket 1.0 specification requires that callbacks for + asynchronous writes are performed on a different thread to the thread that + initiated the write. Since the container thread pool is not exposed via the + Servlet API, the WebSocket implementation has to provide its own thread pool. + This thread pool is controlled by the following servlet context + initialization parameters:

+
    +
  • org.apache.tomcat.websocket.executorCoreSize: The core + size of the executor thread pool. If not set, the default of 0 (zero) + is used. Note that the maximum permitted size of the executor thread + pool is hard coded to Integer.MAX_VALUE which effectively + means it is unlimited.
  • +
  • org.apache.tomcat.websocket.executorKeepAliveTimeSeconds: + The maximum time an idle thread will remain in the executor thread pool + until it is terminated. If not specified, the default of 60 seconds is + used.
  • +
+ +

When using the WebSocket client to connect to server endpoints, the timeout + for IO operations while establishing the connection is controlled by the + userProperties of the provided + javax.websocket.ClientEndpointConfig. The property is + org.apache.tomcat.websocket.IO_TIMEOUT_MS and is the + timeout as a String in milliseconds. The default is 5000 (5 + seconds).

+ +

When using the WebSocket client to connect to secure server endpoints, the + client SSL configuration is controlled by the userProperties + of the provided javax.websocket.ClientEndpointConfig. The + following user properties are supported:

+
    +
  • org.apache.tomcat.websocket.SSL_CONTEXT
  • +
  • org.apache.tomcat.websocket.SSL_PROTOCOLS
  • +
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE
  • +
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD
  • +
+

The default truststore password is changeit.

+ +

If the org.apache.tomcat.websocket.SSL_CONTEXT property is + set then the org.apache.tomcat.websocket.SSL_TRUSTSTORE and + org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD properties + will be ignored.

+ +

For secure server end points, host name verification is enabled by default. + To bypass this verification (not recommended), it is necessary to provide a + custom SSLContext via the + org.apache.tomcat.websocket.SSL_CONTEXT user property. The + custom SSLContext must be configured with a custom + TrustManager that extends + javax.net.ssl.X509ExtendedTrustManager. The desired verification + (or lack of verification) can then be controlled by appropriate + implementations of the individual abstract methods.

+ +

When using the WebSocket client to connect to server endpoints, the number of + HTTP redirects that the client will follow is controlled by the + userProperties of the provided + javax.websocket.ClientEndpointConfig. The property is + org.apache.tomcat.websocket.MAX_REDIRECTIONS. The default value + is 20. Redirection support can be disabled by configuring a value of zero.

+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/websocketapi/index.html b/test.dockerapp/tomcat/webapps/docs/websocketapi/index.html new file mode 100644 index 0000000..199481d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/websocketapi/index.html @@ -0,0 +1,34 @@ + + + + + + API docs + + + + +The WebSocket Javadoc is not installed by default. Download and install +the "fulldocs" package to get it. + +You can also access the javadoc online in the Tomcat + +documentation bundle. + + + diff --git a/test.dockerapp/tomcat/webapps/docs/windows-auth-howto.html b/test.dockerapp/tomcat/webapps/docs/windows-auth-howto.html new file mode 100644 index 0000000..a0b59a6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/windows-auth-howto.html @@ -0,0 +1,340 @@ + +Apache Tomcat 8 (8.0.53) - Windows Authentication How-To

Windows Authentication How-To

Table of Contents

Overview

+

Integrated Windows authentication is most frequently used within intranet +environments since it requires that the server performing the authentication and +the user being authenticated are part of the same domain. For the user to be +authenticated automatically, the client machine used by the user must also be +part of the domain.

+

There are several options for implementing integrated Windows authentication +with Apache Tomcat. They are:

+
    +
  • Built-in Tomcat support.
  • +
  • Use a third party library such as Waffle.
  • +
  • Use a reverse proxy that supports Windows authentication to perform the +authentication step such as IIS or httpd.
  • +
+

The configuration of each of these options is discussed in the following +sections.

+

Built-in Tomcat support

+

Kerberos (the basis for integrated Windows authentication) requires careful +configuration. If the steps in this guide are followed exactly, then a working +configuration will result. It is important that the steps below are followed +exactly. There is very little scope for flexibility in the configuration. From +the testing to date it is known that:

+
    +
  • The host name used to access the Tomcat server must match the host name in +the SPN exactly else authentication will fail. A checksum error may be reported +in the debug logs in this case.
  • +
  • The client must be of the view that the server is part of the local trusted +intranet.
  • +
  • The SPN must be HTTP/<hostname> and it must be exactly the same in all +the places it is used.
  • +
  • The port number must not be included in the SPN.
  • +
  • No more than one SPN may be mapped to a domain user.
  • +
  • Tomcat must run as the domain account with which the SPN has been associated +or as domain admin. It is NOT recommended to run Tomcat under a +domain admin user.
  • +
  • The domain name (DEV.LOCAL) is not case sensitive when used in +the ktpass command, nor when used in jaas.conf
  • +
  • The domain must be specified when using the ktpass command
  • +
+

There are four components to the configuration of the built-in Tomcat +support for Windows authentication. The domain controller, the server hosting +Tomcat, the web application wishing to use Windows authentication and the client +machine. The following sections describe the configuration required for each +component.

+

The names of the three machines used in the configuration examples below are +win-dc01.dev.local (the domain controller), win-tc01.dev.local (the Tomcat +instance) and win-pc01.dev.local (client). All are members of the DEV.LOCAL +domain.

+

Note: In order to use the passwords in the steps below, the domain password +policy had to be relaxed. This is not recommended for production environments. +

+ +

Domain Controller

+

These steps assume that the server has already been configured to act as a + domain controller. Configuration of a Windows server as a domain controller is + outside the scope of this how-to. The steps to configure the domain controller + to enable Tomcat to support Windows authentication are as follows: +

+
    +
  • Create a domain user that will be mapped to the service name used by the + Tomcat server. In this how-to, this user is called tc01 and has a + password of tc01pass.
  • +
  • Map the service principal name (SPN) to the user account. SPNs take the + form + <service class>/<host>:<port>/<service name>. + The SPN used in this how-to is HTTP/win-tc01.dev.local. To + map the user to the SPN, run the following: +
    setspn -A HTTP/win-tc01.dev.local tc01
    +
  • +
  • Generate the keytab file that the Tomcat server will use to authenticate + itself to the domain controller. This file contains the Tomcat private key for + the service provider account and should be protected accordingly. To generate + the file, run the following command (all on a single line): +
    ktpass /out c:\tomcat.keytab /mapuser tc01@DEV.LOCAL
    +          /princ HTTP/win-tc01.dev.local@DEV.LOCAL
    +          /pass tc01pass /kvno 0
  • +
  • Create a domain user to be used on the client. In this how-to the domain + user is test with a password of testpass.
  • +
+

The above steps have been tested on a domain controller running Windows + Server 2008 R2 64-bit Standard using the Windows Server 2003 functional level + for both the forest and the domain. +

+
+ +

Tomcat instance (Windows server)

+

These steps assume that Tomcat and a Java 6 JDK/JRE have already been + installed and configured and that Tomcat is running as the tc01@DEV.LOCAL + user. The steps to configure the Tomcat instance for Windows authentication + are as follows: +

+
    +
  • Copy the tomcat.keytab file created on the domain controller + to $CATALINA_BASE/conf/tomcat.keytab.
  • +
  • Create the kerberos configuration file + $CATALINA_BASE/conf/krb5.ini. The file used in this how-to + contained:
    [libdefaults]
    +default_realm = DEV.LOCAL
    +default_keytab_name = FILE:c:\apache-tomcat-8.0.x\conf\tomcat.keytab
    +default_tkt_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
    +default_tgs_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
    +forwardable=true
    +
    +[realms]
    +DEV.LOCAL = {
    +        kdc = win-dc01.dev.local:88
    +}
    +
    +[domain_realm]
    +dev.local= DEV.LOCAL
    +.dev.local= DEV.LOCAL
    + The location of this file can be changed by setting the + java.security.krb5.conf system property.
  • +
  • Create the JAAS login configuration file + $CATALINA_BASE/conf/jaas.conf. The file used in this how-to + contained:
    com.sun.security.jgss.krb5.initiate {
    +    com.sun.security.auth.module.Krb5LoginModule required
    +    doNotPrompt=true
    +    principal="HTTP/win-tc01.dev.local@DEV.LOCAL"
    +    useKeyTab=true
    +    keyTab="c:/apache-tomcat-8.0.x/conf/tomcat.keytab"
    +    storeKey=true;
    +};
    +
    +com.sun.security.jgss.krb5.accept {
    +    com.sun.security.auth.module.Krb5LoginModule required
    +    doNotPrompt=true
    +    principal="HTTP/win-tc01.dev.local@DEV.LOCAL"
    +    useKeyTab=true
    +    keyTab="c:/apache-tomcat-8.0.x/conf/tomcat.keytab"
    +    storeKey=true;
    +};
    + The location of this file can be changed by setting the + java.security.auth.login.config system property. The LoginModule + used is a JVM specific one so ensure that the LoginModule specified matches + the JVM being used. The name of the login configuration must match the + value used by the authentication + valve.
  • +
+

The SPNEGO authenticator will work with any + Realm but if used with the JNDI Realm, by default the JNDI Realm will use + the user's delegated credentials to connect to the Active Directory. +

+

The above steps have been tested on a Tomcat server running Windows Server + 2008 R2 64-bit Standard with an Oracle 1.6.0_24 64-bit JDK.

+
+ +

Tomcat instance (Linux server)

+

This was tested with:

+
    +
  • Java 1.7.0, update 45, 64-bit
  • +
  • Ubuntu Server 12.04.3 LTS 64-bit
  • +
  • Tomcat 8.0.x (r1546570)
  • +
+

It should work with any Tomcat 8 release although it is recommended that + the latest stable release is used.

+

The configuration is the same as for Windows but with the following + changes:

+
    +
  • The Linux server does not have to be part of the Windows domain.
  • +
  • The path to the keytab file in krb5.ini and jaas.conf should be updated + to reflect the path to the keytab file on the Linux server using Linux + style file paths (e.g. /usr/local/tomcat/...).
  • +
+
+ +

Web application

+

The web application needs to be configured to the use Tomcat specific + authentication method of SPNEGO (rather than BASIC etc.) in + web.xml. As with the other authenticators, behaviour can be customised by + explicitly configuring the + authentication valve and setting attributes on the Valve.

+
+ +

Client

+

The client must be configured to use Kerberos authentication. For Internet + Explorer this means making sure that the Tomcat instance is in the "Local + intranet" security domain and that it is configured (Tools > Internet + Options > Advanced) with integrated Windows authentication enabled. Note that + this will not work if you use the same machine for the client + and the Tomcat instance as Internet Explorer will use the unsupported NTLM + protocol.

+
+ + + +

Third party libraries

+ +

Waffle

+

Full details of this solution can be found through the + Waffle web site. The + key features are:

+
    +
  • Drop-in solution
  • +
  • Simple configuration (no JAAS or Kerberos keytab configuration required) +
  • +
  • Uses a native library
  • +
+
+ +

Spring Security - Kerberos Extension

+

Full details of this solution can be found through the + Kerberos extension web site. The key features are:

+
    +
  • Extension to Spring Security
  • +
  • Requires a Kerberos keytab file to be generated
  • +
  • Pure Java solution
  • +
+
+ +

SPNEGO project at SourceForge

+

Full details of this solution can be found through the + project + site. The key features are:

+
    +
  • Uses Kerberos
  • +
  • Pure Java solution
  • +
+
+ +

Jespa

+

Full details of this solution can be found through the + project web siteThe key + features are:

+
    +
  • Pure Java solution
  • +
  • Advanced Active Directory integration
  • +
+
+

Reverse proxies

+ +

Microsoft IIS

+

There are three steps to configuring IIS to provide Windows authentication. + They are:

+
    +
  1. Configure IIS as a reverse proxy for Tomcat (see the + + IIS Web Server How-To).
  2. +
  3. Configure IIS to use Windows authentication
  4. +
  5. Configure Tomcat to use the authentication user information from IIS by + setting the tomcatAuthentication attribute on the + AJP connector to false. Alternatively, set the + tomcatAuthorization attribute to true to allow IIS to + authenticate, while Tomcat performs the authorization.
  6. +
+
+ +

Apache httpd

+

Apache httpd does not support Windows authentication out of the box but + there are a number of third-party modules that can be used. These include:

+
    +
  1. mod_auth_sspi for use on Windows platforms.
  2. +
  3. mod_auth_ntlm_winbind for non-Windows platforms. Known to + work with httpd 2.0.x on 32-bit platforms. Some users have reported stability + issues with both httpd 2.2.x builds and 64-bit Linux builds.
  4. +
+

There are three steps to configuring httpd to provide Windows + authentication. They are:

+
    +
  1. Configure httpd as a reverse proxy for Tomcat (see the + + Apache httpd Web Server How-To).
  2. +
  3. Configure httpd to use Windows authentication
  4. +
  5. Configure Tomcat to use the authentication user information from httpd by + setting the tomcatAuthentication attribute on the + AJP connector to false.
  6. +
+
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/docs/windows-service-howto.html b/test.dockerapp/tomcat/webapps/docs/windows-service-howto.html new file mode 100644 index 0000000..12d8b67 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/docs/windows-service-howto.html @@ -0,0 +1,483 @@ + +Apache Tomcat 8 (8.0.53) - Windows service HOW-TO

Windows service HOW-TO

Table of Contents

Tomcat service application

+

+ Tomcat8 is a service application for running Tomcat + 8 as a Windows service. +

+

Tomcat monitor application

+

+ Tomcat8w is a GUI application for monitoring and + configuring Tomcat services. +

+

The available command line options are:

+ + + + + + + + + + +
//ES//Edit service configurationThis is the default operation. It is called if the no option is + provided but the executable is renamed to servicenameW.exe
//MS//Monitor servicePut the icon in the system tray
+ +

Command line arguments

+

+ Each command line directive is in the form of //XX//ServiceName +

+

The available command line options are:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
//TS//Run the service as console applicationThis is the default operation. It is called if the no option is + provided. The ServiceName is the name of the executable without + exe suffix, meaning Tomcat8
//RS//Run the serviceCalled only from ServiceManager
//SS//Stop the service
//US//Update service parameters
//IS//Install service
//DS//Delete serviceStops the service if running
+ +

Command line parameters

+

+ Each command line parameter is prefixed with --. If the command line + parameter is prefixed with ++ then it's value will be appended to the + existing option. + If the environment variable with the same name as command line parameter but + prefixed with PR_ exists it will take precedence. + For example:

+
set PR_CLASSPATH=xx.jar
+ +

is equivalent to providing

+
--Classpath=xx.jar
+

as command line parameter.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterNameDefaultDescription
--DescriptionService name description (maximum 1024 characters)
--DisplayNameServiceNameService display name
--Installprocrun.exe //RS//ServiceNameInstall image
--StartupmanualService startup mode can be either auto or manual
--DependsOnList of services that this service depend on. Dependent services + are separated using either # or ; characters
--EnvironmentList of environment variables that will be provided to the service + in the form key=value. They are separated using either + # or ; characters. If you need to use either the # + or ; character within a value then the entire value must be + enclosed inside single quotes.
--UserUser account used for running executable. It is used only for + StartMode java or exe and enables running applications + as service under account without LogonAsService privilege.
--PasswordPassword for user account set by --User parameter
--JavaHomeJAVA_HOMESet a different JAVA_HOME than defined by JAVA_HOME environment + variable
--JvmautoUse either auto (i.e. find the JVM from the Windows registry) + or specify the full path to the jvm.dll. + You can use the environment variable expansion here.
--JvmOptions-XrsList of options in the form of -D or -X that will be + passed to the JVM. The options are separated using either + # or ; characters. If you need to embed either # or + ; characters, put them inside single quotes. (Not used in + exe mode.)
--JvmOptions9List of options in the form of -D or -X that will be + passed to the JVM when running on Java 9 or later. The options are + separated using either # or ; characters. If you need to + embed either # or ; characters, put them inside single + quotes. (Not used in exe mode.)
--ClasspathSet the Java classpath. (Not used in exe mode.)
--JvmMsInitial memory pool size in MB. (Not used in exe mode.)
--JvmMxMaximum memory pool size in MB. (Not used in exe mode.)
--JvmSsThread stack size in KB. (Not used in exe mode.)
--StartModeOne of jvm, Java or exe. The modes are: +
    +
  • jvm - start Java in-process. Depends on jvm.dll, see --Jvm.
  • +
  • Java - same as exe, but automatically uses the default Java + executable, i.e. %JAVA_HOME%\bin\java.exe. Make sure JAVA_HOME is set + correctly, or use --JavaHome to provide the correct location. + If neither is set, procrun will try to find the default JDK (not JRE) + from the Windows registry.
  • +
  • exe - run the image as a separate process
  • +
+
--StartImageExecutable that will be run. Only applies to exe mode.
--StartPathWorking path for the start image executable.
--StartClassMainClass that contains the startup method. Applies to the jvm and + Java modes. (Not used in exe mode.)
--StartMethodmainMethod name if differs then main
--StartParamsList of parameters that will be passed to either StartImage or + StartClass. Parameters are separated using either # or + ; character.
--StopModeOne of jvm, Java or exe. See --StartMode + for further details.
--StopImageExecutable that will be run on Stop service signal. Only applies to + exe mode.
--StopPathWorking path for the stop image executable. Does not apply to jvm + mode.
--StopClassMainClass that will be used on Stop service signal. Applies to the + jvm and Java modes.
--StopMethodmainMethod name if differs then main
--StopParamsList of parameters that will be passed to either StopImage or + StopClass. Parameters are separated using either # or + ; character.
--StopTimeoutNo TimeoutDefines the timeout in seconds that procrun waits for service to + exit gracefully.
--LogPath%SystemRoot%\System32\LogFiles\ApacheDefines the path for logging. Creates the directory if necessary.
--LogPrefixcommons-daemonDefines the service log filename prefix. The log file is created in the + LogPath directory with .YEAR-MONTH-DAY.log suffix
--LogLevelInfoDefines the logging level and can be either Error, + Info, Warn or Debug. (Case insensitive).
--StdOutputRedirected stdout filename. + If named auto then file is created inside LogPath with the + name service-stdout.YEAR-MONTH-DAY.log.
--StdErrorRedirected stderr filename. + If named auto then file is created inside LogPath with the + name service-stderr.YEAR-MONTH-DAY.log.
--PidFileDefines the file name for storing the running process id. Actual file is + created in the LogPath directory
+ +

Installing services

+

+The safest way to manually install the service is to use the provided +service.bat script. Administrator privileges are required to run this +script. If necessary, you can use the /user switch to specify +a user to use for the installation of the service. +

+

+NOTE: On Windows Vista or any later operating system with User +Account Control (UAC) enabled you will be asked for additional privileges +when 'Tomcat8.exe' is launched by the script.
+If you want to pass additional options to service installer as +PR_* environment variables, you have to either configure them +globally in OS, or launch the program that sets them with elevated privileges +(e.g. right-click on cmd.exe and select "Run as administrator"; on Windows 8 +(or later) or Windows Server 2012 (or later), you can open an elevated command +prompt for the current directory from the Explorer +by clicking on the "File" menu bar). See issue 56143 for details. +

+ +
Install the service named 'Tomcat8'
+C:\> service.bat install
+ +

There is a 2nd optional parameter that lets you specify the name of the +service, as displayed in Windows services.

+ +
Install the service named 'MyService'
+C:\> service.bat install MyService
+ +

+If using tomcat8.exe, you need to use the //IS// parameter.

+ +
Install the service named 'Tomcat8'
+C:\> tomcat8 //IS//Tomcat8 --DisplayName="Apache Tomcat 8" ^
+     --Install="C:\Program Files\Tomcat\bin\tomcat8.exe" --Jvm=auto ^
+     --StartMode=jvm --StopMode=jvm ^
+     --StartClass=org.apache.catalina.startup.Bootstrap --StartParams=start ^
+     --StopClass=org.apache.catalina.startup.Bootstrap --StopParams=stop
+ +

Updating services

+

+To update the service parameters, you need to use the //US// parameter. +

+ +
Update the service named 'Tomcat8'
+C:\> tomcat8 //US//Tomcat8 --Description="Apache Tomcat Server - https://tomcat.apache.org/ " ^
+     --Startup=auto --Classpath=%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\bin\bootstrap.jar
+ +

If you gave the service an optional name, you need to specify it like this: +

+ +
Update the service named 'MyService'
+C:\> tomcat8 //US//MyService --Description="Apache Tomcat Server - https://tomcat.apache.org/ " ^
+     --Startup=auto --Classpath=%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\bin\bootstrap.jar
+ +

Removing services

+

+To remove the service, you need to use the //DS// parameter.
+If the service is running it will be stopped and then deleted.

+ +
Remove the service named 'Tomcat8'
+C:\> tomcat8 //DS//Tomcat8
+ +

If you gave the service an optional name, you need to specify it like this: +

+ +
Remove the service named 'MyService'
+C:\> tomcat8 //DS//MyService
+ +

Debugging services

+

+To run the service in console mode, you need to use the //TS// parameter. +The service shutdown can be initiated by pressing CTRL+C or +CTRL+BREAK. +If you rename the tomcat8.exe to testservice.exe then you can just execute the +testservice.exe and this command mode will be executed by default.

+ +
Run the service named 'Tomcat8' in console mode
+C:\> tomcat8 //TS//Tomcat8 [additional arguments]
+Or simply execute:
+C:\> tomcat8
+ +

Multiple Instances

+

+Tomcat supports installation of multiple instances. You can have a single +installation of Tomcat with multiple instances running on different IP/port +combinations, or multiple Tomcat versions, each running one or more instances on +different IP/ports.

+

+Each instance folder will need the following structure: +

+
    +
  • conf
  • +
  • logs
  • +
  • temp
  • +
  • webapps
  • +
  • work
  • +
+

+At a minimum, conf should contain a copy of the following files from +CATALINA_HOME\conf\. Any files not copied and edited, will be picked up by +default from CATALINA_HOME\conf, i.e. CATALINA_BASE\conf files override defaults +from CATALINA_HOME\conf.

+
    +
  • server.xml
  • +
  • web.xml
  • +
+

+You must edit CATALINA_BASE\conf\server.xml to specify a unique IP/port for the +instance to listen on. Find the line that contains +<Connector port="8080" ... and add an address attribute and/or +update the port number so as to specify a unique IP/port combination.

+

+To install an instance, first set the CATALINA_HOME environment variable to the +name of the Tomcat installation directory. Then create a second environment +variable CATALINA_BASE and point this to the instance folder. Then run "service +install" command specifying a service name.

+ +
set CATALINA_HOME=c:\tomcat_8
+set CATALINA_BASE=c:\tomcat_8\instances\instance1
+service install instance1
+ +

+To modify the service settings, you can run tomcat8w //ES//instance1. +

+

+For additional instances, create additional instance folder, update the +CATALINA_BASE environment variable, and run the service install again.

+ +
set CATALINA_BASE=c:\tomcat_8\instances\instance2
+service install instance2
+ +

+ Comments +

Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

+ If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

+ The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +

\ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.class new file mode 100644 index 0000000000000000000000000000000000000000..01a6da9b327c24e055089c8a7557440e5d5e0071 GIT binary patch literal 4472 zcmbVQd3+Sr9sj;bcIRa?39uMsqtzi+41{DUm$2EOl7N65X%dcrRVTZ{?!fL&n4Jyb zuvKe|+QZ)3)@r4-*lKAN4GAc%M^nXG?SZ}RVei&I{e1fQv>)y7y_sE?WQBeTWZs+i ze#iHBPdN4F@sj`+;`I=^u%F{VEpEj7IXQI3DL1;W)-I$}z@qoZ|$?6C6)+oaFdUh_HN@<0*mVX%)|?c$Q&m-gGP@v)Od= zmYv(Qri+2CWvJ`4b9vXuxtonl!3>bE#2?0>^sHcLT({F0GNJ|7%0zq2yj^e-=88ft znK9cLf^jQnxyu=WF>NGe#Xe9qP?zT^Yq=tts>e;SyKs9Y)SfhAsOxo&#IE(mpp3YR?@`6c zWE@xVeHG8C*s0=q!nSfaVGg?Fz`Tl6DqbKLC+%)KPhfaFk@1r()GM=Zl_gWk)8c1M zn~0Kzby#1rG)M7MF|OeUc#*-kcu1r;Lqw2I$SY5tknux?^Cw1qMZwA>O-I8^cv-`b z@M8*mRKrii+fQ+t?9uQFen!!C&0&$L*^Gvt<1~3~Q{SrAr5b*L(;9w>Uy*;~v${5R z_VstK)CJx0xO|d7H2hj{1mkJbNK#eJjAu>P&=YCH$(wFRla$n?N0)0@i)+ZgejwUp zU{w4@!>htrH7*ZG0*^jSn!?(3LOhh)f*W$w`hZ`1O4)R2~zX|{4nbGWUjx4)8J$8-x$?*Gv2F&5QU$I}Z* zdw^WCkevEk{7%E~@drvu4X@#4YEDHj_$&3e_<%#Ce-wfLlOUn?DcYAVDl4X|__Kz; z;6)986``D}>;AQ@HF5tpasPJ_8WJRas67_76B?{JK52_vA2)ZMyat67F^xk zJ7{)@jMg(|E+xV`Ul)bd;VBVY--h}B8;1nxvow~o5?8YS_lz)1)wT}769J6Rwa zdeKKdkh8?=#d!_?z&}ed@S6d{MHTA1Y;I6oCe}B@rDx~y`!B=nbI}!>^K_}>%r1I1 zX#NB#v8~xyYKxQD`~g@-pruT=+i)l#)T{}mHyWblgKLi0*UOJ+?o=S0OeZF1J!zm% z1(6NihMQ(MueqYcpfNaT=4iOJRuDaz!|$v#F1TxZVWsF(x_e3*DhVMpHAXV&r7$_i zqp8@?<qRCD|$wY75(FiD7cV+|$r#dLcVuq&u zOc~+|-$tIOqBSAuIngC(W?s}h=j>BcQ1=$UCoXB;=DBQwac6!~1c*g`PS7g)5c!gJ zvgJ?@llWHmtzSozQzl1nhrbC(OBkj}63?AQqO}zqKRGcbpG=N0xlB0L`)Xupt035C zs^H0X%%X4EF8U%>(1?{-1%|8T+iH5JF-ZGrI-}7~&kghzrIpbdn0pND5lOm{o;fUg(5ZM&>}TsxQvKGB}f8gGocii z=9FYrEvap&B^ig1itvWo1u-o`ewZ7p6H801zQi7$Cy>;QqV)^`ZEq7qB|)S<5*o#P zpYA;+MYqt)Mr&Yy^ThHW6ewijv6oiB#nPN>p)474Gns<=%1yEusXfAWGm> zTu#pgsG;A6r(+RjU@aRZhkjVoZ|N(|vD`aQK12dM@hp!$25 zD)1Syf+n9#!Y#Od*jku02!}Y8SH?V79upSJs zek9mFB-tT4e-LT*5G*!|40{q;_AGMjHP}i$b}NffP~sR;wquVnfMLbLUgb9IQ|`om z

TakK;z=3EZSSgPWC8xJ8!s-Izjpwh*Gt&`4W1?YE+ibgn@^?dn+^8EnIL)Dq77 za4p_PMXTW+Tt~MdQTl#c5WDNi7i1Fc3=B|QyA99LJ5<(<+azj^tPAI6zuyiws@-W literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.java new file mode 100644 index 0000000..c62463b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/CookieExample.java @@ -0,0 +1,142 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +*/ + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ResourceBundle; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import util.CookieFilter; +import util.HTMLFilter; + +/** + * Example servlet showing request headers + * + * @author James Duncan Davidson + */ + +public class CookieExample extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private static final ResourceBundle RB = ResourceBundle.getBundle("LocalStrings"); + + @Override + public void doGet(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException + { + + String cookieName = request.getParameter("cookiename"); + String cookieValue = request.getParameter("cookievalue"); + Cookie aCookie = null; + if (cookieName != null && cookieValue != null) { + aCookie = new Cookie(cookieName, cookieValue); + aCookie.setPath(request.getContextPath() + "/"); + response.addCookie(aCookie); + } + + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + PrintWriter out = response.getWriter(); + out.println(""); + out.println(""); + out.println(""); + + String title = RB.getString("cookies.title"); + out.println("" + title + ""); + out.println(""); + out.println(""); + + // relative links + + // XXX + // making these absolute till we work out the + // addition of a PathInfo issue + + out.println(""); + out.println("\"view"); + out.println(""); + out.println("\"return\""); + + out.println("

" + title + "

"); + + Cookie[] cookies = request.getCookies(); + if ((cookies != null) && (cookies.length > 0)) { + HttpSession session = request.getSession(false); + String sessionId = null; + if (session != null) { + sessionId = session.getId(); + } + out.println(RB.getString("cookies.cookies") + "
"); + for (int i = 0; i < cookies.length; i++) { + Cookie cookie = cookies[i]; + String cName = cookie.getName(); + String cValue = cookie.getValue(); + out.print("Cookie Name: " + HTMLFilter.filter(cName) + "
"); + out.println(" Cookie Value: " + + HTMLFilter.filter(CookieFilter.filter(cName, cValue, sessionId)) + + "

"); + } + } else { + out.println(RB.getString("cookies.no-cookies")); + } + + if (aCookie != null) { + out.println("

"); + out.println(RB.getString("cookies.set") + "
"); + out.print(RB.getString("cookies.name") + " " + + HTMLFilter.filter(cookieName) + "
"); + out.print(RB.getString("cookies.value") + " " + + HTMLFilter.filter(cookieValue)); + } + + out.println("

"); + out.println(RB.getString("cookies.make-cookie") + "
"); + out.print("

"); + out.print(RB.getString("cookies.name") + " "); + out.println("
"); + out.print(RB.getString("cookies.value") + " "); + out.println("
"); + out.println("
"); + + + out.println(""); + out.println(""); + } + + @Override + public void doPost(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException + { + doGet(request, response); + } + +} + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/HelloWorldExample.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/HelloWorldExample.class new file mode 100644 index 0000000000000000000000000000000000000000..4b83e7cf40dec5de27897f3cbcba29f71ae22c24 GIT binary patch literal 2234 zcmbVOYf~Fl7=BL3WgE6F4VMD8HI2PMfoy53t+2rs2nC9OTm>(6lN^$*o85GC0_ph8 zZ+`VpIO7Lr{9r0N;}7shIlgC4f~jGOV`g&RJ?FgF=e_Ly`PXlM0Jx7=aa_ko8XkA! z31;J%!@P!UHx}?z!=j{1a#_~!ERGd?tYKBdnuc}B`bi8Mar8*}O-Z*jY)iVMVOPVa z8um2oYxqpV=Ni7y@TG?58or9biXq3)Q{}#GIXm31+Mc_;G|#}68P3mnZdF*W*s+`% zkC2=4#~7lf?b>37p=)Gxhao)Y6*$Ai72D;jwQ`R8TUO4Ylf;UbC$$zSr+xDO?9xrU)Fe4 zOrObCtxynrTKXCDl@P=2GsTp42F>S61H;)aHEl73d_r|NFk;k%?HC)p>ec)_pRKut zAkZ$aMq&0V7TYt{ecKhgzAd;fVGy=Z07?`L$8w9trXZFgUBc&L!y=JoltxvjnRY*Mn$n86yuOC7$Hh?*sC6{tW4%`z8OGGDU%Di@hlpedC! z=&GkA^M54spAN#+Q3YXg`QIVW)@-N1eafF1@XhF`;gC{e8m;{i>hjuXS{*QRUg1?T zSIm2k=Vww!CBijDHm{mivgGrFOe&ow<`etUeR;oc+T~)h>gNLnyKEJC)yPwIr;GMM zDp}%ou_QA09wd+Kf+)!c%dv}Y#+T>Goad9DnY(mIp&r`&C@E!AGp1n$ShN|p-2$(t zTXy$Ov+HwF^WFbpSqZkxhRxC>S&tApk`hW19Q72Wjp0&9#V}lZd;d`b2YI5>U0ORS z$PTe)x3)3de7oLeUsE9#xd=*?D!OlEw5^xaDK)}i;K3>VrKDA_F+5g{`$iXas%y8< z(XF@6a=JAmE>M-z)D+wmTdykQdjBcL~@;h81}yAT2#tPV`)D*K"); + out.println(""); + out.println(""); + + String title = rb.getString("helloworld.title"); + + out.println("" + title + ""); + out.println(""); + out.println(""); + + // note that all links are created to be relative. this + // ensures that we can move the web application that this + // servlet belongs to to a different place in the url + // tree and not have any harmful side effects. + + // XXX + // making these absolute till we work out the + // addition of a PathInfo issue + + out.println(""); + out.println("\"view"); + out.println(""); + out.println("\"return\""); + out.println("

" + title + "

"); + out.println(""); + out.println(""); + } +} + + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings.properties b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings.properties new file mode 100644 index 0000000..a3f97e5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings.properties @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +# Default localized resources for example servlets +# This locale is en_US + +helloworld.title=Hello World! + +requestinfo.title=Request Information Example +requestinfo.label.method=Method: +requestinfo.label.requesturi=Request URI: +requestinfo.label.protocol=Protocol: +requestinfo.label.pathinfo=Path Info: +requestinfo.label.remoteaddr=Remote Address: + +requestheader.title=Request Header Example + +requestparams.title=Request Parameters Example +requestparams.params-in-req=Parameters in this request: +requestparams.no-params=No Parameters, Please enter some +requestparams.firstname=First Name: +requestparams.lastname=Last Name: + +cookies.title=Cookies Example +cookies.cookies=Your browser is sending the following cookies: +cookies.no-cookies=Your browser isn't sending any cookies +cookies.make-cookie=Create a cookie to send to your browser +cookies.name=Name: +cookies.value=Value: +cookies.set=You just sent the following cookie to your browser: + +sessions.title=Sessions Example +sessions.id=Session ID: +sessions.created=Created: +sessions.lastaccessed=Last Accessed: +sessions.data=The following data is in your session: +sessions.adddata=Add data to your session +sessions.dataname=Name of Session Attribute: +sessions.datavalue=Value of Session Attribute: diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_en.properties b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_en.properties new file mode 100644 index 0000000..a3f97e5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_en.properties @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +# Default localized resources for example servlets +# This locale is en_US + +helloworld.title=Hello World! + +requestinfo.title=Request Information Example +requestinfo.label.method=Method: +requestinfo.label.requesturi=Request URI: +requestinfo.label.protocol=Protocol: +requestinfo.label.pathinfo=Path Info: +requestinfo.label.remoteaddr=Remote Address: + +requestheader.title=Request Header Example + +requestparams.title=Request Parameters Example +requestparams.params-in-req=Parameters in this request: +requestparams.no-params=No Parameters, Please enter some +requestparams.firstname=First Name: +requestparams.lastname=Last Name: + +cookies.title=Cookies Example +cookies.cookies=Your browser is sending the following cookies: +cookies.no-cookies=Your browser isn't sending any cookies +cookies.make-cookie=Create a cookie to send to your browser +cookies.name=Name: +cookies.value=Value: +cookies.set=You just sent the following cookie to your browser: + +sessions.title=Sessions Example +sessions.id=Session ID: +sessions.created=Created: +sessions.lastaccessed=Last Accessed: +sessions.data=The following data is in your session: +sessions.adddata=Add data to your session +sessions.dataname=Name of Session Attribute: +sessions.datavalue=Value of Session Attribute: diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_es.properties b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_es.properties new file mode 100644 index 0000000..fbb5769 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_es.properties @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +helloworld.title = Hola Mundo\! +requestinfo.title = Ejemplo de Informacion de Requerimiento\: +requestinfo.label.method = M\u00E9todo\: +requestinfo.label.requesturi = URI de Requerimiento\: +requestinfo.label.protocol = Protocolo\: +requestinfo.label.pathinfo = Info de Ruta\: +requestinfo.label.remoteaddr = Direccion Remota\: +requestheader.title = Ejemplo de Cabecera de Requerimiento\: +requestparams.title = Ejemplo de par\u00E1metros de Requerimiento\: +requestparams.params-in-req = Par\u00E1metros en este Request\: +requestparams.no-params = No hay p\u00E1rametro. Por favor, usa alguno +requestparams.firstname = Nombre\: +requestparams.lastname = Apellidos\: +cookies.title = Ejemplo de Cookies +cookies.cookies = Tu navegador est\u00E1 enviando los siguientes cookies\: +cookies.no-cookies = Tu navegador no est\u00E1 enviando cookies +cookies.make-cookie = Crea un cookie para enviarlo a tu navegador +cookies.name = Nombre\: +cookies.value = Valor\: +cookies.set = Acabas de enviar a tu navegador estos cookies\: +sessions.title = Ejemplo de Sesiones +sessions.id = ID de Sesi\u00F3n\: +sessions.created = Creado\: +sessions.lastaccessed = Ultimo Acceso\: +sessions.data = Lo siguientes datos est\u00E1n en tu sesi\u00F3n\: +sessions.adddata = A\u00F1ade datos a tu sesi\u00F3n\: +sessions.dataname = Nombre del atributo de sesi\u00F3n\: +sessions.datavalue = Valor del atributo de sesi\u00F3n\: diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_fr.properties b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_fr.properties new file mode 100644 index 0000000..b6b9a3f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_fr.properties @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +# Default localized resources for example servlets +# This locale is fr_FR + +helloworld.title=Salut le Monde! + +requestinfo.title=Exemple d''information sur la requ\u00eate +requestinfo.label.method=M\u00e9thode: +requestinfo.label.requesturi=URI de requ\u00eate: +requestinfo.label.protocol=Protocole: +requestinfo.label.pathinfo=Info de chemin: +requestinfo.label.remoteaddr=Adresse distante: + +requestheader.title=Exemple d''information sur les ent\u00eate de requ\u00eate + +requestparams.title=Exemple de requ\u00eate avec param\u00eatres +requestparams.params-in-req=Param\u00eatres dans la requ\u00eate: +requestparams.no-params=Pas de param\u00eatre, merci dans saisir quelqu'uns +requestparams.firstname=Pr\u00e9nom: +requestparams.lastname=Nom: + +cookies.title=Exemple d''utilisation de Cookies +cookies.cookies=Votre navigateur retourne les cookies suivant: +cookies.no-cookies=Votre navigateur ne retourne aucun cookie +cookies.make-cookie=Cr\u00e9ation d''un cookie \u00e0 retourner \u00e0 votre navigateur +cookies.name=Nom: +cookies.value=Valeur: +cookies.set=Vous venez d''envoyer le cookie suivant \u00e0 votre navigateur: + +sessions.title=Exemple de Sessions +sessions.id=ID de Session: +sessions.created=Cr\u00e9e le: +sessions.lastaccessed=Dernier acc\u00e8s: +sessions.data=Les donn\u00e9es existantes dans votre session: +sessions.adddata=Ajouter des donn\u00e9es \u00e0 votre session +sessions.dataname=Nom de l''Attribut de Session: +sessions.datavalue=Valeur de l''Attribut de Session: diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_pt.properties b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_pt.properties new file mode 100644 index 0000000..919643e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/LocalStrings_pt.properties @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +# Default localized resources for example servlets +# This locale is pt_PT + +helloworld.title=Ola Mundo! + +requestinfo.title=Exemplo da Informacao do Pedido +requestinfo.label.method=Metodo: +requestinfo.label.requesturi=URI do Pedido: +requestinfo.label.protocol=Protocolo: +requestinfo.label.pathinfo=Informacao do Caminho: +requestinfo.label.remoteaddr=Endereco Remoto: + +requestheader.title=Exemplo da Cebeceira do Pedido + +requestparams.title=Examplo de Parametros do Pedido +requestparams.params-in-req=Parametros neste pedido: +requestparams.no-params=Sem Parametros, Por favor entre alguns +requestparams.firstname=Primeiro Nome: +requestparams.lastname=Apelido: + +cookies.title=CExamplo de Cookies +cookies.cookies=O se browser esta a enviar os seguintes cookies: +cookies.no-cookies=O seu browser nao esta a enviar nenhuns cookies +cookies.make-cookie=Crie um cookie para enviar para o seu browser +cookies.name=Nome: +cookies.value=Valor: +cookies.set=Acabou de enviar o seguinte cookie para o seu browser: + +sessions.title=Examplo de sessoes +sessions.id=Identificador da Sessao: +sessions.created=Criada: +sessions.lastaccessed=Ultima vez acedida: +sessions.data=Os seguintes dados fazem parte da sua sessao: +sessions.adddata=Adicione data a sua sessao +sessions.dataname=Nome do atributo da sessao: +sessions.datavalue=Valor do atributo da Sessao: diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.class new file mode 100644 index 0000000000000000000000000000000000000000..d97595c1bd9874f4de031a893f9076d0611bec63 GIT binary patch literal 3617 zcmbVO?Ry+m7608NyED6)w&_yZZlPt93Qe0Pi!EYJHxZjAO)yPDlBT2-VX`~fopyI- znVoG?Q4v%WUr<2B`c~htz6(Xu1{CoH^znnA{1g1j^YFzFd@26!o!RZCO{|ZbC+FTd zbM866^K#Fbzh8OfH30kZw>b78t0UJ63-dbiaxF+=>o^t1X%uyobT~1*7p{(S9FM@$ zP>Ex`Jm<@`s^g4Y7j!J@IIH8MIv&;WF&!V*@d+J|>G)(T9>)`{_!K@Z$!9b?DLJ3j z@wqsj!sm5-A%-vFOL3&|w2m*!^(#{1nN~cD=i>M(zNX{rI-ZXc$TxJHlR&jqq>;+u{?V-~AcgdWSE5NMh_B(QDtlzGNXSADyf zp0p}%)yrCks!pzG9TbRWY{&Nd1)4i|&j_>(xH(H;!>H|8W7X1}A_+cJdU67Zmm} zvqWcGg9jB&8u9|~1a_@$NcmNBLqPYe0II-^eGi>t4%{lEb#s8vcGD9C=O6cM-|`4C z;@iGVh2Z~|Kt|ONrL$9TcO1^k3T%CsLIADEt<7)(jg{*0o; zY2c^wL^LCF$hzK|DOtXm$`(woV)=a?N>fKF-EZIkJ|J*YnB5@dJu1c;erDk3_yyy9 zZK)ip+C|nlt0JRBspgmXm2@{${zPnNj zcFr%zjajtwPM;_FsX5mp&b~Xzq}OL`Yau1icJyb`rV2}gaofpRi*>uRtJ(D|zv?;v zhvnd4&1_4iu%Ff=jE-E}GQMmlb+G*!&Kr0M7g=fsUdC?>{1!`;yEY95F3I$4%lKY@ z#?M`i?#==A>!7B~29~8zjH$^BfE|yZI(5$UACg+3W@#mMZ%)bCJ}QaNmvA(KI@X;7BN=T2E!Uv|{GB`Q+Nho_H@vK=$jba6i11eZ*` zSB1@NX@g@&Mn|TG>qE2QEfu%=?x?$9c>`vJ!nL3_%7htP>A9X|MVPijFK%fJtIYqD zoV8AtBc9&H34E$H<#%?T2(+zwjcS8F!Xt9XZ&WA-)CI43dZ5u*IQg$n`l^s+2!n4X zfu2>=gol*Tm4$Z@?fjD4$M3NwY~z>cT@ZMmdb*p>96{W-kjL3an&DHLtKb^ha|z-l zCE7k84<3_hzg8#C$uH# z-HDi@ang%uO&Cj9*W1$lD%Q_l!iGfK5;i7VND>K>CETQhHz|6vqMH@nqUcsdlakgH zY^y7{r9r{16zN*Vb~+nLMwYQd;2a*6yW0d_N2)j4m5eTfI&u0(_U)2 z@b2T?iEeIWd|M#n`!sfv?t{)GwJ}9oa5uK&{p23NZl-5H6EwjX&rtd#1~G>r6fg`2 zBk(bbXK)nHV+`jp&QFjD4zBw+SSIlXrtl9;PqYx}Q^a{6B19R~RKS@cXPTT|M6Q4zd&e})XgK~Z zK7zQ0`!&pJI8kS-mwf*KH^4h+)88T1lRO`#-3NI{5Mx-M#MR6{K-<&BJoH>G?>L1) zx1uA{i! literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.java new file mode 100644 index 0000000..79e7bac --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestHeaderExample.java @@ -0,0 +1,109 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +*/ + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Locale; +import java.util.ResourceBundle; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import util.CookieFilter; +import util.HTMLFilter; + +/** + * Example servlet showing request headers + * + * @author James Duncan Davidson + */ + +public class RequestHeaderExample extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private static final ResourceBundle RB = ResourceBundle.getBundle("LocalStrings"); + + @Override + public void doGet(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + PrintWriter out = response.getWriter(); + out.println(""); + out.println(""); + out.println(""); + + String title = RB.getString("requestheader.title"); + out.println("" + title + ""); + out.println(""); + out.println(""); + + // all links relative + + // XXX + // making these absolute till we work out the + // addition of a PathInfo issue + + out.println(""); + out.println("\"view"); + out.println(""); + out.println("\"return\""); + + out.println("

" + title + "

"); + out.println(""); + Enumeration e = request.getHeaderNames(); + while (e.hasMoreElements()) { + String headerName = e.nextElement(); + String headerValue = request.getHeader(headerName); + out.println(""); + } + out.println("
"); + out.println(HTMLFilter.filter(headerName)); + out.println(""); + if (headerName.toLowerCase(Locale.ENGLISH).contains("cookie")) { + HttpSession session = request.getSession(false); + String sessionId = null; + if (session != null) { + sessionId = session.getId(); + } + out.println(HTMLFilter.filter(CookieFilter.filter(headerValue, sessionId))); + } else { + out.println(HTMLFilter.filter(headerValue)); + } + out.println("
"); + } + + @Override + public void doPost(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException + { + doGet(request, response); + } + +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestInfoExample.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/RequestInfoExample.class new file mode 100644 index 0000000000000000000000000000000000000000..3b8df5c95279822cf2b17e165d2f0430ddbe23a2 GIT binary patch literal 3298 zcmbVOS$7;q75-|ZQMX6!B@;WgMH0s2c=t>vRzebMBx1{QEJv~xZH^o}NzY7artMMp zq^HJ~fe^rK32WHQz9g(+JHR*$m91ais0iO5)Jn^2xSJgeXBFTt@mRnubx9!jBLq^D#|8SvE_qixx2^n!J1JXXJF3Xz z?V#F_0|GrIKk(I%K-c~QvjW}2VO0uj9`gfvroB*>(X>}?a3wnyR_NHHd(M-^ZdLbN z0$ax><%@0EQlr6qII`$1G>z$WHGEPkfyw;_z@kg=R~k~eb)}l_DT=9hA=y2!u3D?f zbIJh?)QV!40{hn8X0Y+Bb|hm90_#Icd@(R#n}^sI2hk7RiO3JsxyV;CqRq7ORU97^ zW}MiwiwshG}|g)dw93Ug8o zC&Ct;+NDY(Nl#|VxIvsV($rF`!oj5x@JvT9u)2c%yBMHmFxAcylQeApgn%hxYkjl$d>R!~6YA|ms<#Xl;xpJ)%Ho|Byf3?nN=83DXqu~GW9B=Hn?Jm{(={?QR=y69$=~}!6cBrHx{+pC7Pf5co z%SMqotcO*SgMqFZH4ASz_#s}m@FNF5*4fI&?_6W2W9#14wvv^0rN+Y#-!|gP&=QHT^7viX^N?4&Kx{ncDyb@|s(V#iXkg69~n)=ALiqqI2+b z{DN(BB?~p*ZUt-e)YRDU?Ls{olTnA3^R%n!ToO2d)AAgxjbUr<4Fl^HYYnZJwC>E%s>&~eDbi7 zkxGa$Gdao|fb)r@5|SBNukT6T2S!&j{1_QdmT`Ve@$M+M^>wjcbk3G9$%^73b#~(W zT%dU80IiXZ0qo*e#v}YzNTCn!!=n&*%*-C=oXwrj-CX0XLiv8qT#kZc`rum-zcH#$ zQ1+O`-8jZ)Csx35409%Q1<^b=r`|*tH6dO-oK4+CR| don't compress, just chain filter"); + } + chain.doFilter(request, response); + return; + } + + Enumeration e = + ((HttpServletRequest)request).getHeaders("Accept-Encoding"); + while (e.hasMoreElements()) { + String name = e.nextElement(); + if (name.indexOf("gzip") != -1) { + if (debug > 0) { + System.out.println("supports compression"); + } + supportCompression = true; + } else { + if (debug > 0) { + System.out.println("no support for compression"); + } + } + } + } + + if (supportCompression) { + if (response instanceof HttpServletResponse) { + CompressionServletResponseWrapper wrappedResponse = + new CompressionServletResponseWrapper((HttpServletResponse)response); + wrappedResponse.setDebugLevel(debug); + wrappedResponse.setCompressionThreshold(compressionThreshold); + wrappedResponse.setCompressionBuffer(compressionBuffer); + wrappedResponse.setCompressionMimeTypes(compressionMimeTypes); + if (debug > 0) { + System.out.println("doFilter gets called with compression"); + } + try { + chain.doFilter(request, wrappedResponse); + } finally { + wrappedResponse.finishResponse(); + } + return; + } + } else { + if (debug > 0) { + System.out.println("doFilter gets called w/o compression"); + } + chain.doFilter(request, response); + return; + } + } + + /** + * Set filter config + * This function is equivalent to init. Required by Weblogic 6.1 + * + * @param filterConfig The filter configuration object + */ + public void setFilterConfig(FilterConfig filterConfig) { + init(filterConfig); + } + + /** + * Required by Weblogic 6.1 + * + * @return the FilterConfig that was used to initialise this filter. + */ + public FilterConfig getFilterConfig() { + return config; + } +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.class new file mode 100644 index 0000000000000000000000000000000000000000..4fb68964b88b5d72032587a4b8d9ca2d0cc7fdd8 GIT binary patch literal 2019 zcma)7TUQ%Z6#h;~m=K0i)6$A)J1x?33sb-g0;Ly93kXDkVy#-8B&RSqnHgtJShV~S zpM3P$7hL$@^0_~$%iDJ*0fAy^*2=l;*=O%>@BQs_Ui|&r?*K+o$>BW4TJZ_SvzXBH zWEMADF@;;LxQ#n{xNBfKhkKaG;(iV-c#y?x7IRt5XYpwk3;Nrlfh7Y)fwQrUT*q6J zQS1i(!?}9`VqTzaI`CuV_-f7ZYBEFL`X>aMCtcrFQvyxBeQN^g>7XJ7+8113F4d|f z8Lc`ckCOaCP^MXj#<_0@(`v(w1%?;OK{bqItX7eX92&aI@`oBvPMoS1hYV3pBvJTIHNmV++n(dE+bb$^ z{dGDvqPjtW>!+Hmdltwtw#2%?>2Mo3n9-od0K1QQX@pg*sj#MqN;*}d5`=p((X?yI z_3RnHR+W*Xm{5Mba5VYP!uOc5d*62uGY#oxCD5Fcj-pBWbts-#g_5H!>991}hU;-UU zUXN4j72}Pw2XqiPmmG8hd#-p$dhMvoS9^B9UE0^BI!twep5DGU>WDM3RJ^ow1y)IT zhEQ+4Bkio4z2`J6Nf(oogfc6g3NI&tfs>4#+)Qko_6;Xq3?ez>$tv;iJa5a#0 zyAQ64U%Q<~0`#f}*OH{{;5t2~ z=u^>aKbq*ZMBjtNRNxt%y1HbD5}T3^r2j&vfg1*f|AcK|Uo)E+Sa literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.java new file mode 100644 index 0000000..af1a0b9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionFilterTestServlet.java @@ -0,0 +1,66 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 compressionFilters; + +import java.io.IOException; +import java.util.Enumeration; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Very Simple test servlet to test compression filter + * @author Amy Roh + */ +public class CompressionFilterTestServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + ServletOutputStream out = response.getOutputStream(); + response.setContentType("text/plain"); + + Enumeration e = request.getHeaders("Accept-Encoding"); + while (e.hasMoreElements()) { + String name = e.nextElement(); + out.println(name); + if (name.indexOf("gzip") != -1) { + out.println("gzip supported -- able to compress"); + } + else { + out.println("gzip not supported"); + } + } + + + out.println("Compression Filter Test Servlet"); + out.println("Minimum content length for compression is 128 bytes"); + out.println("********** 32 bytes **********"); + out.println("********** 32 bytes **********"); + out.println("********** 32 bytes **********"); + out.println("********** 32 bytes **********"); + out.close(); + } + +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionResponseStream.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionResponseStream.class new file mode 100644 index 0000000000000000000000000000000000000000..146d2a9ce3eb0485792ff6aae355886788d04f83 GIT binary patch literal 6652 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
that works with + * the CompressionServletResponseWrapper implementation. + * + * @author Amy Roh + * @author Dmitri Valdin + */ +public class CompressionResponseStream extends ServletOutputStream { + + // ----------------------------------------------------------- Constructors + + /** + * Construct a servlet output stream associated with the specified Response. + * + * @param responseWrapper The associated response wrapper + * @param originalOutput the output stream + */ + public CompressionResponseStream( + CompressionServletResponseWrapper responseWrapper, + ServletOutputStream originalOutput) { + + super(); + closed = false; + this.response = responseWrapper; + this.output = originalOutput; + } + + + // ----------------------------------------------------- Instance Variables + + + /** + * The threshold number which decides to compress or not. + * Users can configure in web.xml to set it to fit their needs. + */ + protected int compressionThreshold = 0; + + /** + * The compression buffer size to avoid chunking + */ + protected int compressionBuffer = 0; + + /** + * The mime types to compress + */ + protected String[] compressionMimeTypes = {"text/html", "text/xml", "text/plain"}; + + /** + * Debug level + */ + private int debug = 0; + + /** + * The buffer through which all of our output bytes are passed. + */ + protected byte[] buffer = null; + + /** + * The number of data bytes currently in the buffer. + */ + protected int bufferCount = 0; + + /** + * The underlying gzip output stream to which we should write data. + */ + protected OutputStream gzipstream = null; + + /** + * Has this stream been closed? + */ + protected boolean closed = false; + + /** + * The response with which this servlet output stream is associated. + */ + protected final CompressionServletResponseWrapper response; + + /** + * The underlying servlet output stream to which we should write data. + */ + protected final ServletOutputStream output; + + + // --------------------------------------------------------- Public Methods + + /** + * Set debug level + */ + public void setDebugLevel(int debug) { + this.debug = debug; + } + + + /** + * Set the compressionThreshold number and create buffer for this size + */ + protected void setCompressionThreshold(int compressionThreshold) { + this.compressionThreshold = compressionThreshold; + buffer = new byte[this.compressionThreshold]; + if (debug > 1) { + System.out.println("compressionThreshold is set to "+ this.compressionThreshold); + } + } + + /** + * The compression buffer size to avoid chunking + */ + protected void setCompressionBuffer(int compressionBuffer) { + this.compressionBuffer = compressionBuffer; + if (debug > 1) { + System.out.println("compressionBuffer is set to "+ this.compressionBuffer); + } + } + + /** + * Set supported mime types + */ + public void setCompressionMimeTypes(String[] compressionMimeTypes) { + this.compressionMimeTypes = compressionMimeTypes; + if (debug > 1) { + System.out.println("compressionMimeTypes is set to " + + Arrays.toString(this.compressionMimeTypes)); + } + } + + /** + * Close this output stream, causing any buffered data to be flushed and + * any further output data to throw an IOException. + */ + @Override + public void close() throws IOException { + + if (debug > 1) { + System.out.println("close() @ CompressionResponseStream"); + } + if (closed) + throw new IOException("This output stream has already been closed"); + + if (gzipstream != null) { + flushToGZip(); + gzipstream.close(); + gzipstream = null; + } else { + if (bufferCount > 0) { + if (debug > 2) { + System.out.print("output.write("); + System.out.write(buffer, 0, bufferCount); + System.out.println(")"); + } + output.write(buffer, 0, bufferCount); + bufferCount = 0; + } + } + + output.close(); + closed = true; + + } + + + /** + * Flush any buffered data for this output stream, which also causes the + * response to be committed. + */ + @Override + public void flush() throws IOException { + + if (debug > 1) { + System.out.println("flush() @ CompressionResponseStream"); + } + if (closed) { + throw new IOException("Cannot flush a closed output stream"); + } + + if (gzipstream != null) { + gzipstream.flush(); + } + + } + + public void flushToGZip() throws IOException { + + if (debug > 1) { + System.out.println("flushToGZip() @ CompressionResponseStream"); + } + if (bufferCount > 0) { + if (debug > 1) { + System.out.println("flushing out to GZipStream, bufferCount = " + bufferCount); + } + writeToGZip(buffer, 0, bufferCount); + bufferCount = 0; + } + + } + + /** + * Write the specified byte to our output stream. + * + * @param b The byte to be written + * + * @exception IOException if an input/output error occurs + */ + @Override + public void write(int b) throws IOException { + + if (debug > 1) { + System.out.println("write "+b+" in CompressionResponseStream "); + } + if (closed) + throw new IOException("Cannot write to a closed output stream"); + + if (bufferCount >= buffer.length) { + flushToGZip(); + } + + buffer[bufferCount++] = (byte) b; + + } + + + /** + * Write b.length bytes from the specified byte array + * to our output stream. + * + * @param b The byte array to be written + * + * @exception IOException if an input/output error occurs + */ + @Override + public void write(byte b[]) throws IOException { + + write(b, 0, b.length); + + } + + + + /** + * TODO SERVLET 3.1 + */ + @Override + public boolean isReady() { + // TODO Auto-generated method stub + return false; + } + + + /** + * TODO SERVLET 3.1 + */ + @Override + public void setWriteListener(WriteListener listener) { + // TODO Auto-generated method stub + + } + + + /** + * Write len bytes from the specified byte array, starting + * at the specified offset, to our output stream. + * + * @param b The byte array containing the bytes to be written + * @param off Zero-relative starting offset of the bytes to be written + * @param len The number of bytes to be written + * + * @exception IOException if an input/output error occurs + */ + @Override + public void write(byte b[], int off, int len) throws IOException { + + if (debug > 1) { + System.out.println("write, bufferCount = " + bufferCount + " len = " + len + " off = " + off); + } + if (debug > 2) { + System.out.print("write("); + System.out.write(b, off, len); + System.out.println(")"); + } + + if (closed) + throw new IOException("Cannot write to a closed output stream"); + + if (len == 0) + return; + + // Can we write into buffer ? + if (len <= (buffer.length - bufferCount)) { + System.arraycopy(b, off, buffer, bufferCount, len); + bufferCount += len; + return; + } + + // There is not enough space in buffer. Flush it ... + flushToGZip(); + + // ... and try again. Note, that bufferCount = 0 here ! + if (len <= (buffer.length - bufferCount)) { + System.arraycopy(b, off, buffer, bufferCount, len); + bufferCount += len; + return; + } + + // write direct to gzip + writeToGZip(b, off, len); + } + + public void writeToGZip(byte b[], int off, int len) throws IOException { + + if (debug > 1) { + System.out.println("writeToGZip, len = " + len); + } + if (debug > 2) { + System.out.print("writeToGZip("); + System.out.write(b, off, len); + System.out.println(")"); + } + if (gzipstream == null) { + if (debug > 1) { + System.out.println("new GZIPOutputStream"); + } + + boolean alreadyCompressed = false; + String contentEncoding = response.getHeader("Content-Encoding"); + if (contentEncoding != null) { + if (contentEncoding.contains("gzip")) { + alreadyCompressed = true; + if (debug > 0) { + System.out.println("content is already compressed"); + } + } else { + if (debug > 0) { + System.out.println("content is not compressed yet"); + } + } + } + + boolean compressibleMimeType = false; + // Check for compatible MIME-TYPE + if (compressionMimeTypes != null) { + if (startsWithStringArray(compressionMimeTypes, response.getContentType())) { + compressibleMimeType = true; + if (debug > 0) { + System.out.println("mime type " + response.getContentType() + " is compressible"); + } + } else { + if (debug > 0) { + System.out.println("mime type " + response.getContentType() + " is not compressible"); + } + } + } + + if (response.isCommitted()) { + if (debug > 1) + System.out.print("Response already committed. Using original output stream"); + gzipstream = output; + } else if (alreadyCompressed) { + if (debug > 1) + System.out.print("Response already compressed. Using original output stream"); + gzipstream = output; + } else if (!compressibleMimeType) { + if (debug > 1) + System.out.print("Response mime type is not compressible. Using original output stream"); + gzipstream = output; + } else { + response.addHeader("Content-Encoding", "gzip"); + response.setContentLength(-1); // don't use any preset content-length as it will be wrong after gzipping + response.setBufferSize(compressionBuffer); + gzipstream = new GZIPOutputStream(output); + } + } + gzipstream.write(b, off, len); + + } + + + // -------------------------------------------------------- Package Methods + + + /** + * Has this response stream been closed? + */ + public boolean closed() { + + return (this.closed); + + } + + /** + * Checks if any entry in the string array starts with the specified value + * + * @param sArray the StringArray + * @param value string + */ + private boolean startsWithStringArray(String sArray[], String value) { + if (value == null) + return false; + for (int i = 0; i < sArray.length; i++) { + if (value.startsWith(sArray[i])) { + return true; + } + } + return false; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..9245855af7a7c44648c3750969e35b870e1bd599 GIT binary patch literal 5369 zcmb7IeSA}A6@K2PZPN6%rDz&z(083 zoA;i3&U4Or&N**+?v2Nv1aL8a=fzsQzXn&}23c;DhSJou0td{~x` zxbaahG~6mbZjV@2&=RTW&<;JFOvKZ=LPziZ&`4-BnATGxG2IA83?mub$feIZ$VskJs7@OxJv6Ma zu;d$CbX&$qW{f^lNW>4OqK2MQm~M&(qlw`5R5WhvHjgRL98L@;Q+hfbO~iLb_z+3N z1{KsMg+|A#p3J^|qQ)t{B|5C{982nHg{G@5^|4TVC`jYc_z-nh4eA4#A$l9pLxXy1 zT_PD3;RZ`KV?<-YEuka@Yx<%?@sN>8F%~O|->#mjcMu+oS`>A@wvj?i2gjWNRM;JQK} zOVYMG6-p-c6hV3zU_0k^eMTsJfc~4RO=6r@xFD??4n>ZPRCa64G!kMZ7=ifRFjg5 zI(;;nHdsl!La_|BRE=1B4bzg-=Iu*lQemAGq(Ga4IOQ3*M10e*1AQ9SV}ph(ag~OR z*refYV8u@>^%}o7HbDI zY{fPWJy_?)w>5kRXA~|!Ct81)xi?aou#rgl8UD1N1sT%^-FQaBckwI}T8g(P6OFOc zD6|xpM!t^xM#8V*Iebr+?`wD-KTw!iENqcUB&X=fmyo=5LU*{( z9Ln^I9Iq|%yK!1W977Vi7c}U2r-o}~dABSB2y1u|2i*8E`>q)PHuX*0^5vq?Y1V|_ zY6Jc&{8#ObmQE78C24pG2NdQN;<$+s9ty?SoDAKeaz(z3Iy(K4P}(1gu^9}G`3H18 zZs*0nk9m>?>CbgJ@!(kv`@kX4$W(H0`T3gR&gJ1{`rwboC0fOGyQ<{m|1rzjv2|LN zui+<><{47tp)i}ZUyp|qgDfpU#nuTdr*H>e5$Ap?%g@|+Rm0Em3k|=- zuQdD`uW^8OYxoU*tKlF_;Nb6A=?2cNlf z_Hp;gl!L-{K3CxFsN*w7E!Ukqc^*|f1@;8GCZGap92K&-0&aWn)TMQ!C_)SkdJUt<=&D;k#>bDQ8FzmeQw-h<6!w^G}yu{9=ZMkH7cu7m=c$aZuRH z=LV?%@QFMCDJvYkm-!G~>z(A9&Ad%w zPQQ5Aa1wJBCNQtJOGL8p%U+qqeA%nASRlJMi-ldssK?^t0y+rX!Szl|!(CW_dk~rph~AnSn$4BJK^i*D&P7NS-MJr|RgB9+AwU$DSY zo)mIth35r^=S7C+C5Go^_<5b`z$;|Ws}8_h9e}IgYOL=l%2$G=Z3aoTQJLiHs0G<0 z+cCkBgTK^-e}1?xa^faCmnrm8mjvJ0g)XL8S6;O14Cb(%F7Kbjihi-oj(o`kE@d}9 z!d%H4Ii0{|(w_w$;aXf?iF!W&o-X`>iTWe|Yv@n>Z=*kB5&nY3_$xc@-`F?*&i3>V zc9egToc|*0|APnch8ZiX#~!s~wTE5#JxDQwLaI7cYtxp#j({8KIrT-+GmxQ>u)T+| zljzkGSAEw>TwZ}ws1|@$*;fl4l*?hP-ZsW>Fk%{0aw)a-y~c`?COmBGTUo*XKigiU zeCy&f2$C$T4xz(*VfS|7k8d@XZY#1U@fH_$A2CN$eOGtcpMkFK39Km;fypoBL7l2W zi}GT#s>N=_KN(aVVyfPBBS3&HSj~8*m<2-3J2Y%NBxl$0ZG|1j%Ga@(LHsvrD{AQ{ zZ{N1J{Zt?-noK`zh$g1D7CL9Wh^QuLsu?~t-NfLxKFeEf%3E%-Ei1gwOv3g51FEP{ Ag8%>k literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.java new file mode 100644 index 0000000..89e552e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/compressionFilters/CompressionServletResponseWrapper.java @@ -0,0 +1,278 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 compressionFilters; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +/** + * Implementation of HttpServletResponseWrapper that works with + * the CompressionServletResponseStream implementation.. + * + * @author Amy Roh + * @author Dmitri Valdin + */ +public class CompressionServletResponseWrapper + extends HttpServletResponseWrapper { + + // ----------------------------------------------------- Constructor + + /** + * Calls the parent constructor which creates a ServletResponse adaptor + * wrapping the given response object. + */ + public CompressionServletResponseWrapper(HttpServletResponse response) { + super(response); + origResponse = response; + if (debug > 1) { + System.out.println("CompressionServletResponseWrapper constructor gets called"); + } + } + + + // ----------------------------------------------------- Instance Variables + + /** + * Original response + */ + protected final HttpServletResponse origResponse; + + /** + * The ServletOutputStream that has been returned by + * getOutputStream(), if any. + */ + protected ServletOutputStream stream = null; + + + /** + * The PrintWriter that has been returned by + * getWriter(), if any. + */ + protected PrintWriter writer = null; + + /** + * The threshold number to compress + */ + protected int compressionThreshold = 0; + + /** + * The compression buffer size + */ + protected int compressionBuffer = 8192; // 8KB default + + /** + * The mime types to compress + */ + protected String[] compressionMimeTypes = {"text/html", "text/xml", "text/plain"}; + + /** + * Debug level + */ + protected int debug = 0; + + /** + * keeps a copy of all headers set + */ + private final Map headerCopies = new HashMap<>(); + + + // --------------------------------------------------------- Public Methods + + + /** + * Set threshold number + */ + public void setCompressionThreshold(int threshold) { + if (debug > 1) { + System.out.println("setCompressionThreshold to " + threshold); + } + this.compressionThreshold = threshold; + } + + /** + * Set compression buffer + */ + public void setCompressionBuffer(int buffer) { + if (debug > 1) { + System.out.println("setCompressionBuffer to " + buffer); + } + this.compressionBuffer = buffer; + } + + /** + * Set compressible mime types + */ + public void setCompressionMimeTypes(String[] mimeTypes) { + if (debug > 1) { + System.out.println("setCompressionMimeTypes to " + + Arrays.toString(mimeTypes)); + } + this.compressionMimeTypes = mimeTypes; + } + + /** + * Set debug level + */ + public void setDebugLevel(int debug) { + this.debug = debug; + } + + + /** + * Create and return a ServletOutputStream to write the content + * associated with this Response. + * + * @exception IOException if an input/output error occurs + */ + public ServletOutputStream createOutputStream() throws IOException { + if (debug > 1) { + System.out.println("createOutputStream gets called"); + } + + CompressionResponseStream stream = new CompressionResponseStream( + this, origResponse.getOutputStream()); + stream.setDebugLevel(debug); + stream.setCompressionThreshold(compressionThreshold); + stream.setCompressionBuffer(compressionBuffer); + stream.setCompressionMimeTypes(compressionMimeTypes); + + return stream; + } + + + /** + * Finish a response. + */ + public void finishResponse() { + try { + if (writer != null) { + writer.close(); + } else { + if (stream != null) + stream.close(); + } + } catch (IOException e) { + // Ignore + } + } + + + // ------------------------------------------------ ServletResponse Methods + + + /** + * Flush the buffer and commit this response. + * + * @exception IOException if an input/output error occurs + */ + @Override + public void flushBuffer() throws IOException { + if (debug > 1) { + System.out.println("flush buffer @ GZipServletResponseWrapper"); + } + ((CompressionResponseStream)stream).flush(); + + } + + /** + * Return the servlet output stream associated with this Response. + * + * @exception IllegalStateException if getWriter has + * already been called for this response + * @exception IOException if an input/output error occurs + */ + @Override + public ServletOutputStream getOutputStream() throws IOException { + + if (writer != null) + throw new IllegalStateException("getWriter() has already been called for this response"); + + if (stream == null) + stream = createOutputStream(); + if (debug > 1) { + System.out.println("stream is set to "+stream+" in getOutputStream"); + } + + return (stream); + + } + + /** + * Return the writer associated with this Response. + * + * @exception IllegalStateException if getOutputStream has + * already been called for this response + * @exception IOException if an input/output error occurs + */ + @Override + public PrintWriter getWriter() throws IOException { + + if (writer != null) + return (writer); + + if (stream != null) + throw new IllegalStateException("getOutputStream() has already been called for this response"); + + stream = createOutputStream(); + if (debug > 1) { + System.out.println("stream is set to "+stream+" in getWriter"); + } + String charEnc = origResponse.getCharacterEncoding(); + if (debug > 1) { + System.out.println("character encoding is " + charEnc); + } + // HttpServletResponse.getCharacterEncoding() shouldn't return null + // according the spec, so feel free to remove that "if" + if (charEnc != null) { + writer = new PrintWriter(new OutputStreamWriter(stream, charEnc)); + } else { + writer = new PrintWriter(stream); + } + + return (writer); + } + + @Override + public String getHeader(String name) { + return headerCopies.get(name); + } + + @Override + public void addHeader(String name, String value) { + if (headerCopies.containsKey(name)) { + String existingValue = headerCopies.get(name); + if ((existingValue != null) && (existingValue.length() > 0)) headerCopies.put(name, existingValue + "," + value); + else headerCopies.put(name, value); + } else headerCopies.put(name, value); + super.addHeader(name, value); + } + + + @Override + public void setHeader(String name, String value) { + headerCopies.put(name, value); + super.setHeader(name, value); + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.class new file mode 100644 index 0000000000000000000000000000000000000000..909826a6d6cf728f07afaf893411dee4c894a91c GIT binary patch literal 4143 zcmaJ@`Fk8k5q%?RcY0SNdozk15;<4~2V~i?h_5)ZBakf#OK2sNk!57Z!K2kkUTb$& ztY&R19Ekyw1i}%Ha0J2??f_0mWXC4qzQPsmo8S3`{{TK-O^>uI?T~N3?e41TdHt%Z zy1JkL@0I5O?8HCQ7{U28-i~*quodq#aUqQ+t$CNI?@LpCzljGF-mUN+g$EVhtMERB z_bYrr;UR?&Dtt)c!wMf!cvz-?RN-R^A6NKk7A`HG3JN`GGAYtlci@O6c6$ncvA7o~qfnkN;$CH+$hPfNe3 za7p^h3eQM?Md7OS-&S~5`sWnBBmH+3z9;?nQ}_XXn8uIrV}+k6{8Zs*3ePM2T;Ugu z*z@muP5jb;%DDy4pK{9vt{pz@o^iV>LB7y+Fw*Wbkldg5^Ffb+#*QuH2AU3*raS{{ zhx5KSQYlV)}G(Q*PkRcMZ+Y)gY$=&Ml1Pi~KrM zvv?opa$$4E3nn~a#+3(2m2$S^2d7B2V~d_&aQ&GshdBNWzc7mYb7rzA(`4P_ano9y zz|GBO-MNsY3720GyU$(V=jZ6+l)J!>o0rxb^aIUCi0P3g-J-u5osMW(OR}ad=A)iB zJ36i9HOunq`7%obA1YPoaEddtdA}md$=LC7C4Y*{if-OFu)ZV4uP``nd4|jzrY7mh zoPl*6_5RB|yI!sLpufz`5Z*@|aq(EmCxgV@>Xu+B8%VKiCy0C3`C~m3i_{Io@30 zNeUBfG#8Y@ks2wTiIl3(%SFRANBmj8bk=VVO6^(Kx8Mt{q*LM95lluj9GGJjZ$2EQ zj(Stvws5S*PF2c!m>ekQwa#&aN;w=}x7xb{m3(2!D_i&j{>Vsn$>2{GPUECa>6*H8MsA|(Zntm-XDKc4NOiZ<$_w-7^ z1<_22&`d!mvZ!WdF{_%~qAQ3l;gwwx7DPz8#krzLZwpO*&X@>q6`|$W=tzINP90Ic zMU?5W!EC=6L~}PznD~o@zv6Eu{%+wPA^St_SvQ|2``&^(KkM=^n1|h5emb9H9%M@u zKL}5VdC>ENvdauG``!7#D|2E^4vkKp_HxVsyP9@ObxEK5L4Q7Q{T!2K{Zgq}T^CKB z0bK@Kqf-{nko4UrXRMLOfjQSPD77o;&dssR8rVR&?(jw7-e=(ExC8ql^HosN)o+D+ z&H`O#Eo>}RNMW7+K40oO%sLrxzULOXR%__|N;UV32geTzJ~r_Z8R3;mWI3Z8t>>6W zm#stTBpUbwHgsNs(RmpSPowcFnkFtGG2HnS8n-SY`2_6^7z@8mu)Ur)@eOE38(Oh} z?Tt7R+Cm(R<0z$8r0@nza1}#xJz8xiaSU2h0^PI-^Kl9qIvE<;Lnup6il7Wh?Fir* zF5Sp)?(AHI+MltWMQWnaPCFA#cC#~)uq|gIX}35NroG0QQ1)79B9pW;Y)$(bw#v5I zrtDU>Y5Q8X&GtGc+m^8&L(*P({5GZMH7S#05kb&}JzkYl^%5phh= z>AUbovdm&FH`S$Alj10h|6trOk)w$xFmmIO$c-Mlaozrmsoi*qxN*I>af7(gCT?sH zH*O@+r2SGMYQ6~3TS#;Vy0DwSJ=n{i#6=VBStfcLypU)YiB7L1x;G-qVjU6PO)n*2 z%}o-q1S58Gb;xe730d=U$XI$Jh_NW&Ws7(@$D3=$H*vg(S4aSA zlcKj~1qp!UmmwAI|F7^$LG92hY^fP@!MGI$Vpm|Hj#gNaw`5`SeU@KiQ-#i6N>2OE6w3EslXS~ z1wN1-Wh^c+8ZRKgzfdt6aK>okvtk#{8CgDAmMke2xJF=O(TBWU_QQY@V3C>ioBiZE6bhQ^p=I$r}&J(YYFMF7*h31qSD znWVl1UMrWtA-Mzwsh`79%CeY>*}sQt O5UM5R9`0BJ?)@MB2`vEt literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.java new file mode 100644 index 0000000..759edee --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/dates/JspCalendar.java @@ -0,0 +1,153 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 dates; + +import java.util.Calendar; +import java.util.Date; + +public class JspCalendar { + final Calendar calendar; + + public JspCalendar() { + calendar = Calendar.getInstance(); + Date trialTime = new Date(); + calendar.setTime(trialTime); + } + + public int getYear() { + return calendar.get(Calendar.YEAR); + } + + public String getMonth() { + int m = getMonthInt(); + String[] months = new String [] { "January", "February", "March", + "April", "May", "June", + "July", "August", "September", + "October", "November", "December" }; + if (m > 12) + return "Unknown to Man"; + + return months[m - 1]; + + } + + public String getDay() { + int x = getDayOfWeek(); + String[] days = new String[] {"Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"}; + + if (x > 7) + return "Unknown to Man"; + + return days[x - 1]; + + } + + public int getMonthInt() { + return 1 + calendar.get(Calendar.MONTH); + } + + public String getDate() { + return getMonthInt() + "/" + getDayOfMonth() + "/" + getYear(); + + } + + public String getTime() { + return getHour() + ":" + getMinute() + ":" + getSecond(); + } + + public int getDayOfMonth() { + return calendar.get(Calendar.DAY_OF_MONTH); + } + + public int getDayOfYear() { + return calendar.get(Calendar.DAY_OF_YEAR); + } + + public int getWeekOfYear() { + return calendar.get(Calendar.WEEK_OF_YEAR); + } + + public int getWeekOfMonth() { + return calendar.get(Calendar.WEEK_OF_MONTH); + } + + public int getDayOfWeek() { + return calendar.get(Calendar.DAY_OF_WEEK); + } + + public int getHour() { + return calendar.get(Calendar.HOUR_OF_DAY); + } + + public int getMinute() { + return calendar.get(Calendar.MINUTE); + } + + + public int getSecond() { + return calendar.get(Calendar.SECOND); + } + + public static void main(String args[]) { + JspCalendar db = new JspCalendar(); + p("date: " + db.getDayOfMonth()); + p("year: " + db.getYear()); + p("month: " + db.getMonth()); + p("time: " + db.getTime()); + p("date: " + db.getDate()); + p("Day: " + db.getDay()); + p("DayOfYear: " + db.getDayOfYear()); + p("WeekOfYear: " + db.getWeekOfYear()); + p("era: " + db.getEra()); + p("ampm: " + db.getAMPM()); + p("DST: " + db.getDSTOffset()); + p("ZONE Offset: " + db.getZoneOffset()); + p("TIMEZONE: " + db.getUSTimeZone()); + } + + private static void p(String x) { + System.out.println(x); + } + + + public int getEra() { + return calendar.get(Calendar.ERA); + } + + public String getUSTimeZone() { + String[] zones = new String[] {"Hawaii", "Alaskan", "Pacific", + "Mountain", "Central", "Eastern"}; + + return zones[10 + getZoneOffset()]; + } + + public int getZoneOffset() { + return calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000); + } + + + public int getDSTOffset() { + return calendar.get(Calendar.DST_OFFSET)/(60*60*1000); + } + + + public int getAMPM() { + return calendar.get(Calendar.AM_PM); + } +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.class new file mode 100644 index 0000000000000000000000000000000000000000..c676cb957e938599246db25666db9c8cd9525ca9 GIT binary patch literal 521 zcmZutO;5r=5PeH&3#BOXB^o_=gPPcbC!^tF;=vF!so}oh2A4paEXCiYiN?f(KfoVl zoZVI>k;Bf;$D8+N=JV_Q1HdWvJ=kcK&@Q8hT^Ah}dkn>xF9btfe+EpO{ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.java new file mode 100644 index 0000000..82c22f6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/error/Smart.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 error; + +public class Smart { + + String name = "JSP"; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.class new file mode 100644 index 0000000000000000000000000000000000000000..04bc6c15cad419734869544def33e6effb1226fe GIT binary patch literal 1400 zcmaJ<+fEZv6kTU#XlX4_K@q%g5rkeSWAsf7i9kspjgo-85A=vb%FJZul+=InK@*9I z4}O3jWn5=EX-8<=r2AZE?RD1Ld;j_S>op6^}q(fPUN*2{DHUx^13|*&n zD#OV2y^jZb0^(3$V%PT~<#_7UX|?4TdGt>RWY7HOmk(_vu-3SAuAPoeg6o!4_GJ{< z%DIpoW$zF}0wq1QC6Ec6kUN2e;Tb2+g+{)0Jy&fDn5FWmfVJy4rNC6f_2m2Z)tL-W zoU;~hrW^h_H9J(!b8=~^&u%0z-;f>WDrm{bu6H-&-f<#H{#+#0Q6gr!G+K=oFiCvM zi$HlqQVO`GlXDmS$CgUv(XR>QoBpwKLPfQ){{vptJLfV`>`RnIO<=s~*S%&8Ao_r% z(r*gfYx?g#DH(Q8*-*A5{WAa9Z-?h{-_=J<`S7^iu%xeBghm7fsbxiK)qn29gv@PPY57l4PD<%#w&$EcIHi8eI4 zQoVuE&(6oU3zW1NGt72T34>~lskaSyv?;juGJx2+Mecmf~N^r-_#En-zYF` zsx;8lGb|9LO>M+v%rU>-%B-a_jl|3%F%~nH_+RdE)DjM}n7K{zDn()rAbHN#bcIw& zty^=aEpJj3VgSWTPseaC+bNDgURHY(vQIf$MzJDpVCrD$kZSidD*)`WMSGmLI$OJ+ OVlO5N1zr$kVC^3XVD%vY literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.java new file mode 100644 index 0000000..127eddf --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ExampleTagBase.java @@ -0,0 +1,74 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 examples; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.BodyContent; +import javax.servlet.jsp.tagext.BodyTagSupport; +import javax.servlet.jsp.tagext.Tag; + +public abstract class ExampleTagBase extends BodyTagSupport { + + private static final long serialVersionUID = 1L; + + @Override + public void setParent(Tag parent) { + this.parent = parent; + } + + @Override + public void setBodyContent(BodyContent bodyOut) { + this.bodyOut = bodyOut; + } + + @Override + public Tag getParent() { + return this.parent; + } + + @Override + public int doStartTag() throws JspException { + return SKIP_BODY; + } + + @Override + public int doEndTag() throws JspException { + return EVAL_PAGE; + } + + + @Override + public void doInitBody() throws JspException { + // Default implementations for BodyTag methods as well + // just in case a tag decides to implement BodyTag. + } + + @Override + public int doAfterBody() throws JspException { + return SKIP_BODY; + } + + @Override + public void release() { + bodyOut = null; + pageContext = null; + parent = null; + } + + protected BodyContent bodyOut; + protected Tag parent; +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.class new file mode 100644 index 0000000000000000000000000000000000000000..52de017fed91f9289bae6a2b37ef28a322ceec52 GIT binary patch literal 1926 zcmah~Yi|=r6g}(Ln#~4C+&l^m&y+Y0Wg#J?ZFn?soYui$z#%k3NL|}gcT;EA@{UvY z-}DFMLo1a;Y6X1nkE(iR*K!`-3QIfBJLjHz&zzahO^OVB)vN!iVW{q{{3t~`oW&HYvCy02S;cbyDB~I?aP8+O zb}L8$r6N?t>$GcP-BEcO3Nvs^#bV+jKBI1@<1#UUNfV#qf{AOmZsIXY%-F6_`PT8o z#8Z?_Ji~JxFHBUhY2qaqYbHQC$w|Xiwc52<9eYh7tsTE*ZTRHZ=<_!53g0U>SxS3K zD-9FZkFMH2gSixm+=pefExRFDe^PWQ_2nRECz(7uGGO+m1_6&5XfQ*$+fKD3 z>3=3d^J7&|uI`AMTn?(BN+HV~lDH8;LXt#RT1wu4tSiZ7dXUSY9m}#IWWlX9J)aln zRoh{iFw*R7gd1i(G$4BV7iAhS%Jib3ZoO^AI4xPD>N0Bhq=$CmisC9?g%RH5I4)om z8PJZi7{)kb{isW>N{DTmd#p6JQ=F~QMq@vkJA{@?y+iCR;<@-+B>v!P442rRB`R0 z&v7GQHbdKx=_6XJ^Lj2mcZlR^*g2$dGk_fr&HAu<0LBLlvk_p4C@_m)w?6`wivUYT zfh`d1?nl7p$UPPavKWLNgh>&S`;0hLA5+Bq=4QF^9$M~7~(B{7S#>G%E1~i zMJ-aJx>AH+V*Y^YY;%zKAwuXp`QmL literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.java new file mode 100644 index 0000000..f4f3050 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTag.java @@ -0,0 +1,87 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 examples; + +import java.io.IOException; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspTagException; + +/** + * Example1: the simplest tag + * Collect attributes and call into some actions + * + * + */ + +public class FooTag extends ExampleTagBase { + + private static final long serialVersionUID = 1L; + + private final String atts[] = new String[3]; + int i = 0; + + private final void setAtt(int index, String value) { + atts[index] = value; + } + + public void setAtt1(String value) { + setAtt(0, value); + } + + public void setAtt2(String value) { + setAtt(1, value); + } + + public void setAtt3(String value) { + setAtt(2, value); + } + + /** + * Process start tag + * + * @return EVAL_BODY_INCLUDE + */ + @Override + public int doStartTag() throws JspException { + i = 0; + return EVAL_BODY_BUFFERED; + } + + @Override + public void doInitBody() throws JspException { + pageContext.setAttribute("member", atts[i]); + i++; + } + + @Override + public int doAfterBody() throws JspException { + try { + if (i == 3) { + bodyOut.writeOut(bodyOut.getEnclosingWriter()); + return SKIP_BODY; + } + + pageContext.setAttribute("member", atts[i]); + i++; + return EVAL_BODY_BUFFERED; + } catch (IOException ex) { + throw new JspTagException(ex.toString()); + } + } +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..e57ebf20c4167e7cc18d41747f3806964d841b5b GIT binary patch literal 658 zcmaJ;%TB^T6g^YQL&R6*CF(*G6Y9b)Tw>g)BqWU+2#LBHV5}vjCG9}?EM1Xk^aK1T zh?X&OLL_nLB4bzg|B8oZ~QyGzw`HGbm+H&O*ap8kIEm8B!On@5)PtMAd9F z=vP5cFl^bbFK$PJjtE=4;}K%mL6>`N9=fWYgSvcjBZi7CCVVjTL}b;2pv9e=i41we ze++6QFe6Dtzo*b~y~M?*_;M@*zeaQpU=(&m-BnM@{~7j7O_f6iYYZnVCtSXr>>CJW5^b6?bbUwB4;ad;4Eaxa**FGs z=91-c-?3)mwfKp@ko$(&#t~BV!D?w>YJQ4Ysw~Qka`JQv_7WejQ%uER2|3#5W)0ZD zCROxX*ruq+4U*9)7xZ^%cZoL&M#9kb#1zTqGaYF75v#;v#Tj8PMpW#;AUTHJxIh05 Dwoaih literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.java new file mode 100644 index 0000000..e3fe371 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/FooTagExtraInfo.java @@ -0,0 +1,36 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 examples; + +import javax.servlet.jsp.tagext.TagData; +import javax.servlet.jsp.tagext.TagExtraInfo; +import javax.servlet.jsp.tagext.VariableInfo; + +public class FooTagExtraInfo extends TagExtraInfo { + @Override + public VariableInfo[] getVariableInfo(TagData data) { + return new VariableInfo[] + { + new VariableInfo("member", + "String", + true, + VariableInfo.NESTED) + }; + } +} + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/LogTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/LogTag.class new file mode 100644 index 0000000000000000000000000000000000000000..40f55f6a609f465b0df935edba388afb9ac2c684 GIT binary patch literal 1522 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ShowSource.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ShowSource.java new file mode 100644 index 0000000..2337d7c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ShowSource.java @@ -0,0 +1,76 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 examples; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.TagSupport; + +/** + * Display the sources of the JSP file. + */ +public class ShowSource extends TagSupport { + + private static final long serialVersionUID = 1L; + + String jspFile; + + public void setJspFile(String jspFile) { + this.jspFile = jspFile; + } + + @Override + public int doEndTag() throws JspException { + if ((jspFile.indexOf( ".." ) >= 0) || + (jspFile.toUpperCase(Locale.ENGLISH).indexOf("/WEB-INF/") != 0) || + (jspFile.toUpperCase(Locale.ENGLISH).indexOf("/META-INF/") != 0)) + throw new JspTagException("Invalid JSP file " + jspFile); + + try (InputStream in + = pageContext.getServletContext().getResourceAsStream(jspFile)) { + + if (in == null) + throw new JspTagException("Unable to find JSP file: " + jspFile); + + JspWriter out = pageContext.getOut(); + + try { + out.println(""); + out.println("
");
+                for (int ch = in.read(); ch != -1; ch = in.read())
+                    if (ch == '<')
+                        out.print("<");
+                    else
+                        out.print((char) ch);
+                out.println("
"); + out.println(""); + } catch (IOException ex) { + throw new JspTagException("IOException: " + ex.toString()); + } + } catch (IOException ex2) { + throw new JspTagException("IOException: " + ex2.toString()); + } + return super.doEndTag(); + } +} + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.class new file mode 100644 index 0000000000000000000000000000000000000000..e9c4dea95fd60c19ac64943ef23183828147ee20 GIT binary patch literal 2063 zcmZ`)TT|Oc7(MHoj1YvFTbq;^hPE*V;#^2VAted72FHZ75Gd(Y*s2i-OSR;bpU|1U z^)U9=+?3#Az+0wj#$O?4K*(KN0OWwL}Rg7p5 z1%yDmy|rWH1GPXRx1+z%GnQT|W>)--X_~lR*(??Plc!Bq{SBJ5S$5r^yyDqTf^XSz0ksa~D$u!JwJYVkv1rOFb=LF0CYz-pjZwxjenZ1B-q-K} zKGbj(NewBCXxKttK|zCo?-Ud@Y{R4*4Li6g#e@`hq?i=w_Pc*N6@ekCZAyW4s7EQ# zf5Mxfsnm`j4^dRHP8&$U_h!D$w%4vWNM@ZSUogCbxEk; zsvWa4W_(}KEwa5Om7fbl9o|Hu$8^UrN(F)OM$RAeIbfuJiBC0yPUD_^?5w92VPgoi zNVh<209@NH+ds(bIX$wDA--S(d`qIZgeyowV34a2^&!bce@;63BN^$BBqhffZOL28 zF|IZd<_t)tk08>C&>_OUjHG)IJ%qv`ehBq%g+`!G6n;C``qAr#mrH2zV)z^*^bIeER3#@7gGFX`mA5y;Y6Rof!XR$KGx_%Cp zEQrLqjXQO$Fbg2#N;28ASht8ZaSoO&s>HgB$tJ9;rz#fYc$Zj{=U~akNG#q+=Fhf> zA=X#M^)me$?Nw;GM2NF+6&=5!b2ONC9w1OhPSl)UIKXWhDD2ZX(=8?k!Hn7OY@Db1DcrptMkMR@#zLGP8#Ibm4 vni!HHFKfMz<41gq8Tz|V?L{d6AgSO%UvF=8R>8w0U4TUrbR+0Sa)04}RZ6>< literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.java new file mode 100644 index 0000000..b335860 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/examples/ValuesTag.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 examples; + +import java.io.IOException; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.TagSupport; + +/** + * Accept and display a value. + */ +public class ValuesTag extends TagSupport { + + private static final long serialVersionUID = 1L; + + // Using "-1" as the default value, + // in the assumption that it won't be used as the value. + // Cannot use null here, because null is an important case + // that should be present in the tests. + private Object objectValue = "-1"; + private String stringValue = "-1"; + private long longValue = -1; + private double doubleValue = -1; + + public void setObject(Object objectValue) { + this.objectValue = objectValue; + } + + public void setString(String stringValue) { + this.stringValue = stringValue; + } + + public void setLong(long longValue) { + this.longValue = longValue; + } + + public void setDouble(double doubleValue) { + this.doubleValue = doubleValue; + } + + @Override + public int doEndTag() throws JspException { + JspWriter out = pageContext.getOut(); + + try { + if (!"-1".equals(objectValue)) { + out.print(objectValue); + } else if (!"-1".equals(stringValue)) { + out.print(stringValue); + } else if (longValue != -1) { + out.print(longValue); + } else if (doubleValue != -1) { + out.print(doubleValue); + } else { + out.print("-1"); + } + } catch (IOException ex) { + throw new JspTagException("IOException: " + ex.toString(), ex); + } + return super.doEndTag(); + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/filters/ExampleFilter.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/filters/ExampleFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..473cc8f86717180319a6d121b7ce2ee66b7fa831 GIT binary patch literal 2281 zcmb7F`%@cL6#i}!vLRVsDGw>wqE^YHG_^jerG-+Y3guB73fB7CBsXDcl1+CvmG)O3 z_0Op@3ZgUqs5AcR|Ks@G-35{W&N!JlH}{@%&-u=G&bj;7KfnGC;4Rp3jAFJMFX5&V za|ztSd>kKOA%WZYFoBP-s9`CN7-r)%xTF3p$FQQ-)fm>)dN+ZOaW953WuA{=J%;=0 zd_#%N7(UVPK*OgR9tw0Du4|ixrYi-K%iG2iBUd%*m0X^u^~$t>UN)<)wCAmQ*{leR zdp0{cN7_%S(#_p&(b774-K?ALj6gV*-Vlh)TO~T~TQ=)*wOK1jd)+8hy--%ssBRdx zsrJEP#N9F-fstiDq?23NF=~yf^kdMwR+5fuTTcaICCfh*c$n&dl=q?ClaHG;pFU0N zG_1NKJJmrxTZUPmRvBov??&LA7RV@gnlb|4mS5ZI7@Tuyyo9$SDYn9@E@vn$?oDS)_R0YT89rG*#!e5?)gMrQwhy-r*4=<_C+9XHwzB4{1IcW-t!*8iJ4HC|^=bRWDm0~P58F4>>1+#$si zL02BJ+-{-XAfwTc^^(BU36vb~>7&jaPc8kYx*cnKT=G@5_&yGu6qAYeGnYk<<6Xlx zYLXACz#Au-wv_Df32w{dppeH55Awj9{4R`w+#1@H%%) + *
  • Attaches itself as a request attribute, under the attribute name + * defined by the value of the attribute initialization + * parameter.
  • + *
  • Calculates the number of milliseconds required to perform the + * servlet processing required by this request, including any + * subsequently defined filters, and logs the result to the servlet + * context log for this application. + * + * + * @author Craig McClanahan + */ +public final class ExampleFilter implements Filter { + + + // ----------------------------------------------------- Instance Variables + + + /** + * The request attribute name under which we store a reference to ourself. + */ + private String attribute = null; + + + /** + * The filter configuration object we are associated with. If this value + * is null, this filter instance is not currently configured. + */ + private FilterConfig filterConfig = null; + + + // --------------------------------------------------------- Public Methods + + + /** + * Take this filter out of service. + */ + @Override + public void destroy() { + + this.attribute = null; + this.filterConfig = null; + + } + + + /** + * Time the processing that is performed by all subsequent filters in the + * current filter stack, including the ultimately invoked servlet. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param chain The filter chain we are processing + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) + throws IOException, ServletException { + + // Store ourselves as a request attribute (if requested) + if (attribute != null) + request.setAttribute(attribute, this); + + // Time and log the subsequent processing + long startTime = System.currentTimeMillis(); + chain.doFilter(request, response); + long stopTime = System.currentTimeMillis(); + filterConfig.getServletContext().log + (this.toString() + ": " + (stopTime - startTime) + + " milliseconds"); + + } + + + /** + * Place this filter into service. + * + * @param fConfig The filter configuration object + */ + @Override + public void init(FilterConfig fConfig) throws ServletException { + + this.filterConfig = fConfig; + this.attribute = fConfig.getInitParameter("attribute"); + + } + + + /** + * Return a String representation of this object. + */ + @Override + public String toString() { + + if (filterConfig == null) + return ("TimingFilter()"); + StringBuilder sb = new StringBuilder("TimingFilter("); + sb.append(filterConfig); + sb.append(")"); + return (sb.toString()); + + } + + +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/BookBean.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/BookBean.class new file mode 100644 index 0000000000000000000000000000000000000000..9321a62eb8eec3e02242b3aad347b89f3c016660 GIT binary patch literal 736 zcma)3T}uK%6g{)Mx@v2dm6fK^L!jHoLOn$hR1gGG4~Flf4LY{&%DP5Bs~`z_=m+$p zqC2}rQ2Wr!{W#on&b>1qpKtE~4zZa-8f#gku&zQ`g^Gy{6IF&(C_`5;6q^J7z#W%+ zJ*O20((4^Fr1>Q5`vHR?#~qLQ6Y0tDl;NoUcln$i>3lVL{$x4aXt z;CH#(=7CiG3^c;N95bvn2jkI!BOdv1S(-ST zU1Cyw6&;gn`IDe4E~WC$e+%xbXRt7bngtUX3t1I%$S{igQ-1=BQKbq zG3e)B;KhBybh=}P%w>2d7)p*8i0jqd711qseX3YaIN|=7N1n{nVkW-#mJD@gwp^Up z;(^Z>zF6ABFdPUTNcE|R2Xc0$)7?6Knf9xl|842V7=^27B8HyyV5Y*yat{+Z%Gx`g?SFoO? zyg+@TR6&8>9RdRll4ugR1(Py!14og%QnrM0DrM6zrL^8N)JF<7B6?EX|3%im$-A&p ja-Yx&arEBN9}7lOZPN~ii9&6IN)-s7Y$XTpB@-)OY-C^B literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/FooBean.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/FooBean.java new file mode 100644 index 0000000..4dc0a78 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/FooBean.java @@ -0,0 +1,36 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples; + +public class FooBean { + private String bar; + + public FooBean() { + bar = "Initial value"; + } + + public String getBar() { + return this.bar; + } + + public void setBar(String bar) { + this.bar = bar; + } + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/ValuesBean.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/ValuesBean.class new file mode 100644 index 0000000000000000000000000000000000000000..abaff0a15725f8cd65f84dc184e5955ef8af2349 GIT binary patch literal 983 zcmZ{i&raJw5XQf?O+td3@SgxJ6k5Op2}^LK$^jw{C~6N>xo^TMb!2Q5JE$*J0TK}s z2OfZjsyeeVHJIcwyF2>ko8Rp2^WVoO0Ecjj$YHa934G!3mBUsZ+j;B=H-Bn3_368GphgQ1zubeFrD3|fOQgHkh0wH z0`dmf*Yq!s`2B7v1gH@Z4-)o*!u<*Ufm_R+DD0U?w+DjxDA zUFV(MQK+RTqg!y^%NUUj>#xTmavF^5-=r<4&T^aNjdW%b)6_PJUnMQ)jHSi%u-|K| zQ;!EOr&H|n&D!{Yl8rnjZ4^+nF$G(oGH!B#>GVB*w7RMtV}l+pM^9?PU?18UY^7In zqcsn~Z77!MFgR6-xJPmA=m0689qPqWzrTnL(&Njw%oVerp&z;5tbO3pr2OtunAN>UJGoZ z?5Oyr_2z|H4NK54N69R+N?fUm8+aC96SCaSvjS$M1Rb47GxVL8vl0kv({N#AR~f2Ft6ZjZI3S;}Pa{JVrss0v0ta>3D*tI+n4*FmQSE7`pyv+}Pgd7F7^& zHClK{8)%w?+1BnhCDU9IzI#g0a{-VLs?D8Ue=mF-vYXbP=`E9lc(#-)(qM(N!;dyz zHyi|LNDF*n8{u=IMry0;&&s9B^Rr<_qLiWCcQ>n5?iJ1G`-oy%D=1(TI=y)L#X++| znrs)H3|bkjZTW9tUuYA<6|!pR96&ei^#%Y}(L<*s&FmU^HJU~i8_+8_fU^x>{wwR z|NhQ=BB&Co9EL{w5ju^c4L7N%F=Q}~8?>LmRG2nT)Eb5{ND)OQX$nvXH$+lccypMd wF}eq8jdB7_!w6%2e<+qD?$df_2_u`8$bUtuj`s6~PDct&H1jahBHJEach function is defined as a static method.

    + */ +public class Functions { + public static String reverse( String text ) { + return new StringBuilder( text ).reverse().toString(); + } + + public static int numVowels( String text ) { + String vowels = "aeiouAEIOU"; + int result = 0; + for( int i = 0; i < text.length(); i++ ) { + if( vowels.indexOf( text.charAt( i ) ) != -1 ) { + result++; + } + } + return result; + } + + public static String caps( String text ) { + return text.toUpperCase(Locale.ENGLISH); + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.class new file mode 100644 index 0000000000000000000000000000000000000000..e1f6bf3cda3ab767d28c176288445a7feebd02dc GIT binary patch literal 1898 zcma)6T~ixX7=AWcvdMNSHKAyQwxCu+C|&zuTS`DFrAiIZ8YFG~+$1~c(q(sN_k;nj z{UzRb?Tn@~cE<7AYk!S1+CFC!0wJk-ao+Qu_q-p^`*F@6|NQzJfUB@|jA2g0EgcEW zWpEnvk`#541s#j{P+oi_$&!ZK8kTjOz+4)4O68J>C(2fYne^qxaLwATKgp@67vc&WvAg;q8Zu>rU&U1+d|j!8fIC9j@Ou9 zq+M#)a+@|C|EJMLb=$6qwo%dX9I>b%nV;Swv}M1}up=eMv)7wDRXg0YsxBqjl3%mj zEh}{7xg%7?6Nm9;O50Iz#kBXVoxrstGjilEtcJN#d*Uw%Laa809c@|-!W^pmWEhZD zkbdJL9LU8!ij0_H@k( zV#pfqE6`W=YIYzT--|Rn(D0dpTx5$o`<}Jq)VgpL%;o#R{i~#dQ5G`U42d)2%Brnf zJFK8y_M2hNzU#6w_i|i0*4wLtBHY;x*k&WxFN^${Ht7b2ULxm?>G>AesZR1$B!Yu+Ihn9 zv*=EK$_fJ8V=HC{4CYab_NUNkHPQCy9}H>VBp>Rhh2M6eV6>Bf+51AZfZvXAJqfnY z(R};>tU8hQ+#W=Jj4A%6W8ir5XUxjMCjTb?-vq{a=8SjGXOSe&S3x>SjkWj;j2E6k zDLhBw(K94}fqKXe{S-TzB0WiE&`iZU7{LX+#gjotG{@VNf&2x!PQ=M@Y`l=2Z4IaxG+A z$bFwsetglAxROjAOh+S~Mj8bcVurGdq_cRya|LFM^BS>C;eEV|_h>c4Jx>c2I!jRC zIU$jDvPk1TJ+WL8XJ wv~s+F*O9>u_T^>_tk5>=gr)<0K!~!aIb0_vf#qVb$vC*myUScRC{N(#OPZ3>R{#J2 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.java new file mode 100644 index 0000000..8cdd48c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/EchoAttributesTag.java @@ -0,0 +1,57 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples.simpletag; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.DynamicAttributes; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +/** + * SimpleTag handler that echoes all its attributes + */ +public class EchoAttributesTag + extends SimpleTagSupport + implements DynamicAttributes +{ + private final ArrayList keys = new ArrayList<>(); + private final ArrayList values = new ArrayList<>(); + + @Override + public void doTag() throws JspException, IOException { + JspWriter out = getJspContext().getOut(); + for( int i = 0; i < keys.size(); i++ ) { + String key = keys.get( i ); + Object value = values.get( i ); + out.println( "
  • " + key + " = " + value + "
  • " ); + } + } + + @Override + public void setDynamicAttribute( String uri, String localName, + Object value ) + throws JspException + { + keys.add( localName ); + values.add( value ); + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.class new file mode 100644 index 0000000000000000000000000000000000000000..1b1cbc9bcb5826d59d71088e70f6a81b3601669e GIT binary patch literal 1133 zcmaJ>YflqF6g^Y=q7=j;h=5pp(Fd@liqT+5D1itzG@)yapUk!$%R?$`j;C=vi{p6$A<~Ofpu&dZOdsHRpr@EYgHgos#M;8Hn+|4roixq>-frYRLyF4 zrNB_Ix&Fa?SJ@L747}}XX;&cn)^=>QM(9koCJ^3mn~c9xwjH_KJ*rF3wCZiHq{?o? zYS%2!*8cfoSnb=sK)!t7cZ!DWSx23=^bOzEv$9&omhCi4u6tMwR!mD1jWk^vELG=* zz~q0)I=mz;N4K=uYsikW*-H#djOX=Qs5=i!?fx{Cb8jy<^H}Fw>xjvZss-{i@wg$MuxJY=7*I-?

    ;LQyh z^{dvuqIDc@NkueXBE{+g=}a~Vyw2@1f@d{zBcBU|B#&-g@vhdpif1!_JGn~zKsMBB zwuU)AfgwJWFdqeVr8R{S&b*?uLl~exdc_aZzk9`xFoKsCV;t`>!{979M{=hSUjvA7 zj?rLo78A6SX92j6NqPbgm>dd{KO#a4nEr{-r_?|yoQj+xTF#vymivZy{se=UkRz-N z%#&?~oU#G*#98_|wC-aH(=0K=$S~)J{LkVMN6mGO(YjnTm;a9VC9?iN01G6ucm*|j Qj;fo{O6fk+j0<7zFZ+)F-~a#s literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.java new file mode 100644 index 0000000..e44d4e2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/FindBookSimpleTag.java @@ -0,0 +1,46 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples.simpletag; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +import jsp2.examples.BookBean; + +/** + * SimpleTag handler that pretends to search for a book, and stores + * the result in a scoped variable. + */ +public class FindBookSimpleTag extends SimpleTagSupport { + private String var; + + private static final String BOOK_TITLE = "The Lord of the Rings"; + private static final String BOOK_AUTHOR = "J. R. R. Tolkein"; + private static final String BOOK_ISBN = "0618002251"; + + @Override + public void doTag() throws JspException { + BookBean book = new BookBean( BOOK_TITLE, BOOK_AUTHOR, BOOK_ISBN ); + getJspContext().setAttribute( this.var, book ); + } + + public void setVar( String var ) { + this.var = var; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.class new file mode 100644 index 0000000000000000000000000000000000000000..d314eb4c4bde97dc46b043d182f125fc63aef3b1 GIT binary patch literal 764 zcmb7C+fLg+5Itj(n7Vc^q1?(X^qNp$CHk0(7u2e)qVf^=)`|qU@18Nf@bjOkXBFX?5XGz>52>bHYyNG|%>g8p*RP zQMt%ZTwB@*lMRNE3Hgbx()MSE(#uDzFEFVBr=Uf*IAv$?N$$)yhT2572tu25%3wX zC)g6(>ef%tk23s_&sqttA>?~_OF)E2?D2wevR5XzOEDnY8p9i7rd}DNdM^@i7(D5a XtKSPn6QL(%84piUXVE$KJUqJr9VESs literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.java new file mode 100644 index 0000000..f87736f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/HelloWorldSimpleTag.java @@ -0,0 +1,34 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples.simpletag; + +import java.io.IOException; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +/** + * SimpleTag handler that prints "Hello, world!" + */ +public class HelloWorldSimpleTag extends SimpleTagSupport { + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().write( "Hello, world!" ); + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.class new file mode 100644 index 0000000000000000000000000000000000000000..94e5c64d2420a81af35b48382653a2c4e6336db4 GIT binary patch literal 1102 zcma)5+fEZv6kTU}85jpa5WEx-1nf|hQM?NwQ6fnVN@5AVdRmTkpq-h_oHjMS`X#>j zY@%p<@B{n^Kg1Yy&Cmd`#`tp1-n)CRwf5?nuRlM30dNg>Em)Z7M?cP6JSO`vW#Iy* zEzDpxsa&*BgkxgPL`fjyx0(W?ERbLJd{3{ifsD1F^_z9bL}3 z+*Eb6d$4Au6^22i1txlXAI9OqmI5P5gX;xudE-cRpsqCgRs&xXS76ei!#%8r9kg{Q z1!_pY?pAc<`E=N9%SKCWJQoHR%Tv}#M!?V{6*aip?Q-BC5Y zl>SNk`tJwZF9n>xitk#+9o8aQZz^9?&rGkL-aftw&u<62R5a36ME{;fo>mdrF~!Gj z@tY7Zl1IQO!I}p44nH7sEGb8 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.java new file mode 100644 index 0000000..41a9f3c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/RepeatSimpleTag.java @@ -0,0 +1,44 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples.simpletag; + +import java.io.IOException; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +/** + * SimpleTag handler that accepts a num attribute and + * invokes its body 'num' times. + */ +public class RepeatSimpleTag extends SimpleTagSupport { + private int num; + + @Override + public void doTag() throws JspException, IOException { + for (int i=0; is0l}s4BlB|U112u zRb5%iW!4mPRbJD`(iAsRvX+!hmFs1r*WOeuhG?9Q9hH=VoXKj6C0Qz$bPXx7nM?Yco5hK7VKr?wa6Y#A#sS4b&YTQzh`z_0)+PP7!eQUa-w@X3nhb+}Wh zVz){~*G;Fia@m1|kuy`uyvmDguD!x?fUk>g0>holcQ zM+njX3~3TcMzS`#2lmkkYc2-?9cZDwSPDQZ&XUG(j*>k*nW-ds^8P1y8hyK{c}EI; zKT86&B*V03X+5U(gw`usAEG<(vRyiK2fnftxGdti%jK9VAw_7FZFNWy%PvKk z33B~ss)QEN?s8SG;bd_hYQT9&Q?)=8!x+F-4B`fcaEC~{ixDJf4j<9mlEOH}O+d#a z@)Y$H*YFHec!6oW#C5#J4Bk-YTinEZ+`La?(;{s8B5tr!C`!_>25BEj;zrg#ifdR+5NG(`$z*|aDWpIwgr-S#t<7g~j zHP$j=tsH~JCyZlt9*rebW8EjL>{n3qz65J0kl#qlmGw# literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/ShuffleSimpleTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/ShuffleSimpleTag.java new file mode 100644 index 0000000..a39e508 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/ShuffleSimpleTag.java @@ -0,0 +1,87 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples.simpletag; + +import java.io.IOException; +import java.util.Random; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.JspFragment; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +/** + * SimpleTag handler that accepts takes three attributes of type + * JspFragment and invokes then in a random order. + */ +public class ShuffleSimpleTag extends SimpleTagSupport { + // No need for this to use SecureRandom + private static final Random random = new Random(); + + private JspFragment fragment1; + private JspFragment fragment2; + private JspFragment fragment3; + + @Override + public void doTag() throws JspException, IOException { + switch(random.nextInt(6)) { + case 0: + fragment1.invoke( null ); + fragment2.invoke( null ); + fragment3.invoke( null ); + break; + case 1: + fragment1.invoke( null ); + fragment3.invoke( null ); + fragment2.invoke( null ); + break; + case 2: + fragment2.invoke( null ); + fragment1.invoke( null ); + fragment3.invoke( null ); + break; + case 3: + fragment2.invoke( null ); + fragment3.invoke( null ); + fragment1.invoke( null ); + break; + case 4: + fragment3.invoke( null ); + fragment1.invoke( null ); + fragment2.invoke( null ); + break; + case 5: + fragment3.invoke( null ); + fragment2.invoke( null ); + fragment1.invoke( null ); + break; + } + } + + public void setFragment1( JspFragment fragment1 ) { + this.fragment1 = fragment1; + } + + public void setFragment2( JspFragment fragment2 ) { + this.fragment2 = fragment2; + } + + public void setFragment3( JspFragment fragment3 ) { + this.fragment3 = fragment3; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.class new file mode 100644 index 0000000000000000000000000000000000000000..2526a6bbc41fd5c328bc4678c7da12962686c206 GIT binary patch literal 1263 zcma)5YflqF6g^YgZdn)6@=|$~7Njl0NbyanMxu$Pkq;#pzqxIPcFD54*_}fFmWh@` z6Muj|%6MnH;ZaKBZZh}Iy?4$%b7tnx-=Dt$Y~hWLapZK|#)>Uvr2ghR#n;J?CiH2*tK0~^CWS*GZHk}r)N#Al>+my7;y096NWy`T- zg<&LLIADnHx=q0_UbP(YsdHQx{=QkaDUz#}#)_OOsrG5> zHMiq8#CyUgZdclDsNEWvz@&kvc&6dGffsnmFf%B_+m2;71u3*#md(tm)s*d>>{cn8 zX$z~>mVLk83T52M8hC|m19xzjA(O3?4_!xQqFnAU{3zNGjud{yKw8yJm3b5>b5&m{ zbJ?V189N%tzQ!WM%73ZHP*D84JP`f~smo~_dFo${Sw17n#741s6 xG2&TV`+?LTS`i7Xg=o_udNM*&`%+@4EoX*f>4R7sgvD>bQi3Y1C1Mmq_8(`x9FYJ3 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.java new file mode 100644 index 0000000..2d5db92 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/jsp2/examples/simpletag/TileSimpleTag.java @@ -0,0 +1,48 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 jsp2.examples.simpletag; + +import java.io.IOException; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +/** + * Displays a tile as a single cell in a table. + */ +public class TileSimpleTag extends SimpleTagSupport { + private String color; + private String label; + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().write( + "

    " + this.label + + "
    " ); + } + + public void setColor( String color ) { + this.color = color; + } + + public void setLabel( String label ) { + this.label = label; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.class new file mode 100644 index 0000000000000000000000000000000000000000..27d7bc6a3838f82c170bab14bca16bd912eda3b3 GIT binary patch literal 2225 zcmb7ETXWM!7(FYSNKr(bI0QmTX}C1DMS{w$rG$ora7!_PVwx0sUE7Nhl_ifYd!VoF zbUOVbeQpPwDa`Q513!x4TS<0ohlt5bcJ=woIcLxLcHg{x@e05h2pv;6H;e=LT*VhU z5;&*fyj;K3aRCb&F3R;QSy|L@Nv=yewJ&S9tYJmN6&+V`O~Z8!H%73EuZM9Hc^$W~ zrsB4WJ1V|WahE|Yd9E*>_zZ{hk9mtfu^OV@a)fUc!gVG5eSu-kvspjyKtc^u( zT@ekx?md;I*?5Ut%8tb<3j4^sh+&niwz*^fCOHz0S7De8nJkC96{|o-xs~9^YE?8E zyb?GsBkXHn*jw;<>DODl7A2t9@oFsHpFW+;Zof5?+ZGZp5ADqAn4kdarj+5!GzI;uLysQ zS7r9u+%`}`)2LycJI!q!;qj@XPhV8s4z;CE^Sy9f8IHtBjTDZPfd0paVJ6bLlk22v zIu5!o$HG&3f~s__ye6eN8Jb{w)*ZT1J}DKvN_Z0z&+0FeeKpzSxHv`6?GzLo#7Cgn zmbZo8Zk6_QdFbya^mU%7QVip-< zV#vlYj_#Uql^F9MV9doZrgqJ^L5vSRz-UrWn9U9HLAq*~=`k{FAe~Y291s}7LyX{2 z53131&LHRJ0_Wzts5c|jlu7xFQ{ZMg-4{m)+<*ojqiFR2r@FwY2w0I1WhD3SXb6_f zXHZ__s9ZYZFcDfMqyHcK6#Rqf|1kNUU)$I(2O|*-V46k`_?<@f590e1m+)7Qnx(Fq XC45H1&TyK#lTc=-Xn%(G3eLU*sy7jL literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.java new file mode 100644 index 0000000..31f5545 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/ContextListener.java @@ -0,0 +1,138 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 listeners; + + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextAttributeEvent; +import javax.servlet.ServletContextAttributeListener; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + + +/** + * Example listener for context-related application events, which were + * introduced in the 2.3 version of the Servlet API. This listener + * merely documents the occurrence of such events in the application log + * associated with our servlet context. + * + * @author Craig R. McClanahan + */ +public final class ContextListener + implements ServletContextAttributeListener, ServletContextListener { + + + // ----------------------------------------------------- Instance Variables + + + /** + * The servlet context with which we are associated. + */ + private ServletContext context = null; + + + // --------------------------------------------------------- Public Methods + + + /** + * Record the fact that a servlet context attribute was added. + * + * @param event The servlet context attribute event + */ + @Override + public void attributeAdded(ServletContextAttributeEvent event) { + + log("attributeAdded('" + event.getName() + "', '" + + event.getValue() + "')"); + + } + + + /** + * Record the fact that a servlet context attribute was removed. + * + * @param event The servlet context attribute event + */ + @Override + public void attributeRemoved(ServletContextAttributeEvent event) { + + log("attributeRemoved('" + event.getName() + "', '" + + event.getValue() + "')"); + + } + + + /** + * Record the fact that a servlet context attribute was replaced. + * + * @param event The servlet context attribute event + */ + @Override + public void attributeReplaced(ServletContextAttributeEvent event) { + + log("attributeReplaced('" + event.getName() + "', '" + + event.getValue() + "')"); + + } + + + /** + * Record the fact that this web application has been destroyed. + * + * @param event The servlet context event + */ + @Override + public void contextDestroyed(ServletContextEvent event) { + + log("contextDestroyed()"); + this.context = null; + + } + + + /** + * Record the fact that this web application has been initialized. + * + * @param event The servlet context event + */ + @Override + public void contextInitialized(ServletContextEvent event) { + + this.context = event.getServletContext(); + log("contextInitialized()"); + + } + + + // -------------------------------------------------------- Private Methods + + + /** + * Log a message to the servlet context application log. + * + * @param message Message to be logged + */ + private void log(String message) { + + if (context != null) + context.log("ContextListener: " + message); + else + System.out.println("ContextListener: " + message); + + } + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/SessionListener.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/listeners/SessionListener.class new file mode 100644 index 0000000000000000000000000000000000000000..d683d5d0e5f597ec0804ac5ac3ea4c6a0e2a8535 GIT binary patch literal 2863 zcmbtVTXWk)6#mvpBSlf|#7TOgX-JbMzBH|YatTe_+?tS3H!XEYDNsPR7e|RKxwagV zGQ;pphaUjL@X9j`I8&J6kq3Sh!&ynOCDn0Y`l8)EI(xov&-u>o-~asnCxEN?Qo(u5 z^!g3#0@Q#dCu~-wIcg4TkGO}X4qtM268FyvelkuK{`^d@I zknz5PO)SfJAmf8RJj92+_y`{>c!W$<7iHyOH;sZECNC9B98Vp-kf>-BP;S2wi0L6&&dDrm;0R@KGY zGj`isdX3>+*3fGn&k9y2xR^3b|DTNv{Y~Wiylm|X>;a#tVrT_n>-VyCi`VR`wJ%IlVT!@L zwU|wW7`5}G>O$q;ONPdb{1;X7KFVU-w$ zU960unWapQ>SLCiOiN`VrInn53*`hH7*6JFt*~=Pt9SxXa#p=s;48Y2$WW;ES4036 z6S%120>&9mha)c5b)(3u{z^F-NhVYj!6kgIqJ%98x{7V=kUSI9WAx9!j*2o&;bk#I z5-AlGVVl9*lx<&)ow6qr41+$STX$6Ap5J9#QcQ?Py3xs!3n2ze}!|tPA3%Z4M zvT)d%tsPUHceEUPv`U4Wq}$8wwB!iXuO6?~bRncWBlx?YK`C+D%Ob;gGIfmbDg0>X z@N}C{$Ti|UQyQS5w z%ssj`Y&s9u%7i*7;$?zn%4S74875w(ckMhqaHDt`W1yxLcLF__y)>sQg1(cqnjt%* zQAr;9)O0*fDGe1gN@W7_=s^K};J&D8Gq)<` z_BAKBSDR69dr@O)D(N6;Bpn|L6wD1=fsDt9qUH-6YX*)r1HX*FgD@z*}6$tKh!LA~jm;jIo(r~fqo-aL4=h(E9>cn}Z1U|WN>F1yg(3VzLl5Aac9dh=pJCQO(a z^8P$u0M-~QD2131pIlQHyekb8lFcJ<<{BHgURL_936rfYjPs?v95`IvSz$z&S!Z+O zikqC%AJ1Y%0Aakhmg~%D@7YUgo0J+Y+GAdE5eU;i0m)qK9r>`Wt~7*2=*f=I7aYpO JqM?>0gD+BNGHn0= literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter$CounterListener.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter$CounterListener.class new file mode 100644 index 0000000000000000000000000000000000000000..3c5b2cf9a806807f789f69be13fdaf292aa8f78d GIT binary patch literal 2741 zcmcIm+g1~26#o7sFd>eDU`4@dJX9foctC3fZ2_glqFBKLP^&{S!a$fwGZO@BtMydZ zYG1&M_Nr_3x?K`i533K*2j~;@F}iBM{U?%x=;}=`vj4;0|K8s|PX74km)`*##^V@T zFcL#6&em~vPROW`^FlrnazV&g4CA;M!zEmn-4!7da^$WBlLn?@sK?nTK9=>WkWZqx zChPS&SeT9>iIhCB*Wm_c3^)en49puyD}=11!nTn)YtdTj_U-Iq+77z={be^f=(&Nt z6!a>DeaBbWRV6f55FU0jxnL~F+SY;=^(eY~ZPC$OP%dloO=`$-9e>tNDX2+>4S^R} z>4D|I_Aijh%QFhK)43Zr>@2ZP4e->*7r{w|R9lsm3e;7+HNdVdQGv1jl0szAOW6wb zBaUmI%PmaX*>P(+&6~y%FKMMOSy@NU#mh)AE3v8{^m2?|cEs@m+ZF8Qu*-EYZTY@U zf%XyCbEnf@a^7)gy2at*i#=5@8Pj^tJ!J(}|Dxrj3#P+u8kxk8AsSX#KNeWY`LkB0 z2qSiSDQRZ{$8&uH3*>ule>yE%3Sp(n%ULI|&wIY_Xm7#`{*3q}h0vY02#Pr+Hrh8l z_jESv(TOdEkQeylvsv$^;OP}Gb-|0H!W(5;N>T<~1t{G4|MT|B;2zXiLrVu(OiKra z91?O^q4hOy6k=muE}OK697%jbS-SR1yi6p}A*9E|9=v5@FZP*eL%WIX*kK}$ohEi+ zw*k*Y2A>+pn(z^r$YIgM5!^JgW&ToODXcr+Hi&BR(yi5x>dQv8>`J;!`G; zuq@;j3*oAX&v4to=O(_u9Rqhwe2IG|?&E=hhbA7O$G}$#`~G9?(bW>5(djum87Q>K zRcTa6J(a4wwUVi8ti)~7+8nQYcyzTs6}G+#4f7MP)c0~1vpak{s06X2y1>fWx&U^r zskXfJ={ogR;g44zBe+ zG4E`?ZEa^>$BqVG;f2DcwwDE|K>OP5GU~}$D@&)?*p{2JvZ=wsnbWA|;`q?DW6W&< zNV#xPh>FT;;f2ZQj2-AZp8pD@2ptLWW-=$~V8F zJlIt&{C0-04R4|rjnZoTt~N@y>6Hz~bwD~&uWU-LA?Zu5wcN35IgdJd`W9hCxE@SA zLnskmK{!#jf=FUx9KS_ZP?P9bL2aUQ1xBK41<}q#9(7$Lu^+X{F46>Iq?f7Y0_re^ z4g5?u;|k$T5YQxN!Zn(^jsyH8@7MC$Ai8mgCz{p{D7_OGLV71ogbDI6dUzvHAEHL{ z4uty>PhsS-?g{p`hQ7y6Ir3MNhuPQq-SfW^6HgIoeQ42 z=+&duaO`F(`*1?z>#f9hyaL}zyh|a$H^5c!#VX8&bOvIY^EK<_n^hB(EGm}Wd+3L1 zkg7UW)HlhX3CL)oqqFN7RH^c6HLMY>siz>bsws-oYzs+A6hpzz>4@njkRJ5m^KAU0zLh>geh#h&c@w|2R`*T z^r!TT9_%^(0Dn|ZpV{mQAsX2ab7$||muH@P?|k_0-FpCw*tRi-yLl{(;2sw9xNqbG zvpme>k&PvMJA%h3TXtUaZ7yr3 z`WubtsO0U_s??5IppsYG+^9E77a0 z1jYwA3S9qu@!3NITqhSka!wnjTN!~1Cc5i~Zgrzad-L--x7Z7&lLSU%sgsf^-8gDd zajDZGZs4(>>pCK9Nxxk*h6i5cH92!Dsu}L_MBv=M)W1ePb);Z=Cg})+W|NNT0c+X? z*`pS)TE-|)0#j$fP0GcxbB-gO^cks1)1Ay!UjvR3TUE8%n%9utOM%IcJW@V;tcZ4u zej9Dw<2W_QvDb{AfAx>oDMWqa@`>D^wm6k!;3O@uO!x|;d~D5Yc@-CNiSjc4G8jje zdyWp*Yt$@K@=?Xm?Y9vBBqkGFZJGj8$Z;sXcFNYEnWRd{CQ)a1~m@Q_G zk6|H@lBF*0+Ym%!A<%N zQ{KWfW6X5(|4prV%H96_caCvRVEtd%zs+$!A`Bvjw|$HAk8>xGE+_7f2x*Cs%4BGn z;3^5M`<>8TSZ)`Vo5C8$7r2c(gg;NXv%FgF6x0m$hIbc5$|83KRtAMUDIUcI*#85k C>DuW4 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter.java new file mode 100644 index 0000000..3923780 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/ByteCounter.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 nonblocking; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * This doesn't do anything particularly useful - it just counts the total + * number of bytes in a request body while demonstrating how to perform + * non-blocking reads. + */ +public class ByteCounter extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/plain"); + resp.setCharacterEncoding("UTF-8"); + + resp.getWriter().println("Try again using a POST request."); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/plain"); + resp.setCharacterEncoding("UTF-8"); + + // Non-blocking IO requires async + AsyncContext ac = req.startAsync(); + + // Use a single listener for read and write. Listeners often need to + // share state to coordinate reads and writes and this is much easier as + // a single object. + @SuppressWarnings("unused") + CounterListener listener = new CounterListener( + ac, req.getInputStream(), resp.getOutputStream()); + } + + + /** + * Keep in mind that each call may well be on a different thread to the + * previous call. Ensure that changes in values will be visible across + * threads. There should only ever be one container thread at a time calling + * the listener. + */ + private static class CounterListener implements ReadListener, WriteListener { + + private final AsyncContext ac; + private final ServletInputStream sis; + private final ServletOutputStream sos; + + private volatile boolean readFinished = false; + private volatile long totalBytesRead = 0; + private byte[] buffer = new byte[8192]; + + private CounterListener(AsyncContext ac, ServletInputStream sis, + ServletOutputStream sos) { + this.ac = ac; + this.sis = sis; + this.sos = sos; + + // In Tomcat, the order the listeners are set controls the order + // that the first calls are made. In this case, the read listener + // will be called before the write listener. + sis.setReadListener(this); + sos.setWriteListener(this); + } + + @Override + public void onDataAvailable() throws IOException { + int read = 0; + // Loop as long as there is data to read. If isReady() returns false + // the socket will be added to the poller and onDataAvailable() will + // be called again as soon as there is more data to read. + while (sis.isReady() && read > -1) { + read = sis.read(buffer); + if (read > 0) { + totalBytesRead += read; + } + } + } + + @Override + public void onAllDataRead() throws IOException { + readFinished = true; + + // If sos is not ready to write data, the call to isReady() will + // register the socket with the poller which will trigger a call to + // onWritePossible() when the socket is ready to have data written + // to it. + if (sos.isReady()) { + onWritePossible(); + } + } + + @Override + public void onWritePossible() throws IOException { + if (readFinished) { + // Must be ready to write data if onWritePossible was called + String msg = "Total bytes written = [" + totalBytesRead + "]"; + sos.write(msg.getBytes(StandardCharsets.UTF_8)); + ac.complete(); + } + } + + @Override + public void onError(Throwable throwable) { + // Should probably log the throwable + ac.complete(); + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e63768e5af2f348756284ace0b92f47c4dd1665c GIT binary patch literal 211 zcmZ`zF%H5o3_L?2P%2S2#Kgc%g?Iu2i2)cGn9~qJOGu=o<#7x=fJY(RjRjji>#Vzz z-=F6Tz!Hgo5Qqu!(bZn*O<^=)w6E{E_9tId+Rsb*kc8pdD&s<7FFRdb-C1Bjm{@0X zIWC%JC(k3c1lEsI-)T$zk|0SeT_P6-SrrO+K7NNsCLYJ}6 K6SIaImiE3xl{3Zw literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter$NumberWriterListener.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter$NumberWriterListener.class new file mode 100644 index 0000000000000000000000000000000000000000..43beb948b391534d057aeaae3ac42c96450831ce GIT binary patch literal 3075 zcmcIm*;5>K5dLNtm}N4`kyA+G=7tTpA%`YHR3L|2At45W0xAx(15C0zLuO`ycqSe( z@lHJRVp&$IeAW^YjmMi0{vG}kR(X9ryRZX7l`j_XJNwuDb@$gj{QB4TKLOZ>&opdC zpN945S8-ND90S!nc~XX_WEhlTNQPkN1$R##k7hU1(iLSlbL=6N=Csw-LB&Yh7$}J zxq=l3cGW6~8K#1bJ?D%mV?ZV;=b)G*t$fhuPB^xCJRAd z;8{jK6m==OZF$k&LJ*ZzO}9W3o`T(>e7X?WxwPpzX2J6;CrBHCo43t$XE`J`tv1UdL9P?)+xe5YOCw?mKOd4F8|627E!1~D=9ghs=PO}dGZ ziwacNIqG>X{n=1VK~c7U!gHquRJ$Om4(7KC)Ye3o9)cKFL;P5NPFi`Cb4Jcf21Z{UiKH*rNlVn^HdJ$v_LH3hY0LiCQFvrP7& zt2(aXEfsI;cn9yQcu&Xs_&~>X+|cnMK2q_qj!)38;!_2!D@HOJw|SZ?Xb^klh9z_@ zUp6kj3@Kc`ZCKG1lUvc05o#tEYxs9-V4e9^u-NSVOIaGd4oS3SS+&uA!bno@62!@+ ziWl97npN8uYb+O5I~!tU({NWad;Z#J`ISml9E^`!K`2X^8rv~FE6=odI@#lLUMDz< zC0lB{Ea@rvYV?jNSjQMe%C+2>BP1xAVk;hVy}Ut{hn4{{9MMu_O?y=FLT3rXmUhTm zbHeZ#A2uDs$r@g^ySQiTsyy3&Y~&z`QPdd~E(x*B67;(3Vjzuma|zFKg3a;~shpP1 zT#6(kwuEufF9{W!Zhn$qPRegsiC#$ZOTHd4+|QMY25iAr_O@;O*CB@OsFxzMpE`$oI~qU#`?tHO8LY3pjk=!&WgLRCf&K#~HH@PU6W9cs@jS=Am=95{E9x$x ziqU#U812J+r6TqRVoDPp;iiJ1YWVl)0neW4`oVbP9c<{kgZoYiwAOFXFo(uDY?K{=9{%d@U*z!@(0P*h4x1E| zQSXILb1yRluMqVmhVC*p;#Jb`HKKnV-R$lsaD{2V%2Z#&vuxe-Nj`ve=p+r}eA!D$ zA#WW{;s|Lei5!XeybAF@QKu*!zf(9G=A$^qXX1MoXL+VAf*A|5tA#h$QH>j+`C>M; z1&(Prj>ncAqE-n`>FyS7{SVmbRpHLr|7Y|mYhN?;?E|7;$cCk6=~+fo?^ zN)?S&4x44ehCC`sUuEjL`9;1(W&*kmo;(s5t{YOmna}g2UlgcMrGg<4F$)5HR{$3L zQ>Va;DtV&##JGKtexqh82CDP&uU-sJES(f&QL$LQhKz<;nl{~%SCGqAkoflMxbYx` zI=awJuK?XB+NR}bc&lR$^UU`4)^d7U$2-hxSkUnvS%Gw|^4!Qt$0C+=EMp}AS{3N2 z6)w6DsZq?V6__~zh2e*CH-Dudjs~(9+yCB%YK3x#$z>P~(Yd@iVN^>0-7(2%uqMacz6a5d>6^4%^ z4g+m$$K9A_KhA`(Q{}5Gumr(FJPN58eBl#P=q8D$7(fGKsGpGXFzGb%EQJw{quh}V TS~(}VYG!887H7L}B3|Mz;Bd1D literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter.java new file mode 100644 index 0000000..d7a6680 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/nonblocking/NumberWriter.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 nonblocking; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * This doesn't do anything particularly useful - it just writes a series of + * numbers to the response body while demonstrating how to perform non-blocking + * writes. + */ +public class NumberWriter extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/plain"); + resp.setCharacterEncoding("UTF-8"); + + // Non-blocking IO requires async + AsyncContext ac = req.startAsync(); + + // Use a single listener for read and write. Listeners often need to + // share state to coordinate reads and writes and this is much easier as + // a single object. + @SuppressWarnings("unused") + NumberWriterListener listener = new NumberWriterListener( + ac, req.getInputStream(), resp.getOutputStream()); + + } + + + /** + * Keep in mind that each call may well be on a different thread to the + * previous call. Ensure that changes in values will be visible across + * threads. There should only ever be one container thread at a time calling + * the listener. + */ + private static class NumberWriterListener implements ReadListener, + WriteListener { + + private static final int LIMIT = 10000; + + private final AsyncContext ac; + private final ServletInputStream sis; + private final ServletOutputStream sos; + private final AtomicInteger counter = new AtomicInteger(0); + + private volatile boolean readFinished = false; + private byte[] buffer = new byte[8192]; + + private NumberWriterListener(AsyncContext ac, ServletInputStream sis, + ServletOutputStream sos) { + this.ac = ac; + this.sis = sis; + this.sos = sos; + + // In Tomcat, the order the listeners are set controls the order + // that the first calls are made. In this case, the read listener + // will be called before the write listener. + sis.setReadListener(this); + sos.setWriteListener(this); + } + + @Override + public void onDataAvailable() throws IOException { + + // There should be no data to read + + int read = 0; + // Loop as long as there is data to read. If isReady() returns false + // the socket will be added to the poller and onDataAvailable() will + // be called again as soon as there is more data to read. + while (sis.isReady() && read > -1) { + read = sis.read(buffer); + if (read > 0) { + throw new IOException("Data was present in input stream"); + } + } + } + + @Override + public void onAllDataRead() throws IOException { + readFinished = true; + + // If sos is not ready to write data, the call to isReady() will + // register the socket with the poller which will trigger a call to + // onWritePossible() when the socket is ready to have data written + // to it. + if (sos.isReady()) { + onWritePossible(); + } + } + + @Override + public void onWritePossible() throws IOException { + if (readFinished) { + int i = counter.get(); + boolean ready = true; + while (i < LIMIT && ready) { + i = counter.incrementAndGet(); + String msg = String.format("%1$020d\n", Integer.valueOf(i)); + sos.write(msg.getBytes(StandardCharsets.UTF_8)); + ready = sos.isReady(); + } + + if (i == LIMIT) { + ac.complete(); + } + } + } + + @Override + public void onError(Throwable throwable) { + // Should probably log the throwable + ac.complete(); + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/num/NumberGuessBean.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/num/NumberGuessBean.class new file mode 100644 index 0000000000000000000000000000000000000000..75208b71a08080d28f2036ee9a3f3d0ebd6c2cd9 GIT binary patch literal 2153 zcmZ`)ZBrXn6n=I|c0r&pFR-{`&WiKLK1vIf`+lb*x39 zBHfR3xEJM+5vz3_UqzuK9YI#i8^X9LR$F3qUkneT*hWsrP6WFV>_zZU06mIg9|tFma3NbKf$Cyt2b6 zV_8N|`PXF<%eLhbyT4?6ODzI~Cx!k-#}Z0rL`0pJ?nz>!$=P1ibo%%g#*%NJ3y2tR zFnXJRjF7>7l>6M9k}we#B}$jJDU>`AFcI1$2J2ShL)J5afIh!;wSHuIcb^sPn#UHB zWw<2j&Mb1CRrr3xs>$L|3OuUY#ALKwwOKFNX-8CYw5w28L^}<9ge3JLTN~(*flK(% zzzUKECNZU8yu10!O{Y>65`lql@x;J1W(*wSx`7LrGH?+e=pcR`1qD+b@1AtnXKUJ( zeV=yiXWq2u95H3B?3BtPMz~U?91Rqa(qS9;4lL9N9lE>!hKf|_R{p77U>Qbbbf=oi z$+y7y$(NR9)oQj|RB*Xhe*+!x)!rh^%16AaZ&EPaA(nAHyCjm0)U0~L=9UWWg-ku_ zf~33=?*MFAUYYNMm1k3hNHdt>8$J#N??A(Qc$bfY^L#^9Oz>e}Va1VS7yalD8@qKpt>juylB z#mBhJoq{V!wQ$8OaKq*cXuopd18LG|2Asof=d1Xn<-Ew-Dt$Eb{0X#98sbw11_?8a z2!GDM)k5HXSppIG8b75z!6n`iiHyI7PHvGz|0$wOYJk%zjNf<^Ozm1AwefapH}L6O zsm+~WpgXmjOzqYgsfn(L)Nb~s8SBQHC)VvVutaAC)~%lPj&;|2F+i$Q@6Yf#A%qBm z&5CzBFZXnwXKudp|C$x=W|1a~wKG@B-R3(q0&>u zBEI0B>9-Y`! answer) { + hint = "lower"; + } + } + + public void reset() { + answer = Math.abs(random.nextInt() % 100) + 1; + success = false; + numGuesses = 0; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.class new file mode 100644 index 0000000000000000000000000000000000000000..8caf0ad1f323b53abe5aef4b4d8e350b1ef699b6 GIT binary patch literal 1566 zcmaJ>+foxj5IvK7HcP;S;9XEuLJ*=NAQvObMbUVTg{3|%VGCE2UEJMJrBD8bU*M}& zDO73cqYr+R<(cdd!bM+tr+d0jpFT6QzyEyu31Adu4Ov`@5i;aj!hvRU;VcUmA> zvDR$EZ@8ww`F#m9L8NBbYsHH1TK3v>iA6E5u~N7E7G(RrK*aLRI+JEB+ww~S;r!q- zqjSzGdvum9+q~bXubA!=W2MGOrtDOW+OpwV(pSNV|I+dVy33yFd6r{)#ra0P{&voA zefEzVtE)@RCb|56hRtraQ75+MnssNx407Y1=?AMMR~0paV4K8Ru)}38Kloxlq(Jt- zXnNgss$}@seA6&J3er*Wjq2-r#=4p#>YD6DA{D3MR?S6APMmJdG9phz$8nqx=-PWa zI=Ye5aRf(o9Ft}a^Ewu=sN)uHZx^&_uVV>!s5jNoaaZP@K|c>75JAT|^y?Ury)ye{ z-G%pH+#3PhXW9>t_RN$(*mgxo7^K@`3t^lS^^ zuZR@HS45?WedcZmr)V>X(B^1+&`IQOBKI<)2MFjR3zaEvPx5MiKlzu|GdGHGR?D(K hpO_lmT{0l2338DZ1 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.java new file mode 100644 index 0000000..bad0cb9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/sessions/DummyCart.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 sessions; + +import java.util.Vector; + +public class DummyCart { + final Vector v = new Vector<>(); + String submit = null; + String item = null; + + private void addItem(String name) { + v.addElement(name); + } + + private void removeItem(String name) { + v.removeElement(name); + } + + public void setItem(String name) { + item = name; + } + + public void setSubmit(String s) { + submit = s; + } + + public String[] getItems() { + String[] s = new String[v.size()]; + v.copyInto(s); + return s; + } + + public void processRequest() { + // null value for submit - user hit enter instead of clicking on + // "add" or "remove" + if (submit == null || submit.equals("add")) + addItem(item); + else if (submit.equals("remove")) + removeItem(item); + + // reset at the end of the request + reset(); + } + + // reset + private void reset() { + submit = null; + item = null; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/CookieFilter.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/CookieFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..f1278ab2ec1d78a3822f1f6a3a29623992fe7765 GIT binary patch literal 1942 zcma)6TUQ%Z7~LnCWRfu4(gJd^VwE<8n^j6{11%-of+3)xAk=Cn$p8ak1~Ze|OM20M8iW@R?f`%&OYDSdw<`Y-`@QE3xH2xCD4yq6>|yP z#k~YVm{)N>hJ^$o$jV_+2AAa9asuyQMNU`ckds^1E*pT7P7(SQJ zFJdUF*i!L8AhEHq{Ggb(y<&X3BXGRNO<;5xA7EyJmGN zYum@Bv20ddqsEh>``(+t?Nlp~*2rjUNI)xlIadw6V$=lUj^Q|_ZRIKgA*UqJ-?C|; zZdQrq`60&@81w-iKi`8b``EC|?>$Il->gZL*rPE;S1%v0>!+SJmW+j>G+#tPKQTPR zHg%IcBBpg(m-|fqb9Bw(I>S$VPuJc`a0~U!g%%`y3nT-9Hh&V-E>X1WwX$@aOWn=( zPs++`co$a$`u^Vqfki5|HSFL^3EQQW9_%8cs4*i!dm0|%D-DnEwT5r-Si=pB$SF@M z$!QrC4F>kPVNSz`xTWGi!y!x!M>uA89tHI?iL2s-^?hiU_Ulerca6#;YG~;rfv$7< z8>J(oOxv46eofhIRl_=P54|>)1xe*(H(!6NLP%u$q3*2PHN)!;wlu#6_C!=aJvA&g z+fXXoTAcG%i(AH1*V`&^In|0}H%?qYr4@LdGUnRpDtTOT`H{PbH&wvuZE^o?r3xEy#1X~%jyon*8;-Lmb0WrZQZcSMrL#m@ALNR=dCC(z~3OBL!5=s2ZbYBm67+nTa*36XC!?F z@zR3~bCj1LaGl^$rUEn{gsb>~vpCyrBuMZ(F%iaAUn8`eZXkRHW&JfGyXj=~3~E7{ zQ6?IQJ;O+k@(l6tjPe|b@vck*@ttw5B*uP1TLaq8^S}NWZ=n4JbA>U?@fyzoCV2M8 zq&-a;H_2s&@mmQSG#ONKyL&*FMEyS)|q-%K$zbmL9V^WJ+N-#I@|zn%b?!*T!@5Dh@Vq|IUy;sJP& zkdd@yO2(9oX&GtTx@of+39}OB1bmCSsas0|?pS<7z>}-)Xaao&-P9g8E8ALqUEMb5 z2^XqG)!0z$x^161Jyuz72=o`4mTsgUt*;gy>V~D&vy8jzXaY*Cu&2IM(}rr6(rZ>- zH%r-gw@X0iq`ZJs(Haf4-@c2Cb2h@v1GgBPW97v)*$*2l8_1F7UqMvjRk?>^W~gnu;1Pxc8XzT zgSZQ}?@>w?g;!B4H5(1(MYGzzTnyqKhBw-`l)@I+C^Rg4ksar%eg_nl%~!ZisKBID%4X0#vc*$ B;6MNX literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/HTMLFilter.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/HTMLFilter.java new file mode 100644 index 0000000..a0f7dec --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/util/HTMLFilter.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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 util; + +/** + * HTML filter utility. + * + * @author Craig R. McClanahan + * @author Tim Tye + */ +public final class HTMLFilter { + + + /** + * Filter the specified message string for characters that are sensitive + * in HTML. This avoids potential attacks caused by including JavaScript + * codes in the request URL that is often reported in error messages. + * + * @param message The message string to be filtered + */ + public static String filter(String message) { + + if (message == null) + return (null); + + char content[] = new char[message.length()]; + message.getChars(0, message.length(), content, 0); + StringBuilder result = new StringBuilder(content.length + 50); + for (int i = 0; i < content.length; i++) { + switch (content[i]) { + case '<': + result.append("<"); + break; + case '>': + result.append(">"); + break; + case '&': + result.append("&"); + break; + case '"': + result.append("""); + break; + default: + result.append(content[i]); + } + } + return (result.toString()); + + } + + +} + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/validators/DebugValidator.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/validators/DebugValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..13d269c85413c37eefaec11e467f2ae273a55188 GIT binary patch literal 1539 zcma)6*-{fh6g{0}GBFN_ArTQ5a7~0bE{Fmm3WP-iqCqUn@}U#PI2w|v$%KO6@Y#1> z)rVN6Repe9;zwBO=^=!$RXNG@y?y6)pL3V)pMSpn0B{R0qKLsfg6p`U<7N~=m=WAk zaxjA15ezByP84@B9K{Gmqqv7LHNCH6T*(I!Jk&9vV^Sb|&o0~EeSu&ywJZ>ttgKi9 z$Fg?WTBxn&Eq6)gOSHtYm4YlSOV?KOhB4&5wW|U>*)>_RSEN^QtLBuIuN9ZK=c59V z#z$_lmdw7BYtk&qa?#9ru3avU9%5NHtCqV~vOM!$)iFI;wAMXykzz`Eay0eIUv{8V z1KX~Y=dEg$E65>Gcq<_0_>x6p3(~Hbb5Ans1jQ0`i=^O@>65&wCkvcoHj-w-??ob`Zke1LsBD{$> z*CwL>^(DzZ@3uitVienuSi^<2a2o(D*%wvp7eMfi!|tS}${^GV>besRexP w0xr@!%}e_dE+a%_DES*{9m(Hl7k_aSnvRr?tNy>Ab_g8$CATALINA_HOME/logs/catalina.out). To utilize it, simply + * include a taglib directive for this tag library at the top + * of your JSP page. + * + * @author Craig McClanahan + */ +public class DebugValidator extends TagLibraryValidator { + + + // ----------------------------------------------------- Instance Variables + + + // --------------------------------------------------------- Public Methods + + + /** + * Validate a JSP page. This will get invoked once per directive in the + * JSP page. This method will return null if the page is + * valid; otherwise the method should return an array of + * ValidationMessage objects. An array of length zero is + * also interpreted as no errors. + * + * @param prefix The value of the prefix argument in this directive + * @param uri The value of the URI argument in this directive + * @param page The page data for this page + */ + @Override + public ValidationMessage[] validate(String prefix, String uri, + PageData page) { + + System.out.println("---------- Prefix=" + prefix + " URI=" + uri + + "----------"); + + InputStream is = page.getInputStream(); + while (true) { + try { + int ch = is.read(); + if (ch < 0) + break; + System.out.print((char) ch); + } catch (IOException e) { + break; + } + } + System.out.println(); + System.out.println("-----------------------------------------------"); + return (null); + + } + + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/ExamplesConfig.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/ExamplesConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..e4fde9900e294b48bc8d663c6d32493e30c26f76 GIT binary patch literal 2382 zcmb7GYf~Fl7=BI?*bo+J184!OXaTvElu|DxDKzC`(Lm8uuy{S$Y?Fnso7vs8*f0K$ z{sO=17b-gAIO8|J`VagWj<;ubbJ?WrD6=!?@}BqhJnwr>^6TF}`~+YTl>~KEXk9QNejmOy2*q+r_)kbD3?KYWUTajidwOWymlbQ7;$Ei@}^(52F z`~;St1-Y24IWPAm98Aorgf`MS?!BGn$(i=4oFBC;Q}GI z`t7!K%1lyVwACoOR<=^>92%UlwkkeEo?4-P^3-;0t7OZgBk3BNf{#>ujC(5f@rjC0 zJ^hK6*P<;S7A$EOQ)`V?!#}AE`E4qy_za(uClz1dOBE6Y-W5Of7IYOFiVAcU_faAP z&3N+)$|?*T2wZ3iJ8rMQxt6;-g#%q95k67RZL@5(S}`=jwannM3-qneDO2&AThKK-8_Xc?77+Qp6f<>GT!cM-gs z4fd$1l%=z+AG17s#`pP*oBn37p&#awUBHXK!?#J6h<&I{r!J<;;1c+TOkj4PKe=>=_D+*D%N*M6$tO$0%psS&qZpr8o=DT{BN0 zzT+Z-5suxy@FGUJRs#jRjEmd}ynaNH+(wxEj`8j=p&2|TtXZZOnj2xEUsb>Ygq6z8VjPfA6X@Zf&)&u>p*T4IiAW|!fglp7pZ z_}%m|U1PvYWObG}WBmJZ1(z}J6 getEndpointConfigs( + Set> scanned) { + + Set result = new HashSet<>(); + + if (scanned.contains(EchoEndpoint.class)) { + result.add(ServerEndpointConfig.Builder.create( + EchoEndpoint.class, + "/websocket/echoProgrammatic").build()); + } + + if (scanned.contains(DrawboardEndpoint.class)) { + result.add(ServerEndpointConfig.Builder.create( + DrawboardEndpoint.class, + "/websocket/drawboard").build()); + } + + return result; + } + + + @Override + public Set> getAnnotatedEndpointClasses(Set> scanned) { + // Deploy all WebSocket endpoints defined by annotations in the examples + // web application. Filter out all others to avoid issues when running + // tests on Gump + Set> results = new HashSet<>(); + for (Class clazz : scanned) { + if (clazz.getPackage().getName().startsWith("websocket.")) { + results.add(clazz); + } + } + return results; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..0dda34fe1ddddaaa6f5b6f41d952b13bc87a5e72 GIT binary patch literal 3723 zcma)9`CA*;6+KT2BgEKBq;eRKEL8-}=9+Wgl4sQLQUJ#R)rlC9eHXU&^;-(AjK-|)}>y!Hlw_u=nx zBv4ea7)J=j7)-e?wW15larB}jw=42tNt!JmtMc)QHaKu&@D!9|Sc~H#*5jmaNctyZ z_*4v^mP9L#&)``p@!1$Y7speu+VC8nmu#PJ!x!*H`S_B8FSp?<_-Y$oz>5mL7Q@#i z+czZfn=yPVj+gMVf^SPquPAsmjx>q_;gZegLpj?iX0%mJUoTb7}Frfp>l zu0VevRQAkLhDUnYaSY4LXr8@d>Y3yIlC?aeXgJi?R+FY|qE0q%csy^-n?+0W$__2P zyYcjB?xL~a+WNBLW%NbO%Z%}H+_G#>lVFBNC?2y+ec94hD6P1L>yj?e?(134)Wq|_ z5d~U~nwIH}FkroXvjUMZyFl4Q&a{lF^2&nY%xDWGQj$4a*GjXRW6FJn81WWOdeLuXZXBA79svRhdIq!FQVD_bt#^>w;rz1zmHgPcTpwou-}1PVcB8 zUyEKcS%v~3vs++qVA-$HEPZ2f%3=(!xQxTDyr=2QliI4ERR!Nw@I7`N+m~qAaSYl~ zY75FFp0~@6ZcLc6DE2f~;9=Q40*CI1mTNd`hLg$r%eYlowM|PFdvq;msYG3A%F0$T z1Rg(ddpC}j%~HW&pra?shD)~Z;|D6Jf?Dx9Z~Qz z6+g!>n5uND$K`*4`)azU7na!0Y|TZ@O)U|cQ8>&HsQ4v*r6P~4ieF3N`{jATbSoW9 zE{3_s9il!3zfo}szg01SL5>v}mz1Bfp_GE(srWtqpyH4C6Qir*&-jaqzv43IQ>`VX z-?w$Nf-5SnVpGAEifv>Wa36JJvIPd}%}r=bO(EskDVNQVs&tgx2Nj{>HHqb>4Df#G z(Sl)EjczIUn~K-*hCrWh@BbNXGG%WH^fnb3vsX8!t<#R_8OI$*+u*3H`r^;poo3*i zsVS%yYD2PuvCP10t895T`(S;~Rfcw7U84o0O6Ab!MA6{TEMzU+F;@Hz;pAgzJA1Qt z6N`Cv)%4!pI~l2XR}H!EUsx*;Uc-x8Cr z5N|MB1kW!LUitOm^)V0k-Qyc3!ouYR^YGn~;vhe?68x}h!2vm>_;vt?kpXS;J%kAN zoTNUTGn4f9`}7YWDW|Fb&VkBR;Th*MpGUdNBg{A8VEP6``X)kiHxN!nHW9somQ5&| zh;5?vI^vgo6(8nvH$^~W5t>VJK#y>z21;-YAK^~mI7SId8dyiv=TE2mucPe>)buuX zg>X8#JNh~jbK&$g#Pf5Jc}ebg!~rUI=Mi{NLY zbWe~ciZMDI!bi!~LdrN-feFe6hzxRsNb3o}>}djKuLP6pZvc~|!=Phvx|X8yZYq{Q z_6N!;KvEU+V#oXm-~8jqR?J@@hYVmUxvwDt{hQdog$J61Aqe;r=)feaV5-jj)QzyFK#eC5%lGdh%U^+vpC1ng+HZlNiYK2;St;p-8p9 zNcHRMQ5o2wNPC1yy>#ov%S4)D5g#F%BP<=ccCti9@Casb4)a{YkmWw&_uW~ZK0}Ff zjP1wCw?z7RMt`2s)+nL#JR7T z;k@`4I^Ln~7!g+c{TQvve_eafwS_}hWexPsg>RtmDq3zL&GzrV3RNaw`0fYAcZdMf i*o%IOFYqixhh=}Yk*mO;;nMr-B*eLS0XJ~1rS-pcmX;>~ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java new file mode 100644 index 0000000..d1d5523 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.chat; + +import java.io.IOException; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + +import util.HTMLFilter; + +@ServerEndpoint(value = "/websocket/chat") +public class ChatAnnotation { + + private static final Log log = LogFactory.getLog(ChatAnnotation.class); + + private static final String GUEST_PREFIX = "Guest"; + private static final AtomicInteger connectionIds = new AtomicInteger(0); + private static final Set connections = + new CopyOnWriteArraySet<>(); + + private final String nickname; + private Session session; + + public ChatAnnotation() { + nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); + } + + + @OnOpen + public void start(Session session) { + this.session = session; + connections.add(this); + String message = String.format("* %s %s", nickname, "has joined."); + broadcast(message); + } + + + @OnClose + public void end() { + connections.remove(this); + String message = String.format("* %s %s", + nickname, "has disconnected."); + broadcast(message); + } + + + @OnMessage + public void incoming(String message) { + // Never trust the client + String filteredMessage = String.format("%s: %s", + nickname, HTMLFilter.filter(message.toString())); + broadcast(filteredMessage); + } + + + + + @OnError + public void onError(Throwable t) throws Throwable { + log.error("Chat Error: " + t.toString(), t); + } + + + private static void broadcast(String msg) { + for (ChatAnnotation client : connections) { + try { + synchronized (client) { + client.session.getBasicRemote().sendText(msg); + } + } catch (IOException e) { + log.debug("Chat Error: Failed to send message to client", e); + connections.remove(client); + try { + client.session.close(); + } catch (IOException e1) { + // Ignore + } + String message = String.format("* %s %s", + client.nickname, "has been disconnected."); + broadcast(message); + } + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ba7103a88464740b683706d386ec028643cef34d GIT binary patch literal 1774 zcmcIlTTc@~6#j-57MBI8Ab3GUtx5sea#z6%A}Y{=3WD9e00uBJtp=q`Tyq{EQ{JsK_$gE<+Jl!;WdY!gA)4+@E*T3QlU+f*K9A7*udd!w^nu z7{(a|XEmI|AVZDZs#~r;GBJF^l!i+n9vccp%hnR@V2A{uY{Qw;CsNnANxj)wh^=#mleW2+uOiqmHSf90*^{#4 z_gScw&9b383Wd#|hp;6k#sbe-;@vP!>S8n=r(@n%{P-4Vtq?>k^}qhtguxO+sq7u~ zG@qzLChGo+MEa6%**e{m1)fe=Lf*65fWV*Z42mU&GmHMs;237y>y)jwIToPRH?U0s z@*uh-h|5Jm{PSgqjjreE?CfM{Dw=0>qks4R#6{;KUw=>hkGN)IvuL8nG(wNhX0S*^ zUO9SWOX#b`R>jn9}BF~p( ze@)(R(2lnlz&mX%F^N;rqzC6=l;3 nqWFpv3ig+uR&d}8!3p6YEta4eF`C2lj|A+bPo-_uG}G@p5vtro literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Client.class new file mode 100644 index 0000000000000000000000000000000000000000..ef6e46098b97a4f362c32307c35f56463cb18aba GIT binary patch literal 4964 zcmcIoYjhN68GdH7yOT@?0)d7G0;DyRWCJW$DG3%xno1x6O2Q>5#mVjv1~#*CcR~V1 zYgMpfZL39XsI`h0)Ph1wHd3%RywySAv+&c@rZ^}d`uRP zmg3|1gv>sv;-rQdI3XaXg!)qv;sa$(8&y13f=}agF+QWA0*}k3&#HJr#gjt#lnkGf z;qxk<)=(`VRX8KFFBId8^8J$RJR>wiD$Z)C#j_f|jOR3b1<#jaExszl*97^Tim$8q zhKg@0fC9bMw#`g)%E)HTtOAu|)=Jw7D%%blM~%VwfZ3f*Cytm-yu&+cR1h(;$LxfP z^PFyyse*eZknc2m(~j9r_xz&E0~=}@`PMXKZ%ZeP)NUhV$=crx zJBKVftt!wA%_+;Y#g35#)geStt#EMV9#wdKZQ$M8F`1R$#5z6A|YkiJ#p_2SrqkV>8*8B@wjC;D45pa7>Oh8 zMxSe1W`~<2-)3&QnfM*XDea%=Pf-frdiiMhUu?)gx|7*qW^5xR5#vMqNfpkvi(cVw z_cNsln=ISN9GhT572j2$8HogAzh?RJ<#a}{*Zqj8yJdvZmxH{X$66s+t8W7mP(3NemO5G~G`M1n@hV}wchXD$btnk4yl|`kpM01;c|L2FPicgGbu3LqK!@zbO2k;>so6w}A0gXCVV~vg$w6mBA<#<=<*oX}*Awh-I zV^Fg~?!Ta;8TYHWpyMLGr{ld?N8bnCDySW99T*>vI<|?J-^V2d^Tzj>g36)dvW}N< zg@Q|FR5$e>JZNUB&B26eCe5S>HKL;pKTt5s)yzuATer9HxX*Dr*qSM%3$8diuHt1K z*Kl3O4{=?=92dNx-Zb@Fsic|F@d{qm@fu!dL!hDGkW~wA==c$StY9kc!O5!QC-|v~ zpXvBHE~$7^$1iY6$1m|K9lyqJL|=Mx;h0FRsg&8n+TpM+73e-UNO#YlYFrS-UODHPX# zp74dyV>)gD^%PK0TRX9&1u4fy63$x3y;j-EH_dp96hvo@JC|eAgW{J(?0yducSDezY}5jlMpnuY#qXFdm$L?D?f| z%TF#cDt6L&=sSY0QokZ2N#L7KeL1CC7E`#UV~#jzPF@$AMMCzxVnQxn_}#qCs|lme zNLXT)f@H~y6HWQ=z+!m=cAA5<*2(}8Cm6r*O(_1+v# zmyRuh-%`@H-~o>B=jsWBc?)QWjX;fELvhy#N`?`M6%9j?L5p!2=1FN6N%Ub%i`5S! z8mqsG=?aEXcA2+B*v#=BlyKZY#APVsud~^>7nPJ~0d62hY2s{r>nKYrsVY3K*n+KG zk-w`IYqiu+U$zDmaR%t*K7(@2%%OaYo8}^Hp*~w(MBStH5f$lU9**)BB8U>_o!Avb zy4v61M>~r@)W41yLnw}gMae5rhHza7a+o!<=&f^@&P8}OW}kT$i(Q&)sOWkTbIR`= zLFG0cMwed2+z`$q(hxq6(}b%U!T}Fr{#oquW((Zy&E8_+YpB{5>mqP$=?IEUTJ{>M zsoGsjbGSQ)_mtOgs3(=T%wbUjDXO|E!z26=Cm{7XEZ*Zm)DyxW#CiIJN+>aIgqGYm z53M1xrlBZ{u(7x5#zbLzu(8-8|ic>FB~8*oV2;&u~l7 zRVG8}5D^B5ahxcFJUzkFNAWOD@&98ugVV_2arW6K*%P0_AMrH)#N9vR8T=hXu47iy z{973iJMbXoIYn3RLFz|5stv&ofDJzt8y5V43@ zyF8Xv!m^!yEL%bk^E>S-mJ~6DR(Vp&d2Rl@&O2W!=d*auXw|tDy^3WDx5Dk0T?Kd0 znsKs_?>t|DWlRg;1uAd>@+O?m7u{l9!V+9&LcYY*A13`Z-WZ_|uDgoG=m{M&(aqfu zDQ7YUk}ii`qss0oP*y{vdSO|U$}pKxjDzU$RgUv3X&Vt)FLB~khp4-`s32D(Zg9zE z3x@+PM{e)(5v2Uf8|gMNw(jP~LUTWpL!3HM0I&S$o&a(Ky(~-$MX{0g(HeM9N+W9> z6Kyh_=qOH messagesToSend = + new LinkedList<>(); + /** + * If this client is currently sending a messages asynchronously. + */ + private volatile boolean isSendingMessage = false; + /** + * If this client is closing. If true, new messages to + * send will be ignored. + */ + private volatile boolean isClosing = false; + /** + * The length of all current buffered messages, to avoid iterating + * over a linked list. + */ + private volatile long messagesToSendLength = 0; + + public Client(Session session) { + this.session = session; + this.async = session.getAsyncRemote(); + } + + /** + * Asynchronously closes the Websocket session. This will wait until all + * remaining messages have been sent to the Client and then close + * the Websocket session. + */ + public void close() { + sendMessage(new CloseWebsocketMessage()); + } + + /** + * Sends the given message asynchronously to the client. + * If there is already a async sending in progress, then the message + * will be buffered and sent when possible.

    + * + * This method can be called from multiple threads. + * @param msg + */ + public void sendMessage(AbstractWebsocketMessage msg) { + synchronized (messagesToSend) { + if (!isClosing) { + // Check if we have a Close message + if (msg instanceof CloseWebsocketMessage) { + isClosing = true; + } + + if (isSendingMessage) { + // Check if the buffered messages exceed + // a specific amount - in that case, disconnect the client + // to prevent DoS. + // In this case we check if there are >= 1000 messages + // or length(of all messages) >= 1000000 bytes. + if (messagesToSend.size() >= 1000 + || messagesToSendLength >= 1000000) { + isClosing = true; + + // Discard the new message and close the session immediately. + CloseReason cr = new CloseReason( + CloseCodes.VIOLATED_POLICY, + "Send Buffer exceeded"); + try { + // TODO: close() may block if the remote endpoint doesn't read the data + // (eventually there will be a TimeoutException). However, this method + // (sendMessage) is intended to run asynchronous code and shouldn't + // block. Otherwise it would temporarily stop processing of messages + // from other clients. + // Maybe call this method on another thread. + // Note that when this method is called, the RemoteEndpoint.Async + // is still in the process of sending data, so there probably should + // be another way to abort the Websocket connection. + // Ideally, there should be some abort() method that cancels the + // connection immediately... + session.close(cr); + } catch (IOException e) { + // Ignore + } + + } else { + + // Check if the last message and the new message are + // String messages - in that case we concatenate them + // to reduce TCP overhead (using ";" as separator). + if (msg instanceof StringWebsocketMessage + && !messagesToSend.isEmpty() + && messagesToSend.getLast() + instanceof StringWebsocketMessage) { + + StringWebsocketMessage ms = + (StringWebsocketMessage) messagesToSend.removeLast(); + messagesToSendLength -= calculateMessageLength(ms); + + String concatenated = ms.getString() + ";" + + ((StringWebsocketMessage) msg).getString(); + msg = new StringWebsocketMessage(concatenated); + } + + messagesToSend.add(msg); + messagesToSendLength += calculateMessageLength(msg); + } + } else { + isSendingMessage = true; + internalSendMessageAsync(msg); + } + } + + } + } + + private long calculateMessageLength(AbstractWebsocketMessage msg) { + if (msg instanceof BinaryWebsocketMessage) { + return ((BinaryWebsocketMessage) msg).getBytes().capacity(); + } else if (msg instanceof StringWebsocketMessage) { + return ((StringWebsocketMessage) msg).getString().length() * 2; + } + + return 0; + } + + /** + * Internally sends the messages asynchronously. + * @param msg + */ + private void internalSendMessageAsync(AbstractWebsocketMessage msg) { + try { + if (msg instanceof StringWebsocketMessage) { + StringWebsocketMessage sMsg = (StringWebsocketMessage) msg; + async.sendText(sMsg.getString(), sendHandler); + + } else if (msg instanceof BinaryWebsocketMessage) { + BinaryWebsocketMessage bMsg = (BinaryWebsocketMessage) msg; + async.sendBinary(bMsg.getBytes(), sendHandler); + + } else if (msg instanceof CloseWebsocketMessage) { + // Close the session. + session.close(); + } + } catch (IllegalStateException|IOException ex) { + // Trying to write to the client when the session has + // already been closed. + // Ignore + } + } + + + + /** + * SendHandler that will continue to send buffered messages. + */ + private final SendHandler sendHandler = new SendHandler() { + @Override + public void onResult(SendResult result) { + if (!result.isOK()) { + // Message could not be sent. In this case, we don't + // set isSendingMessage to false because we must assume the connection + // broke (and onClose will be called), so we don't try to send + // other messages. + // As a precaution, we close the session (e.g. if a send timeout occured). + // TODO: session.close() blocks, while this handler shouldn't block. + // Ideally, there should be some abort() method that cancels the + // connection immediately... + try { + session.close(); + } catch (IOException ex) { + // Ignore + } + } + synchronized (messagesToSend) { + + if (!messagesToSend.isEmpty()) { + AbstractWebsocketMessage msg = messagesToSend.remove(); + messagesToSendLength -= calculateMessageLength(msg); + + internalSendMessageAsync(msg); + + } else { + isSendingMessage = false; + } + + } + } + }; + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage$ParseException.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage$ParseException.class new file mode 100644 index 0000000000000000000000000000000000000000..58be9d5cef1cf63114b62d8f93311280a2a5a30e GIT binary patch literal 688 zcmb7>-7W(`6vzK(`?0l(YSl-5l*EOPq?NcNZi(m!^~E_j|UJ}5*Hr8 zo4E4?;w%y+L|n`{d(QmxJO8uu_;UXMU=_0-;wVI6(#5ok8A8TNspv*d6U2Pq_v_Y=f48h*oV{jxeAqJjIi|U@!L`FVxwL!-x_#3OaP*=s#gU){2Du)6S78WQu2_#8Mwk(?@;|Yh f@2nKF`hH=JVvHFM#+mG30>hj=?!+*K4EkOHs2iSQ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.class new file mode 100644 index 0000000000000000000000000000000000000000..7ef881e481267b035043226b31181dfbca2bd72f GIT binary patch literal 5967 zcma)A3wT>)8GcW4l5=vJwOzYHx(+rrU};)cwz*-uF}k%3i`~F&Ov*h?4_#QAlqB5^ zL{LOTn4sd=z%g)GxhO+v3lx}&cmYMl3y6wb<*GhDqC9|F-|s)UHJpm=lmGht-~ayK zdB68R$)o?d{~-X2@p^#87p3@;6xT`dWhr(^alI6~rPw3I4N}}F#aApW!CnJ5S(t`> z7H-BZ2EJ;c8vCVltASyE`<6?%1z@2Tx5?=32JW;F!Z!@uWnre&2Q19OUMcQ2@hz#p zEyX=1Mof%KbIiiMxX;4<7&q{Mi3csr$3qql;yY4&*Wccwc7ciSnRr;Nzi;3XvHF35 zA6f+aBLhFyPB&&L!>fDpt9nrnj?#-lP zo9%2%Upl(AHx*6ywREzzhH#?&_A+ji$#0~GyBat0#Ikb{GPft_pjZ_L^>C+{258!m zivsO<>HzKXBYJq%BqK(rFfHx;;?iZ(&W}s%^6uF7ar`t!&BrlSOP{e*eW}^+$<3=; z`nh?jr^PefrBNne#<`N-CJpQ1(*?DEc{~}F6MXlUdZcOxAj%>6nJP;(WiI8faOWj&Yt(GQmfv;gGUvd9coW+Ky#4G?dM+ z<7hP5pKy${{z)5@0N_E_XQQ#rYoddS45YV#M>Uw))cR~Xp5($A;YP=Kf(~1p(Pd0C z1CNnmgOUNO)2V^H`I6j8ORXFK4`yj`?rJCO0Xvx`8EemY@1_zBJ`-kvy-mZc5`%R^ z$!vU}n28LWH? zI%cnqODa{DWX1y7C5R89HHhQU9z+|K1+iR;o-LQZMCpSRJG9I3~vUtQns!yoKG2)(1nMI4i4JMK4vek zkN4zejx@~P54fsGF_unN@neTn_^-rv16BN z>gI?Suj@EtQbL1#Mph_q`JU@S>X9#=SsPtT<>LW)0r~9%;-R80+2 zHD!$TOlUX}A7M#Nhlk#<)g8}YFMkdlaa%Yk$dNaqwl=u0_kxFqL%~dB9N1&03s|CAg8+m@s$JVb_H^VI}l$vkdq1IlqrA+%>~Gr zu0Z_dK-ReeIm;c0zZ}S^1hR1oAd+VStEC2n2Q zl>^!A3dD8?VwD3)5=d$aAfmAX>H%I>oUwGKQd1>d34Scq506K#$bvBh>yn-w3rcLgomJNXQz283_eP z5Qu~-M_@(jsz*?QWGTP@1D8U_rx3tpsKlrFb^mhI<1?6zD{vG(izZyj3+;0_7FSV# zujXs@PKA00?-b%G+y|Yx`#{D-2R&+5gh)iaQ{K+GkF+EeeX1qG?N=?y3RAU&mX>M> zFPuH(!Bna-iA*(PlE8oy8P8f&@uG#+-ZYMBJ-h)u*XZ6cRF0yGBh@nEosNl%S?jsl zm#h6!k74>KYB+1~WA5661*`-7SZvQ7N3D2}xjw(SYxQq+wT=Sf6m_6hn?&jU1Hd(vkbKQSz4`TIHd2|i%OZ0S))}C z`9mg$s?@w#1zN?q=HG`S#xb)eOandKA2LJ!{xLMPSxxnpg4iTh+=|d@Ct2msk~bB8 zdezO}%U^kbU8uosKD8UE+F1(Hd_!~y>Hpa9{+^5aJxHcOPYOOe^9gl|y!-=dkDB1GO&({6mYRH7a=3*z7!i4&**}h1J!3dbVmXS#Yi5sP4%>=X zC4I%OlD^_uNni1;r0*HU5qV!mNjp%|HcQ%kq6Pbk-7stB4#QV7k6=b|~Ro?a#$TA`yb;E!<$>!U-Nty0ri zIyjESJq^v?#m)NSX5Zpw|Ki4apLb!s&&Q9>kAGpEe+(a#&>Ub)19%f}Q8Jx}aW)QR z(4Qh*pXSUn6!B*%ug_r~o~IDL$anac_;&LmUl(41jaNy%*Ki$)w-0}23jGD+_$ybw z!Bu}(e&51Bm{kANym(t{#=q4=-bry>$zNMP!54B9*VCudnvNHkESJLIj?d)e*~S;- zcN3y}lb=sgPW|*}@dCJvc6{Kx0xoCmMRRV2t~K#GxPpl(W6s)ub~LYsE8$aP$_vqW zc}=XL7ok}a(
    + * + * TODO: But a Color objects needs to be created anyway for drawing this + * onto a Graphics2D object, so this probably does not save much. + */ +public final class DrawMessage { + + private int type; + private byte colorR, colorG, colorB, colorA; + private double thickness; + private double x1, y1, x2, y2; + private boolean lastInChain; + + /** + * The type.
    + * 1: Brush
    + * 2: Line
    + * 3: Rectangle
    + * 4: Ellipse + */ + public int getType() { + return type; + } + public void setType(int type) { + this.type = type; + } + + public double getThickness() { + return thickness; + } + public void setThickness(double thickness) { + this.thickness = thickness; + } + + public byte getColorR() { + return colorR; + } + public void setColorR(byte colorR) { + this.colorR = colorR; + } + public byte getColorG() { + return colorG; + } + public void setColorG(byte colorG) { + this.colorG = colorG; + } + public byte getColorB() { + return colorB; + } + public void setColorB(byte colorB) { + this.colorB = colorB; + } + public byte getColorA() { + return colorA; + } + public void setColorA(byte colorA) { + this.colorA = colorA; + } + + public double getX1() { + return x1; + } + public void setX1(double x1) { + this.x1 = x1; + } + public double getX2() { + return x2; + } + public void setX2(double x2) { + this.x2 = x2; + } + public double getY1() { + return y1; + } + public void setY1(double y1) { + this.y1 = y1; + } + public double getY2() { + return y2; + } + public void setY2(double y2) { + this.y2 = y2; + } + + /** + * Specifies if this DrawMessage is the last one in a chain + * (e.g. a chain of brush paths).
    + * Currently it is unused. + */ + public boolean isLastInChain() { + return lastInChain; + } + public void setLastInChain(boolean lastInChain) { + this.lastInChain = lastInChain; + } + + + + public DrawMessage(int type, byte colorR, byte colorG, byte colorB, + byte colorA, double thickness, double x1, double x2, double y1, + double y2, boolean lastInChain) { + + this.type = type; + this.colorR = colorR; + this.colorG = colorG; + this.colorB = colorB; + this.colorA = colorA; + this.thickness = thickness; + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + this.lastInChain = lastInChain; + } + + + /** + * Draws this DrawMessage onto the given Graphics2D. + * @param g + */ + public void draw(Graphics2D g) { + + g.setStroke(new BasicStroke((float) thickness, + BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)); + g.setColor(new Color(colorR & 0xFF, colorG & 0xFF, colorB & 0xFF, + colorA & 0xFF)); + + if (x1 == x2 && y1 == y2) { + // Always draw as arc to meet the behavior in the HTML5 Canvas. + Arc2D arc = new Arc2D.Double(x1, y1, 0, 0, + 0d, 360d, Arc2D.OPEN); + g.draw(arc); + + } else if (type == 1 || type == 2) { + // Draw a line. + Line2D line = new Line2D.Double(x1, y1, x2, y2); + g.draw(line); + + } else if (type == 3 || type == 4) { + double x1 = this.x1, x2 = this.x2, + y1 = this.y1, y2 = this.y2; + if (x1 > x2) { + x1 = this.x2; + x2 = this.x1; + } + if (y1 > y2) { + y1 = this.y2; + y2 = this.y1; + } + + // TODO: If (x1 == x2 || y1 == y2) draw as line. + + if (type == 3) { + // Draw a rectangle. + Rectangle2D rect = new Rectangle2D.Double(x1, y1, + x2 - x1, y2 - y1); + g.draw(rect); + + } else if (type == 4) { + // Draw an ellipse. + Arc2D arc = new Arc2D.Double(x1, y1, x2 - x1, y2 - y1, + 0d, 360d, Arc2D.OPEN); + g.draw(arc); + + } + } + } + + /** + * Converts this message into a String representation that + * can be sent over WebSocket.
    + * Since a DrawMessage consists only of numbers, + * we concatenate those numbers with a ",". + */ + @Override + public String toString() { + + return type + "," + (colorR & 0xFF) + "," + (colorG & 0xFF) + "," + + (colorB & 0xFF) + "," + (colorA & 0xFF) + "," + thickness + + "," + x1 + "," + y1 + "," + x2 + "," + y2 + "," + + (lastInChain ? "1" : "0"); + } + + public static DrawMessage parseFromString(String str) + throws ParseException { + + int type; + byte[] colors = new byte[4]; + double thickness; + double[] coords = new double[4]; + boolean last; + + try { + String[] elements = str.split(","); + + type = Integer.parseInt(elements[0]); + if (!(type >= 1 && type <= 4)) + throw new ParseException("Invalid type: " + type); + + for (int i = 0; i < colors.length; i++) { + colors[i] = (byte) Integer.parseInt(elements[1 + i]); + } + + thickness = Double.parseDouble(elements[5]); + if (Double.isNaN(thickness) || thickness < 0 || thickness > 100) + throw new ParseException("Invalid thickness: " + thickness); + + for (int i = 0; i < coords.length; i++) { + coords[i] = Double.parseDouble(elements[6 + i]); + if (Double.isNaN(coords[i])) + throw new ParseException("Invalid coordinate: " + + coords[i]); + } + + last = !"0".equals(elements[10]); + + } catch (RuntimeException ex) { + throw new ParseException(ex); + } + + DrawMessage m = new DrawMessage(type, colors[0], colors[1], + colors[2], colors[3], thickness, coords[0], coords[2], + coords[1], coords[3], last); + + return m; + } + + public static class ParseException extends Exception { + private static final long serialVersionUID = -6651972769789842960L; + + public ParseException(Throwable root) { + super(root); + } + + public ParseException(String message) { + super(message); + } + } + + + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.class new file mode 100644 index 0000000000000000000000000000000000000000..82f642bfb94fb8c466ecabcaaf3daf58e2b80f69 GIT binary patch literal 890 zcmb7CK~EDw6#k~$vUP0>qE-Z}1qvyqVPlLZj2FPfq-bId2XE8e5f;i0*`2oNzw)BS zgGUekCS&|&xAb5t(Zjqq@6CMQ``*j@@$2h10FSZhp@h30ma*dD9vUw0yLjNDDKPgm ziX-z(z-ezC3KVyBs08M_QLJ7L&-yBPBl`np7P~r-gF~4_Hl8Gl<~T|Pw!351Pjzsr zj2|X)+}AP*{k_ZEu8xhmFx@CMDptu3$$~uff~6xlh(4%LV6)vlkt2EGrz#l@NY%^z z1in8~vDvX2oiw1J^?&#+urR5#r&5#X_qI+k(fUkad8X*se51f>&&c5PK%Qrfx>yzP zdU}`y>Um_R(fC_)+qQ)YT$Ej`Rj`g0!4+(vEYSI%DN(wm@&__L@?Z5&RA2;JR}JWL zz5+|L3fayCHfB9do7s=Ua~;L37oJ`0fl><$xUuDTPN@!)=%^Wr5u1&a0{B;wzSot<_ R?D8k7F6yjuhj9T*zX1|J(`*0$ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.java new file mode 100644 index 0000000..dd022ba --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardContextListener.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.drawboard; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +public final class DrawboardContextListener implements ServletContextListener { + + @Override + public void contextInitialized(ServletContextEvent sce) { + // NO-OP + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // Shutdown our room. + Room room = DrawboardEndpoint.getRoom(false); + if (room != null) { + room.shutdown(); + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$1.class new file mode 100644 index 0000000000000000000000000000000000000000..90a3fe6240945733b0bd9885ee9fba82da89fccb GIT binary patch literal 2158 zcma)8eOJ>~9DXhZQbL>v2oBk(S|_w(iqmachNBfGTM-8cW3SvMmoyNPo+K5vFXZ2z z!;8*y_5t=m_Az$+-Go}OIn(y^zCOR#`~2?hKmYypH-OKv-GgC#A)7B{^OcHAxToSi ziYo44TEW)}W)wV7(Sv(wd?Wi=6$(mnR92D3LltwFm(8~d9!ar^Ok8&@*M@7M+ zg2xJ$7}C$Ull47smtmx`C#r#G?1)e|eZE)qxNqvqv{z(MCC+ec;f4&OiO6!aOW5wP zW(U~wJf=O>GuG8hIhXbY|@{IbJ?K+wuWqMf$jvQrdZ%5S*Tj!W|$ zVxQqkWt%_ay2D*dUvL~@ac3pup_tn@L_M@UmxM-7VU`)FpRy&afZ7|G};SxMG$aH1o}$oli~Fy*B0Y-hT)dx7*cB3jwyTwR?zSh ze%9~{e%0`sY%=&=!KMa|ss;l&qHjz5-E3(vA=B~H75jBzgu={-W}@$B6l`g*P$Rx3 zdES=8>=Z*^%h*zNn^Y2eT1#Z#jVX2ggESKVJ$I=th$GYE(W&q2Ex{E^kYq&LMzem( zp1WmRMME=~e}*rJVY99|Yno3S{)g}t*kn2$GdxHxy=LVk(p?r@Hda84 zRk>l1v)Mx7Hp5P`y0&x{->W#e($1Rh=5@-S$uJowFfOf_N5zR#m2`$$@; zKZW_0i-Y6sG6YVCUM$aWG06^{z(~>w#5rW>4amp0M(C`Qz^6)Owi<*!H^TLIiX}Sh zE?L4v>t@!c3UuX;k>j3k>AcR3n$Wi!j;%YMWl_cH70;p=F8|LqLznPd+qVXWEW1MDmKO=Xd>tA$5+P88C zr0Re)9Uygtu9xUue-6DOr>~LTc#WQoW2pVTN6_*|I7i(PK03zvBlN{07oOu<|K`BHcVCIE329Ja!jOHvNkLW$zB|;s%ZS QX>FK#`FTozB-U`@4Gq*-0{{R3 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$2.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$2.class new file mode 100644 index 0000000000000000000000000000000000000000..ca1727e34ffa9019f2c245642c49ec11eae1bcba GIT binary patch literal 1590 zcma)6TT|0O6#kY%Q)85Z2;R79m0pB!^MW995mYSd0P6U-O?OHl&34ihaK`b)@$x@> z@R=D!)EOUr@JBhGP0ADp)FzYNvuDrc%Q@ff&tG4^0~o=BBWOlaM;s{~myp(x!DS`& zYZy?osbNq@45=7~)I6*siV-D^9K|TEXt=83nuhBPQGeAgCk7e%vYR4Tme#uP&Ai7q zbCP>`^Y)%J=jKb&cKva3nXp~kpJYfU>-0%IVQ8F{dBM<}wO#R`Qp^c&h36d7v}UEn zohRJ0)w-%|RInJpVBB+E;mta{To$BB)t53cOh6-E#icQ+(l>}LhI839zQIk0y9INp z;`(+`%xzhs^T8=E+ZedaQ zt1_=)%)kwd8)(G|18wLsFo8)8QwFBhVg|DeXZ{Yxz-`Pibkr=CeUHM=RBR_NJc9Dr z6n|6G%Ognk1RE|uD&LQ8RE5c4|8i2oSIWpQNi4>V;Ad+ z$e>AgmdZkv8%qY2-!f~S%c5LXWk0YHxGV`?rcKp3om&>!CI$zIrO`(Yf36C!P&fAu zCCrkP#Y7luT*D$mcMVyM{rjvKj(eggH^jUri%P#A7}ajQUOfMWb2!8IK_RB@)nrK3 zq&u0)O0Qt@61P@`xmIy((~*S&@x{!_f;zFhR1$8Up+D?HcmhI7ji>ek|4jLq;F~WHG1&|Q+O8uYp3MB=%%+P@Sm?O|_BAqiD&UaJ1 e3$$)P0vBm+q$|G0`lqUATEFsnHL literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$3$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$3$1.class new file mode 100644 index 0000000000000000000000000000000000000000..237fb7d271fe82bad97f440485dce9145a5c7e84 GIT binary patch literal 2521 zcma)8YjYD-7=BKYW}9?r3%2E|Ef6GaY14{;kb*#Hu{Gt^Ql+A@NtR^W&2HRm+JaoX z;K*O_7nB*t56nO);$?J3X7r0XesIPa9mmU`@B{jsBqaqJr#rLfyyxtDp7;Kq{qDi1 zUjW#N4+2<=!*YlPu?|Oq7{rhqj>_RBISdCef|rAcV>E!LaV&`AI1$82oKi5R;Iv#% zD0n4^W*n)|dZAOcjnw5@> zxsG9_qXK?6W8_2q3eE{YKpnO$-HDl6KCkBmI^(l?B5x>BkD$gzk)M3A1E@oz%<;%`xP< zvgwl+2z0MhXsDmcdYyvBF)YP37*B7=5Z>xkgqWoJ;CC*RU<3w4}&9HmjMYJ^OH< zCnp6w`kcV3F;`1Yk7~J+`3f`ziBiaAeh37|?1GcjhYabjwkIOhD^q~39ki0Boo5P+ z>TbqPsYrsuCUmISfQ>3Pqm$4obeva_Mn;8!DM?K$FjZt>QLG9ZITdfgQIJ>RVn)H7 ziVL_X&|52UD*g(c(42hLaQf=;jSbaoecVkd-o_bZdA?I#sG#Cbd7wY(7KVVjZ-FhnMGUtXdtnE!IaMC&O8$msN?C)Kuaba_sD)sk@d_eg&0QZd!c;+iNmE z5IU)s(IfQbsg`p_3$(|%QgmZW>4eo>*2c@TljS=sl8l#IX886--hVgaT}hl zJMi8tF@`w$$q0OcZ5-7S-GpbcohyMbI?FKPYxq#ly&K+vu3PYUi}3B2gs+IYW1Bwa z7eM1Hh4=BLLg?rF%shsAnlBaM-|g%1wvt_0K>eP&o>rgl9M3Kwuut(xOmPdr1vK18 zOLehcX{#$j^$yIVadaNR(TyLWZpWAN*cx9z(>*kwxr5bf))etncM&a|ifHY=i#9KA z(r6E6*q~RH=F9wX0IuOf&R$5nC(*|7F2CMG13p6wKBwki@#p0mL~$QS@h!&jJtpu2 zZ;T(=@_!=U??n6=7dcSzDP` P@xN@G7M#Q^3RwLgX0Dvr literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$3.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint$3.class new file mode 100644 index 0000000000000000000000000000000000000000..6907213b8bb635542d810531deabb216d21762c0 GIT binary patch literal 1279 zcma)6T~E|N6g{()t*u2W%7=)ET4dQ(7FqlXgoGdllSLEOKzy8SCre?OF>M$8Nxt~t zgJ3ii4DH{b$ zn<(0}T{7{uHh1~53Uq!iIglgF`$8S=??7<;n}Q`G}ekCneGl5!C7gSz5TP=0YT zT9v_j70P6RToywaCQA&(LYF?%n+(Q^3Is!cHI(9YYp*V%x4hn@m4T}Ad2^FTp`K@p zhNi_Z-CY2$LbNO;*F_xj24M~ssylq2mz!KR%C#g4Wn)2;F!xR@209JSxV@?G2tP^P ztXkNRJZVJ)-Mh7|H0|msfXp;q`A}}_nDJTTGH8m(OFb7)`DM(Oh`n7?t;iQILybMu zA^VIz4ym^){icfPIO`(WR)L9G2UpPVz{Mj6bEuGJ?f4hu(W`jm;9}myV+T+0l)*hK znS)`BP-S!p_z%LdBqp9QcpCSAvM@|`6^5awpfhQ6-=|!9bF);tV} literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.class new file mode 100644 index 0000000000000000000000000000000000000000..1b3d2e3d9a737d522612e095a226afb48a9fc55f GIT binary patch literal 3908 zcmb7HX?GLX8Gf!Ldt@;N*#;XshB(H6@q)ahl-MpwFs5;8;}o;hZc}G04f0?yqmCpn z>5`^No3u%~W`j0qlP-Ksp)sL8r#)@XNzdu;=!gD>o^*NMnb86g;OZRRdv))-Jnwq1 z{{Ejo{t3V+e%F95oRc9f!%7T2ur!>Hp$@CElab+q20MlZSXDzNz6`F|@;q;yIbWE$7e6>iI4B4qnjkVhrEK z_cXi|L$`op90pX;Z*wZcPpmDuBxkg+kBcM0VQ!%k&{{}qM0vnx)HK zkv0S39*>SP8s@FEZR86snZ`E7G*My0ya!`D+q$qORjAffA z3Ky15_mr_L$eQU1BXh=ZE%_a6M)E5beZIe@(Z`Aoow8F|$Fjv|TH4Hudl{kL#RE0j z0`J!+UDL=@v09|Z=JQ5!b=JswdYJ(lUL|zLp39oH!bESC2j=NE%dy9+4vJtV9s8V> z9v7Q6CXNs*v{#WA zq*D;P)wEw@T*i!KlK$-(8X8ep?XBsM>Qt#oCaF;@qq`?hkwPJ~HYCGv8N~1qcOL9L zaG&;2#!T`jH;Z{QkcyH=1V|@=lq(iE#n3_92wU#uqdDgX#E4ZrAQaqcU zD;+7cdAnX`_q*cJf|W^`tc?c8_Nrv8OUKXg3mxy^T@Am~@hiNiu(y`kResg*zK&nx zHwy8x9{&cRhh?j>P>X$pDOyWjb3 zg$HtGe%4q!Wv=A|?MDme&YAAK^(-?r(mO2;s>w*DZpWsur@HgpPU7{N&T6V+M;5`) zY}Saoms!n|ph1g@M$5kFteTJ8sk4T~cGl)2@>}1@f^C=jVw88=q*0J=-p0Z%$GhZp zxo)kTe`oQ!<;7NSWO;+76b38B2G?_?jN5XPa-w<1-(t?+rYzuPWbW|-VxuO%{`2R zq$;Bt!DD!w^hf!PBl0P_G)x}TaO_`*go$zr#{;ZaP*3OaVc*}hKYj~aLg?@N1GHPv zL)bv$LjO%{JrVf`+r}d8kqyKb`r0FdH_^0?=CW%#CB)*%PJ*oorU6g+o*nw9(1bset2|;TKK`Z9)6cN+~dc&U6qEMe=hlVdw|4GaT zDE>iw;;g0ckpc0?I(B@5)?M-K?<4O08jHLbR@eUf&-Tb)&`Q@{!=e6LXj8a~t+Kb% z+v~oL&<5I>1Rc!}tfO;a9lJQKWB0%)$O*;22CidHm`ci@i>Vk?X|xC#SanwfXk4VkM$&wY7ot>J_)|;RRW3e6=tfUpr?t>FR)IJ9*EF( zk-|SI90Mt&T*5N}WrDNFu45kFMWJ7Mb-qF}8(0pQE7Y)90*@CW* z@X!r}6f1HA-3-f~8;D8}e2`n|11ZM__LD|-lMqt;9fFB{ockCU$qD(i_!CRc{~RPw Nf_XK9A7He;;eV;;;-dfn literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.java new file mode 100644 index 0000000..cd99f49 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawboardEndpoint.java @@ -0,0 +1,236 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.drawboard; + +import java.io.EOFException; +import java.io.IOException; + +import javax.websocket.CloseReason; +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + +import websocket.drawboard.DrawMessage.ParseException; +import websocket.drawboard.wsmessages.StringWebsocketMessage; + + +public final class DrawboardEndpoint extends Endpoint { + + private static final Log log = + LogFactory.getLog(DrawboardEndpoint.class); + + + /** + * Our room where players can join. + */ + private static volatile Room room = null; + private static final Object roomLock = new Object(); + + public static Room getRoom(boolean create) { + if (create) { + if (room == null) { + synchronized (roomLock) { + if (room == null) { + room = new Room(); + } + } + } + return room; + } else { + return room; + } + } + + /** + * The player that is associated with this Endpoint and the current room. + * Note that this variable is only accessed from the Room Thread.

    + * + * TODO: Currently, Tomcat uses an Endpoint instance once - however + * the java doc of endpoint says: + * "Each instance of a websocket endpoint is guaranteed not to be called by + * more than one thread at a time per active connection." + * This could mean that after calling onClose(), the instance + * could be reused for another connection so onOpen() will get called + * (possibly from another thread).
    + * If this is the case, we would need a variable holder for the variables + * that are accessed by the Room thread, and read the reference to the holder + * at the beginning of onOpen, onMessage, onClose methods to ensure the room + * thread always gets the correct instance of the variable holder. + */ + private Room.Player player; + + + @Override + public void onOpen(Session session, EndpointConfig config) { + // Set maximum messages size to 10.000 bytes. + session.setMaxTextMessageBufferSize(10000); + session.addMessageHandler(stringHandler); + final Client client = new Client(session); + + final Room room = getRoom(true); + room.invokeAndWait(new Runnable() { + @Override + public void run() { + try { + + // Create a new Player and add it to the room. + try { + player = room.createAndAddPlayer(client); + } catch (IllegalStateException ex) { + // Probably the max. number of players has been + // reached. + client.sendMessage(new StringWebsocketMessage( + "0" + ex.getLocalizedMessage())); + // Close the connection. + client.close(); + } + + } catch (RuntimeException ex) { + log.error("Unexpected exception: " + ex.toString(), ex); + } + } + }); + + } + + + @Override + public void onClose(Session session, CloseReason closeReason) { + Room room = getRoom(false); + if (room != null) { + room.invokeAndWait(new Runnable() { + @Override + public void run() { + try { + // Player can be null if it couldn't enter the room + if (player != null) { + // Remove this player from the room. + player.removeFromRoom(); + + // Set player to null to prevent NPEs when onMessage events + // are processed (from other threads) after onClose has been + // called from different thread which closed the Websocket session. + player = null; + } + } catch (RuntimeException ex) { + log.error("Unexpected exception: " + ex.toString(), ex); + } + } + }); + } + } + + + + @Override + public void onError(Session session, Throwable t) { + // Most likely cause is a user closing their browser. Check to see if + // the root cause is EOF and if it is ignore it. + // Protect against infinite loops. + int count = 0; + Throwable root = t; + while (root.getCause() != null && count < 20) { + root = root.getCause(); + count ++; + } + if (root instanceof EOFException) { + // Assume this is triggered by the user closing their browser and + // ignore it. + } else if (!session.isOpen() && root instanceof IOException) { + // IOException after close. Assume this is a variation of the user + // closing their browser (or refreshing very quickly) and ignore it. + } else { + log.error("onError: " + t.toString(), t); + } + } + + + + private final MessageHandler.Whole stringHandler = + new MessageHandler.Whole() { + + @Override + public void onMessage(final String message) { + // Invoke handling of the message in the room. + room.invokeAndWait(new Runnable() { + @Override + public void run() { + try { + + // Currently, the only types of messages the client will send + // are draw messages prefixed by a Message ID + // (starting with char '1'), and pong messages (starting + // with char '0'). + // Draw messages should look like this: + // ID|type,colR,colB,colG,colA,thickness,x1,y1,x2,y2,lastInChain + + boolean dontSwallowException = false; + try { + char messageType = message.charAt(0); + String messageContent = message.substring(1); + switch (messageType) { + case '0': + // Pong message. + // Do nothing. + break; + + case '1': + // Draw message + int indexOfChar = messageContent.indexOf('|'); + long msgId = Long.parseLong( + messageContent.substring(0, indexOfChar)); + + DrawMessage msg = DrawMessage.parseFromString( + messageContent.substring(indexOfChar + 1)); + + // Don't ignore RuntimeExceptions thrown by + // this method + // TODO: Find a better solution than this variable + dontSwallowException = true; + if (player != null) { + player.handleDrawMessage(msg, msgId); + } + dontSwallowException = false; + + break; + } + } catch (ParseException e) { + // Client sent invalid data + // Ignore, TODO: maybe close connection + } catch (RuntimeException e) { + // Client sent invalid data. + // Ignore, TODO: maybe close connection + if (dontSwallowException) { + throw e; + } + } + + } catch (RuntimeException ex) { + log.error("Unexpected exception: " + ex.toString(), ex); + } + } + }); + + } + }; + + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$1$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..07c525b7a40450df19942f450155cf652b1b1843 GIT binary patch literal 725 zcmaJ<+e*Vg5Ix)0#-!2KdarklS}WKVeG$bMQ4p$vO5Zo>qS3euNvdBX=qCt@;)5UH zM~SnwqAxM9J2QuwvvVf%@%i=+U>#)>Jt$eoV#0)pNefe$HZWsg*1#M?Hoov9r*2@L z0Sxwmlp@>>cod06+(>y>BCfVVe(Ne8wyGyeT|4zHD&F>`AMY^Cl>bXyX)98#s(q;XEb*kE-C-!~K zYU&=>F8K|oH}|9$sK}S+ha$dEEgM4^w$TgQMxXW;;22o6v4mxkoUGWXGZZvuHQ@5R zdhA{bFD3=Q&`Dd$Z&{^enxCQ97)pr(X}V)c6r`1Vo`@o+RwI(BN8m71*ykQPJwP+3EW|TZoA`KC}NNzrpMT2*d(j- xa+N2rC!}AI`K7QraXY9d;!RTo~!@> literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6ca9f51e8509a76891df54bb83af3137e23eaef2 GIT binary patch literal 747 zcmZ`%U2D`p6g{&^H*8GZblbYM-yc!8TQFVpO)1o(Agn&LrKOLv$bHC=yxw(h?=kL$o0AAo(19dF=@UY}z*@uG_9}8IZu;yW% z0Sv)=rGz=ic%F-#p|cpNu9KlC;?(e~f#xQS549e>BGhZCWU^GVUQ%^8*}IinsmcTB0sb}YYtq)U^C zchYh;?B6~A#4kB@e5;a7=Te=25XFT~J!}Nn#8vKxRn3n2N z55>MpPq{1@+MQdfjH~nbuvE$lO-QWMPI$B)EDWs}6xHYin5J!bNYP8mZN=~I+<l@*vDv4)S_CQy#1V8_Ydk+sdoSX literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$2.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1d69d3d136702a929cea3211b0515fafa74d446b GIT binary patch literal 899 zcmah|+iuf96r4>=+!&XH6i6veXdyt7(mGAcMFR0sEoz(*m@rjY_jDVDrD9v{z~%lhZ9?>_)+;7%Shs5r=@>fj2lnq|qsGOihP z-9ZgEY}~YQ%SN3cm-MBswHOvUL($Wb|3)NU5c6R#;&I^ZMA6^@MLm>CCXW~@_32@a zT?T6_3Is!;Bb9iW4tgT)@?J z**I0S){Ud{DoSHtJe9^JZ}MF`;BPtQ@I?7xq@~(_A(DO+*l4(DqU_=Ctc zRjk?YT(k_cj<$^r7n>+kPo}k`)@CRg8!zN)-`nmT2tT1BC)7@=)Jf&@(?l3%bU#gk zXh_94-1mjnwYx2nuAb86y~f@o`d*7Bw|Yu+qcch=O=ReGqng&*n&MP5@URwZ@9+E8Wv}z|*Vi8arm^ILf@wB4+?c_v17i-%xzUeXZ04Qt zyXi8)h@=w%_P3oFV!zHeFh^V(P7SgQRRBdE?Q`WqP?_JRXbj9D1uV zOar&PB7!qnt{rB#hB(t)SA|)#y`Ah$aDg7*t<~F&vawXnIu!qFz2Oh}S}Zr&j*7v4z4={xJEFV>zK;nD%}RK4`nfb`S@ zA^bcgz&FZ+qF8|oXE6?ea}=E?&p&qumd~*6!}g9MfeEs9c{fY=Nr_|p3@q~0GXN#> z1@?U?Ot73FT%Z&60EQqg%6l3zp;+P`tgta6a%F4}j>y?h5bq^sf~=Qrfd`bl01q^< zR)CnS7?KU~KW@p2Fr8Wu@i}n?S1BK>N6B+bO5`KNTM3vT`=^)V(iB{ia!y>ABqqP1 z>G1E#Hz-BF)9Q=u!Sw-d8G3BKxC~Vpo>F{MGW5!@&+eO+q0jN1$kq;RZPC_&suh(E zyjs!TflvDY3%7bO-+;_Ek3L%6aT?1ttRRWmqsC&06V`$$oF?xkmV%oYNR9jkE5kO_ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$Player.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room$Player.class new file mode 100644 index 0000000000000000000000000000000000000000..5a6f0a50fa595dd9405e17a0e22f1f88474b8112 GIT binary patch literal 3859 zcmbtX+jA3T6#som+RbI#hSEYobOv5M$Y#y3c$1Nj!RkgcvrZPQlC}ytf z486+;H0z3GpHZ`_Hl^lWQ3yI4Mw@)it$f3vBU47p{VnQ|5+)+aJ zFf4)O&=qA$=_=Wp-Zi9IHc7@twR};rOQtH&yXtknuaPRq%m5+O+Ltve)h)0wui8g^ z?KZZyt%4@K$e@uUqYXn^Q5`82##M7n8P{p2amdIj`dP))_}SZxuoW_PT32ROQ$RjZ zEUM-p<;qfNe}}KDoY9o4K?e7)@!}r_*sm2edq7~cHPA}tU%v4w)pk}uqO`H2R8(^C zFNhH%L03;;Yk=r71L{q+U`(mUO{3s~hg;cL-Kec(uMR7dURqlSbI6}>q(F>ou>u7m zttT0>W=hdZRJL`Om10g;tLP!H%RggPG8qRWT(I&%MXVMkYb43t&|s;>97pD{Tf(yf z3GZQSc9I;*_#1afQ6-phsi`Z)eAlRLYQ=np!;07r$nL<3q^dEfj9H^-JH6Ss7LZ)a z8ih$+wbfyZ#>R635HNxr{EvJJcDBa}Dl|iV8k*_hWiKziL8HXUQV(@aT*+o>2&MLR zlj_A_kIQ`)>_T%wscIb<)<1B2D0mfXn0~ zB~8z%ri@qcs)W~MypA_yyotADyp4BgB>Ih;X{+F#I+oWD=gNnbS3wToT?y~Wcpo1K zZ1V%DDifVM6~9i6Us1DkfTaSJs%SzdWuO>wxFzUig-Lx}(ShKK2KQN+&& z40q}O!1=aE^@wvgy=;&y3bX|qTrq^&23Mror2tJPXF#8tpsyCKgC6^q_WmKSWBYZ(+-)TY`tX#{+?W|M075dU)KjO(koe zTSZiwdFY|9Zd>U4UkyUsS9BNR)}w19x0rLK&ZKd?%XzmundBy=`+Ab3KBhHIPhBKI zQyVquFHn2k5pAcnmN&&UbkM!*3ZN6+^yI?zkUDigyo4(2i(B~HPp@euyd&&c3pA%V|-bOX4q(9E76yKvp{NNyL;Abj{TV}qypZLV=IE2F<)-dsn z3!QLcY~Q|!hSh*SA})S%0Nwf}mH`tufGJ0zBn zB=W5LY6*>WUEjWlrbRT*V?zi1&tu~V`B1lnmh+tp*ffvLl}v9SFCl(LRQ!UZ_!Vv9 zHyjYZJ5HrtBg;OCLj^G8;(Ta6b?Z?it`@i!3q@?5cWqb)1Zu4ONc}R!nuIQJe*3eEg-bIUEKJ~ zL&Jd~<%@WHS-DK+1)eY~$?T&{C3(V;dXk0}PmM5*J{^0oj((o%c;L_`jL<&){R!Lh Bo?ZX| literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/Room.class new file mode 100644 index 0000000000000000000000000000000000000000..608dd361369723eb210b4bee6ffe0e057a308c4d GIT binary patch literal 8278 zcmbtZ33y!9b^gz2MsGBFvSrBz32Y-{nP^3pjSX0~u_Vj(7)f?yVId%xr_n?OT*H-CD4L{B^#$9O`FiBTe^m%O_wCJO}eB@+E7B`{O7(m(#RSC zUn}ri?mhP`|2g-ZbKiXBCog>-z@k^Q|6f2$1N#&`7cS_J=qe=Ng4;k)|u zJ*EF=z5I*5{;P$5i(m!5Uygsre^~g>F#aooI{d)Ge@Czy|5Jt-ei+8DO4aJe5&Q(_NiN_*5laFQwByyVltd&bAxlavu{b2*h?Gerf{jwHly*ca zWD!}*VzQP>OO`~i6|Y95N~*)MRB4t)&?^^Fs9dasHRVz(m+0kEon3CpiU^{3Rp(Y( za+wa+Q6E{wVYxgkt95<7zN`t$6-xFl)wF@wN~2zy$}ud>mbBE48M%uNgIXfo-hyAw_(<7OJYCW-`v0J9uou6+jS9r&8m+sn}sb zQ|}??h|`wK#uII^R5F%Jr`=?>Ey2l5+kngGw3Ey#Z3kt<5~++kDv+B5OS^8^v7=|; z!1jU8p#yzA`}TG2?Aa%%=uRawS+3ddByw&EogjkR(X?}P+|!~fopMHFP9{4TA6I>s z6lh?ED5!ie+NZ30dOL?HEvjr*3Tm8KHh#pN%VE&T(2ivna?xRODpOOVf^be|f zM8%pgF5t?_0&RNZnXD?ZFFuxZvbi)BS%1Ow=H8?3NQM}@*)~OLB;}+>+Xkpiz30`A zt>myc=EM%VqXW5Q(ius(6m!KqKE{~|Cpp%ZCo@Z{>opqE**JZ(J)Y6!)VFkVJQ>e! z6_hkI?iU2RQ=?RFac?~7_UFb&-1MLl3aaRSC$Zm2$MxMG3}z3;slp`-s!ok-VrkdO z7WLP~4UGlL8^8M=tMV3gCPzC*NAp2_T|-eh-HA9Ow4<@;WFdYgc9mAJyeP5HiNQ7@ zSXGo{EW*tv{}V)sm=4*E4p&=#Hg$4 z+M}~>;+l)*Ze^O{Z|8TGk_vU(+QH&x$u+EMjKX;GNb0c5O*`bo8TS`A6zDXQiqxE7 z*5qp+-MOjCl51IjDzDK0X1fL^iF06bJ>9lBmhj6-WM3+mj=4MHT0F{hPh6>W$;PMggpFUs<2H`q zsEu(XZ5%}0#;@Z(8}G+`f`)h6j@Y;zOq`2n>HU6UxfxlY$Ww}JvXMp3mJZo0sGePK zva?oe8+YO^8}G$kmTa+Qt907ZCEb>6x1~pRShCZWT@tmKf3CNsSNd$}*UKK+%YwLI zDQ{O3zrY=1%e$qIwZVusJ0O}!xMNO&sXXiUOvc;^t<-{+K4&sMo*S>5FpWiBER{=U z>l*0Y#=3(}rf!7&Ssm+$wgp$JX#?cCpnNY*lx&|ZgLsA+q}j$V<5z6CLH657BV*$s z{ERI_awF@9EyHq?EjQyCTW*o}a0eQN7pi3}WqbQ~T5_u`2jsRqvZRjgDKKe6G4R%x{* zB@?#XA!!@W;yIh?G|Nx$y07TkdD%%W;MH0TulLeSJ_jLe;G3eEziMA)Q$`!q(Y1iB$2rZC@zYk~38@w|-c`Amlg+$4)2`>|c@Tv+@nukRT? z(Ahs2?d*+q?u%-$euz1C9; zYEgE^&CbzBu+FcM3&@<$+W=vJ(qiDhL+w!7wrrByYwSQ6mG`6d=e`n8jTH=h-;5iEV4$`_G&S=KWX?eQD zx50$s>@j4wsczO0J;Uy~T{%Vlc$?eiS48`G?9Cs4XZwM5TF!4-7>E41Zeha;_S^zp z>M{+5N$)7DX;zQ4(LIcaqv?2-rbP?f?VWeM0L-6v3j)k{o;N~XbIvG=Sa~)zbAVwF z*U)%#S3c5{enIdK)0{lY12mh`hMT*5$mUWoFl&6xE|}2R(csG`la<`##d4A#6x1ri z9qt1q*jya$g5uISlHuo!Sa#^bW0XoR^$t3Dv*rebo*$iL%uSe0LO}9;+j@2Mn&Og8 zfco8;iKn18wmN;p*Q9Q|2zR3RKNnKnL-R2d0t!Au)F9+Ds?6%=uFdr&z7cqQkfU3 zvj?1THsw+AoHYjre=YZe$zePS6@ICrCh^QJH!<3EtlRtM#j@i%R3NC|zUbz3j%Bhm zm-Jq}KGOhfKCRI|qi!b7k4H0IhIVf`mYGXuQuLgJpV3Of?~b?PHhwO$QKbzmpSrXK z=KT^J;$3i<&jBPj&;Hnqr!X-yeh25+sByeXyI6B)Gi~T53+Rqa8Pr%`qqk*1Q<2=Tp~@Ahc~`B*W$ zq~!RLz>UFaEIN(FO-(Oi@f0dgqlA-7NLO_l)lG65OF2_=3d>I6qA6VLz0^#hR-Z~r zyk(bow@at6`~{=%abDLECg5WT@{{Lc!nTxvTt+k6srqJo2s`C^^x|hRj8F1o@FO(% zQ+R+YY|jLI01p~oY-)Y;)}zGCm7T+iVVbz|c|)MWJiAX6FevjG2tG(*1|La~u9VbI zQQzvb;L*2o^a)g)L)~!Is%c#Q@;R&?Zfa_lY1H>Mox+-`E2i--C2l#3h5&~6*!T*T zH&J-gX*BXRs6$K9%>Sp*s-%YR8C==latdv&XR!7h+KK17O-j1BYJF|+46YhFiO{Cd zIcyxR4Nl?eGq`3N*KP{6Okq=PXbK%I&r{_ibnFAzK&#cnE>!aREEeH8)Zhiw<3+S$ z8rR?@T!(YmiO=Ci{1#k%k-_&Ru6~8Qolgc2UcC+NdR`7QpF^il{vM=e$(So0>Xv+$|&XhF!rqZS_Hn}rh= zejZ}s7kIMN)1rqwg_Q6=V4EV;d={Gn*m4S6PGIr!6DU82twiX$muKKRfl59%PGQ@S z#$coIMJIis;pM@x5*DAoPPM+l9~!=iMtp~%^%^$fyM*I=#?(4b=8UP^jDajY1ofA= ze*(rB3xPMWLTdQRGp?`j7?+LTP8yQyUw+h;?(iogIrAmI=B%f}ns zwLda)o6LCijNEEpF4+;pCn-pup2E`<63|1OFZ5Ags0J3}s7KJ>dKNnbkD-PSI|X0B z>P^AgU~>!O>g4&?X5lcZNSGhm%dkcwXpnNF%2iZOp;FHV`4h@YoW!phSQ=;4Ys9bN z8L9w+sDAfgDOXq`7C!R^@eSxn%hyr~)NTdE)3T4-!)SRaA3QDl8Tq^DXx%j@&wuMe zMK2@ZbyRW{nq~D2W-I6!RkVbPt}==$QY|xzwixupc&$LaIx57E5T1JS2$zSs?CBZx zdZ~v|?-P9R)ayHkC_`>{KY`q(h?-sdIFcnBL(4+`>yzlK4K53v#q|LK-@B>QU&J+i zXV5=|Jym;osV$wtyLq3&z$R;1=y60^tM>7IsI}J8+wqW`JpY{X9OPGlQ@Ej(l*WID z6qcab-CLO>A#H@Eo&H-#Sgyhb*?{e`5d(4!a7x{(0`A0O62FX|jRNgifH0lQ;4=Fp_;48%wq< z*C*q~Cvmw)vP_4T`~Dj?0|55FHqBV)>|z-5Au78-o1RY zo4Xrw3nFqWmdF7t7Y9w^@`uMbe{wvGEvzoxGJ)N42Y>TR<2K14&F4uuf_vmn9GAQB zAnzZSdyTU+H}x{M)iE0756?vT!%XI%BT|}Zt5LSRf~htvYu-R87`5=5Wt{qaKHAYi zAk|+LMDAuSinmPRJ+m1qqP*n+*zyr0)hn(Qo~+6+US?o>y+a%C$|yu0rLzpY!rD@> zIK&!5Sh)C$_-%i22aQo9tfotEVyp2i9|I<=3zuKyk$B6M7{8-E6B&I8U!JE0OY4Q@ zy|@;yu*O|z0<-lyTl{
    + * + * Note: Instance methods should only be invoked by calling + * {@link #invokeAndWait(Runnable)} to ensure access is correctly synchronized. + */ +public final class Room { + + /** + * Specifies the type of a room message that is sent to a client.
    + * Note: Currently we are sending simple string messages - for production + * apps, a JSON lib should be used for object-level messages.

    + * + * The number (single char) will be prefixed to the string when sending + * the message. + */ + public static enum MessageType { + /** + * '0': Error: contains error message. + */ + ERROR('0'), + /** + * '1': DrawMessage: contains serialized DrawMessage(s) prefixed + * with the current Player's {@link Player#lastReceivedMessageId} + * and ",".
    + * Multiple draw messages are concatenated with "|" as separator. + */ + DRAW_MESSAGE('1'), + /** + * '2': ImageMessage: Contains number of current players in this room. + * After this message a Binary Websocket message will follow, + * containing the current Room image as PNG.
    + * This is the first message that a Room sends to a new Player. + */ + IMAGE_MESSAGE('2'), + /** + * '3': PlayerChanged: contains "+" or "-" which indicate a player + * was added or removed to this Room. + */ + PLAYER_CHANGED('3'); + + private final char flag; + + private MessageType(char flag) { + this.flag = flag; + } + + } + + + /** + * The lock used to synchronize access to this Room. + */ + private final ReentrantLock roomLock = new ReentrantLock(); + + /** + * Indicates if this room has already been shutdown. + */ + private volatile boolean closed = false; + + /** + * If true, outgoing DrawMessages will be buffered until the + * drawmessageBroadcastTimer ticks. Otherwise they will be sent + * immediately. + */ + private static final boolean BUFFER_DRAW_MESSAGES = true; + + /** + * A timer which sends buffered drawmessages to the client at once + * at a regular interval, to avoid sending a lot of very small + * messages which would cause TCP overhead and high CPU usage. + */ + private final Timer drawmessageBroadcastTimer = new Timer(); + + private static final int TIMER_DELAY = 30; + + /** + * The current active broadcast timer task. If null, then no Broadcast task is scheduled. + * The Task will be scheduled if the first player enters the Room, and + * cancelled if the last player exits the Room, to avoid unnecessary timer executions. + */ + private TimerTask activeBroadcastTimerTask; + + + /** + * The current image of the room drawboard. DrawMessages that are + * received from Players will be drawn onto this image. + */ + private final BufferedImage roomImage = + new BufferedImage(900, 600, BufferedImage.TYPE_INT_RGB); + private final Graphics2D roomGraphics = roomImage.createGraphics(); + + + /** + * The maximum number of players that can join this room. + */ + private static final int MAX_PLAYER_COUNT = 100; + + /** + * List of all currently joined players. + */ + private final List players = new ArrayList<>(); + + + + public Room() { + roomGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // Clear the image with white background. + roomGraphics.setBackground(Color.WHITE); + roomGraphics.clearRect(0, 0, roomImage.getWidth(), + roomImage.getHeight()); + } + + private TimerTask createBroadcastTimerTask() { + return new TimerTask() { + @Override + public void run() { + invokeAndWait(new Runnable() { + @Override + public void run() { + broadcastTimerTick(); + } + }); + } + }; + } + + /** + * Creates a Player from the given Client and adds it to this room. + * @param client the client + */ + public Player createAndAddPlayer(Client client) { + if (players.size() >= MAX_PLAYER_COUNT) { + throw new IllegalStateException("Maximum player count (" + + MAX_PLAYER_COUNT + ") has been reached."); + } + + Player p = new Player(this, client); + + // Broadcast to the other players that one player joined. + broadcastRoomMessage(MessageType.PLAYER_CHANGED, "+"); + + // Add the new player to the list. + players.add(p); + + // If currently no Broadcast Timer Task is scheduled, then we need to create one. + if (activeBroadcastTimerTask == null) { + activeBroadcastTimerTask = createBroadcastTimerTask(); + drawmessageBroadcastTimer.schedule(activeBroadcastTimerTask, + TIMER_DELAY, TIMER_DELAY); + } + + // Send him the current number of players and the current room image. + String content = String.valueOf(players.size()); + p.sendRoomMessage(MessageType.IMAGE_MESSAGE, content); + + // Store image as PNG + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + try { + ImageIO.write(roomImage, "PNG", bout); + } catch (IOException e) { /* Should never happen */ } + + + // Send the image as binary message. + BinaryWebsocketMessage msg = new BinaryWebsocketMessage( + ByteBuffer.wrap(bout.toByteArray())); + p.getClient().sendMessage(msg); + + return p; + + } + + /** + * @see Player#removeFromRoom() + * @param p + */ + private void internalRemovePlayer(Player p) { + boolean removed = players.remove(p); + assert removed; + + // If the last player left the Room, we need to cancel the Broadcast Timer Task. + if (players.size() == 0) { + // Cancel the task. + // Note that it can happen that the TimerTask is just about to execute (from + // the Timer thread) but waits until all players are gone (or even until a new + // player is added to the list), and then executes. This is OK. To prevent it, + // a TimerTask subclass would need to have some boolean "cancel" instance variable and + // query it in the invocation of Room#invokeAndWait. + activeBroadcastTimerTask.cancel(); + activeBroadcastTimerTask = null; + } + + // Broadcast that one player is removed. + broadcastRoomMessage(MessageType.PLAYER_CHANGED, "-"); + } + + /** + * @see Player#handleDrawMessage(DrawMessage, long) + * @param p + * @param msg + * @param msgId + */ + private void internalHandleDrawMessage(Player p, DrawMessage msg, + long msgId) { + p.setLastReceivedMessageId(msgId); + + // Draw the RoomMessage onto our Room Image. + msg.draw(roomGraphics); + + // Broadcast the Draw Message. + broadcastDrawMessage(msg); + } + + + /** + * Broadcasts the given drawboard message to all connected players.
    + * Note: For DrawMessages, please use + * {@link #broadcastDrawMessage(DrawMessage)} + * as this method will buffer them and prefix them with the correct + * last received Message ID. + * @param type + * @param content + */ + private void broadcastRoomMessage(MessageType type, String content) { + for (Player p : players) { + p.sendRoomMessage(type, content); + } + } + + + /** + * Broadcast the given DrawMessage. This will buffer the message + * and the {@link #drawmessageBroadcastTimer} will broadcast them + * at a regular interval, prefixing them with the player's current + * {@link Player#lastReceivedMessageId}. + * @param msg + */ + private void broadcastDrawMessage(DrawMessage msg) { + if (!BUFFER_DRAW_MESSAGES) { + String msgStr = msg.toString(); + + for (Player p : players) { + String s = String.valueOf(p.getLastReceivedMessageId()) + + "," + msgStr; + p.sendRoomMessage(MessageType.DRAW_MESSAGE, s); + } + } else { + for (Player p : players) { + p.getBufferedDrawMessages().add(msg); + } + } + } + + + /** + * Tick handler for the broadcastTimer. + */ + private void broadcastTimerTick() { + // For each Player, send all per Player buffered + // DrawMessages, prefixing each DrawMessage with the player's + // lastReceivedMessageId. + // Multiple messages are concatenated with "|". + + for (Player p : players) { + + StringBuilder sb = new StringBuilder(); + List drawMessages = p.getBufferedDrawMessages(); + + if (drawMessages.size() > 0) { + for (int i = 0; i < drawMessages.size(); i++) { + DrawMessage msg = drawMessages.get(i); + + String s = String.valueOf(p.getLastReceivedMessageId()) + + "," + msg.toString(); + if (i > 0) + sb.append("|"); + + sb.append(s); + } + drawMessages.clear(); + + p.sendRoomMessage(MessageType.DRAW_MESSAGE, sb.toString()); + } + } + } + + /** + * A list of cached {@link Runnable}s to prevent recursive invocation of Runnables + * by one thread. This variable is only used by one thread at a time and then + * set to null. + */ + private List cachedRunnables = null; + + /** + * Submits the given Runnable to the Room Executor and waits until it + * has been executed. Currently, this simply means that the Runnable + * will be run directly inside of a synchronized() block.
    + * Note that if a runnable recursively calls invokeAndWait() with another + * runnable on this Room, it will not be executed recursively, but instead + * cached until the original runnable is finished, to keep the behavior of + * using a Executor. + * @param task + */ + public void invokeAndWait(Runnable task) { + + // Check if the current thread already holds a lock on this room. + // If yes, then we must not directly execute the Runnable but instead + // cache it until the original invokeAndWait() has finished. + if (roomLock.isHeldByCurrentThread()) { + + if (cachedRunnables == null) { + cachedRunnables = new ArrayList<>(); + } + cachedRunnables.add(task); + + } else { + + roomLock.lock(); + try { + // Explicitly overwrite value to ensure data consistency in + // current thread + cachedRunnables = null; + + if (!closed) { + task.run(); + } + + // Run the cached runnables. + if (cachedRunnables != null) { + for (int i = 0; i < cachedRunnables.size(); i++) { + if (!closed) { + cachedRunnables.get(i).run(); + } + } + cachedRunnables = null; + } + + } finally { + roomLock.unlock(); + } + + } + + } + + /** + * Shuts down the roomExecutor and the drawmessageBroadcastTimer. + */ + public void shutdown() { + invokeAndWait(new Runnable() { + @Override + public void run() { + closed = true; + drawmessageBroadcastTimer.cancel(); + roomGraphics.dispose(); + } + }); + } + + + /** + * A Player participates in a Room. It is the interface between the + * {@link Room} and the {@link Client}.

    + * + * Note: This means a player object is actually a join between Room and + * Client. + */ + public final class Player { + + /** + * The room to which this player belongs. + */ + private Room room; + + /** + * The room buffers the last draw message ID that was received from + * this player. + */ + private long lastReceivedMessageId = 0; + + private final Client client; + + /** + * Buffered DrawMessages that will be sent by a Timer. + */ + private final List bufferedDrawMessages = + new ArrayList<>(); + + private List getBufferedDrawMessages() { + return bufferedDrawMessages; + } + + private Player(Room room, Client client) { + this.room = room; + this.client = client; + } + + public Room getRoom() { + return room; + } + + public Client getClient() { + return client; + } + + /** + * Removes this player from its room, e.g. when + * the client disconnects. + */ + public void removeFromRoom() { + if (room != null) { + room.internalRemovePlayer(this); + room = null; + } + } + + + private long getLastReceivedMessageId() { + return lastReceivedMessageId; + } + private void setLastReceivedMessageId(long value) { + lastReceivedMessageId = value; + } + + + /** + * Handles the given DrawMessage by drawing it onto this Room's + * image and by broadcasting it to the connected players. + * @param msg + * @param msgId + */ + public void handleDrawMessage(DrawMessage msg, long msgId) { + room.internalHandleDrawMessage(this, msg, msgId); + } + + + /** + * Sends the given room message. + * @param type + * @param content + */ + private void sendRoomMessage(MessageType type, String content) { + if (content == null || type == null) + throw new NullPointerException(); + + String completeMsg = String.valueOf(type.flag) + content; + + client.sendMessage(new StringWebsocketMessage(completeMsg)); + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.class new file mode 100644 index 0000000000000000000000000000000000000000..c6953a4fd7552b49ed1f466d9d2a0dcc5643dd10 GIT binary patch literal 359 zcmbVIJxc>Y5PfsG4?Ry4Y^*Ho)WR(+M3jICsV-V5vEJQV;>ODz>~6f@WhGen1N>3q zT-4IW8FNmaUfcOgh{1A2AM())UUl&M4pNClf^FWT#r`D$)6+@m|i27gx#$Cv|xEwN1Y_ z7liz-T{&$gwm-7}m+@pFpJjm<3E}LY#|Wc7MbxsHi(9oYI>ZNv_!)f>H^(!k%*2`l f$?+@bg@p(iW6CnHhYiMJJtx>i&Wy0d7@_zA6IENt literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.java new file mode 100644 index 0000000..d425393 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/AbstractWebsocketMessage.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.drawboard.wsmessages; + +/** + * Abstract base class for Websocket Messages (binary or string) + * that can be buffered. + */ +public abstract class AbstractWebsocketMessage { + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.class new file mode 100644 index 0000000000000000000000000000000000000000..ada7b3418ace6e69ca53bf5271611fbe1ad0cbd7 GIT binary patch literal 590 zcmbVJ!AiqG6r4@drj4=HYFnWS9@`2A5%Hi1M(8PeQR;bW*$%w1j?T_ek&Qqk~P$X$aGHJBhOH(n}*YQM! zqASxJ&E;PE>BtT&)E(qeU^x0$B%0-qzVkpQiigSXVHk3)b`J;iAtrqgJy@E9DuZeZ zMOsUQx`Ykd?amumXYUopbEdIrEmJShr2cKv?qG#beXfRsRYKI4xiWGqqq6XHX=ikn c@4UcxqQW2<=<<}@&1{^xU}3|smZ{di0c<*q1^@s6 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.java new file mode 100644 index 0000000..b16e1ae --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/BinaryWebsocketMessage.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.drawboard.wsmessages; + +import java.nio.ByteBuffer; + +/** + * Represents a binary websocket message. + */ +public final class BinaryWebsocketMessage extends AbstractWebsocketMessage { + private final ByteBuffer bytes; + + public BinaryWebsocketMessage(ByteBuffer bytes) { + this.bytes = bytes; + } + + public ByteBuffer getBytes() { + return bytes; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/CloseWebsocketMessage.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/CloseWebsocketMessage.class new file mode 100644 index 0000000000000000000000000000000000000000..f080cee9271cf1ad4ac62628b9ab6e0c1fe67165 GIT binary patch literal 389 zcmbV|ze)r_4936g?H^rNPb@6#?9{?76fHaiIj~x7l(U}M4LZ7a12c2(b6E)%K7bD; zW>0NI5KQ1B-;acZyuH7?0yw~WjsaFPtYsJy(vg{&a7q~L>`n;r*fvZUR%XVR^QmTc zt#m77qq4PXC(4=Lf5AB18BaK>I@aFS4;;$IsZLwvnzHj#_FmnxFUPI*eDmFN@rh3e z`IVi!n$JzYVe8kf{d@JO3dBeVhyPhaIR0boO#9$e9ey5&ZA9{_K1fnd5KYCE3lAiF d&!8s(5i-$KFtCXw(PB|2SVk_6up%0v_y8hvXc_h2t7qFm3rQ!ON_P&WK;XM6coXOKfoU) zzI=FT4}zE7H}mGr&hCDFe|!Qs#*PUcb{!RL8)zA56KX0=!YClv?t^#|&QwH!Gs?L$ z?w*HHm|hUtz14PqOwh05i6k`LFp@X(nJ1H5;Z2#b-Pjk?u}H!Um!zKFhl+6OE~KYo z|52vSBoPZQ7Rkg}sF_qs1X7jf-~EcN3!d}T1DO`#2(4a!H50)c#q-3M!!S$HEyT-C zhuKvv80c82qDDCRS0KL0A9I%;Kd0M?DBk1+)G5@ku)&Dua#v!v2AZX(!#i=WI(UWl%!S4> T@ZlM`pW9f4ptK=u=Blk9M~{iX literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/StringWebsocketMessage.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/StringWebsocketMessage.java new file mode 100644 index 0000000..49be369 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/drawboard/wsmessages/StringWebsocketMessage.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.drawboard.wsmessages; + +/** + * Represents a string websocket message. + * + */ +public final class StringWebsocketMessage extends AbstractWebsocketMessage { + private final String string; + + public StringWebsocketMessage(String string) { + this.string = string; + } + + public String getString() { + return string; + } + +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAnnotation.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..a7c1a0262976140aa6b92878a572ea1a08d04307 GIT binary patch literal 1806 zcmb7E+fvg|6kUh5MB6BM0YyYb(H24C1#c8Vi>PQ7$1*(dmWD$Kv?rY;Mf?=Mz-ONv zeeeSuzsLu5oupDq@x}}}mwjDpuhTEzKYa#p1I08B;%Wxha9w|HWH5=F25#xYZGE_7 z;I4rwf$nKnx#5gJA~(7$keu^Yr9e;7Rq{onR+j#fU9R%xXwh@*>ay*-`rN!shU;!1 zaJKkbmIKe(l%XY^b~kT{;HuuwPH=!&v*4CsS)6i8e@9?n4Zs1;%>X)9X?36jzS!S0#uet52*93+-0PJ=X zNSC~Z@5o24*2A&(8Bb_V1+pC}0_kr_-zr7Ryjrb$t_sOVYRj%Rm}g*@05nA{N=>AZ zF_1SggIN>zF=t@j#3MXr^=O3cGBEK3850Y5N+>N=>7;uEDbU-Jz+!nrIvo88eYKAq z+ni%P{;JK7-_AJ4x{@zIM)IaM!UUuo?dYm) z4`NRl7&36iz*)f?=+8HXo}-(_J~)si-DPii7Mvlb zd4HZS01FHvL=j>_ymQx!;h5<*?y!bo&T> z!t~CCclOL7Wlg3(;?p?+guz;bFU!h!&z_Lf(6lmgNVmm_Z6Hkkvy!or8v1`-O>L-a Sp{=`xj%rUQ)*Gr_()|K-TRr&z literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation$CompletedFuture.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation$CompletedFuture.class new file mode 100644 index 0000000000000000000000000000000000000000..5ed8542e4b15517481740376ac7df87e6032c36a GIT binary patch literal 1714 zcmb7ET~pIQ6g``Mq?9TZ5m8hSL0S|-0a1iu>{OV6>FA6g54@%6T7u~Y^MUZ-Kk`9e zaK;CJfIrIdZW2l?8G)C3v%BYH=8?fn9$6VO&}5iZF{ff)#R5Zi z#T2Hu%8)9RcNo$&yU7{)>Zagt{C0yo+j_&Io&LIQ=+=(zm~tI$roBDWC3MYhA6VSu z&2``N9YPm2gy2ri(p{GmV4?n*H(cBJ$UTi4d$zVlq3RwBqbh{$>7Hqe@h*{Ns?E@a z!7Zw)v|HX~xYgE=H-yI>$3O5kKD_gVFhz@j(OIwQ)&jJ}o55pfFKfE5Z9(OvTHK>2 zl*;ve{ZQ8|U9_|v+icPu`L!d1AIJh+70*;GGR&1WL!9rKmS)((@EwN>Pun)z{5^GR zIYCGD=+O4*8n#IV`vhYcxj;w7b860&u6x_q=Y~gx5B&3*Xj{b#1~8OMm+5$AS&m#e znq_!=IXpwpme~?|IOS@rolybF4-Rdy5`zcbUzPpevVF(k>!vi>P=YUJfJTpL8F~e}M)jjJ|CqFnNbgajl9n&yOCeqiAxIvP(h#@BukAYX-EQA1D zLy=YtH_%T}k{2l}l$F$18Dq>=z#I%uBc?>$!~k*VCyc>J<7u!?(y(H;E1lbKpJ%4K zZ~v6YB*RbzvhL2E>|0mehY8HPgvk&3Uo$NbGFJCrJNKDif26 zUQ8p;VUntreOsa|=Pk{`lFbs1{8WgbD4|TW6sCx%;0ZNf=4td%?x(K|D!5Ma6O>WR F{RNTyV&wn; literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..e4bd6c5839b535bde71ecff6e5d31fe6495af9db GIT binary patch literal 2844 zcma)8Yf~Fl7=BI&EQD>j^a>26ttUQZEIVLRi|8aXrOB)YPL-orr}Hr zw8Vz90^wOJPdHukhN<7FmezDTqpcNr(mQYEv|?7X4Y~IZ!_Ksb~c{O~l;zHWLl|G-XnK54g$uGCo18 zV*y!eGpCn*{|a*>ZEMu*=ax82m4bxh=E$YiBaZ=wnO}!@+!r{McC_5%1+DBNRY21F zmaC>?l=Q4oF-SoJ8W|YagJaS3QPOXZ1fDcZ&EBd*ABsIl?lG!?ccF$JBn2XMfE5Ld z+vRY{G7EJ_r}uIgkWWg|LgiAeDubK^)dbq7az(!sB5A8?=kyzfO#I1xk~t>HQxU_k ziXog<@tRzscwNOCI45wTnOwgzRjk8M@JPjD6a`K-)aFb_x9w_~EmcP>aL!d|Zlu(v zp5vKi1~mH{uKYCBg)+{P0#k*BPgU3;lT{T@ut8E>vsbl;icM^(_za&b_(H{(_)5js zcq(wAQLi$!`_+52X++2(k9Tzy#u&m>+of75TV&Jq* zE0=XMFL2(gphU14hWGSGW4H{smo#UkHVIn_I^#VW3wrQSuoF%Ouga|3)`pxWZjrh* z6D&`^83Yc~qdQHO^^)bVBwO8`K+L}+Xyxgo%zW80OegAU^5S;K^4h#PG{5;3d`prg zu!Ee@SB136IVLb3#N)g2f$z@`LuuWx4HpF`fb7mr$Epu!&Y;+^?0YYfreB%K>cfY+ zP2q;El{tx|rI(sGeKX{W?()(X%aqTkkpAr58hvP5Mwz>mF z`sc~$HriJPzsFT>T6WPPu<`@CCc-bEuJ(m@aOn5=$Sw{uQYvqwYZu)i)B=3QJBEm3 z6cPW~$=hVCV~h~E0EHhny||14T%pDUb*HI4N%=c?3)gT5?;?$)i{TRE9HXak+J$MI z@zKa%7jel&n4zyLyj7lErH2;0&EFje_pU0K=6y3lpzqVYJ3V>o$)5f@8ZlUMGS{3gHw}Gs5t_=gUOgBoXhCh+8a` z+tgU3ZkpOlgt$x~8UDJ<|CKrs=L1A!>qKM;|C&og)}=%ek!>R4o+M(ByvoWHm}#OU ziCMogE>lA~5RDR(%mJDk#c@wqzgyrsQj`Z7ZpV#!8Ar*m{8L}x#H!fA$)6CCo`qWw kp657y-sD+`Yz*?*Pn!X@5xU#?W!gt(BK%TyP;Tq^7yi?}Q2+n{ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.java new file mode 100644 index 0000000..39df783 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoAsyncAnnotation.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.echo; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import javax.websocket.OnMessage; +import javax.websocket.PongMessage; +import javax.websocket.Session; + +/** + * The three annotated echo endpoints can be used to test with Autobahn and + * the following command "wstest -m fuzzingclient -s servers.json". See the + * Autobahn documentation for setup and general information. + * + * Note: This one is disabled by default since it allocates memory, and needs + * to be enabled back. + */ +//@javax.websocket.server.ServerEndpoint("/websocket/echoAsyncAnnotation") +public class EchoAsyncAnnotation { + + private static final Future COMPLETED = new CompletedFuture(); + + Future f = COMPLETED; + StringBuilder sb = null; + ByteArrayOutputStream bytes = null; + + @OnMessage + public void echoTextMessage(Session session, String msg, boolean last) { + if (sb == null) { + sb = new StringBuilder(); + } + sb.append(msg); + if (last) { + // Before we send the next message, have to wait for the previous + // message to complete + try { + f.get(); + } catch (InterruptedException | ExecutionException e) { + // Let the container deal with it + throw new RuntimeException(e); + } + f = session.getAsyncRemote().sendText(sb.toString()); + sb = null; + } + } + + @OnMessage + public void echoBinaryMessage(byte[] msg, Session session, boolean last) + throws IOException { + if (bytes == null) { + bytes = new ByteArrayOutputStream(); + } + bytes.write(msg); + if (last) { + // Before we send the next message, have to wait for the previous + // message to complete + try { + f.get(); + } catch (InterruptedException | ExecutionException e) { + // Let the container deal with it + throw new RuntimeException(e); + } + f = session.getAsyncRemote().sendBinary(ByteBuffer.wrap(bytes.toByteArray())); + bytes = null; + } + } + + /** + * Process a received pong. This is a NO-OP. + * + * @param pm Ignored. + */ + @OnMessage + public void echoPongMessage(PongMessage pm) { + // NO-OP + } + + private static class CompletedFuture implements Future { + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public Void get() throws InterruptedException, ExecutionException { + return null; + } + + @Override + public Void get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, + TimeoutException { + return null; + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$1.class new file mode 100644 index 0000000000000000000000000000000000000000..023557261ae19989934cfe9660c42bf412e2d871 GIT binary patch literal 217 zcmaKmO$x$54255`TCD}^S_BuaE#eWRf(vos3EFAsk7Y(Wqu$Mh2k=m0x^rbhUU-oA zk@x5M0H^`#-s!$7u& Oq3Bp9kQ?e;H2MOldo^4D literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$EchoMessageHandlerBinary.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$EchoMessageHandlerBinary.class new file mode 100644 index 0000000000000000000000000000000000000000..e6a13ec6aab236cfbfc20d4bb20874a72277137f GIT binary patch literal 1624 zcmbVN%Tg0T6g{1U88U>oAP`i<6hb0K1n~hr2%umEP@!13>kKW7h8b!yD13z9;hHMN z(uL*9g&$>kdJ-Oqh?I-zp64`?tOW}<;(QxvKqGFN7`0G` zF%!4+@wkaQChnS;5NP++rWdGLcWuja+#n}Qj&0(;KwbDMkeGK}9|htKwxO_Y%W8q0j?E_c{;x|yJM@Z!0}vSn44uzhZZ#e zl*_CJ1bHdYxEx6P&4SztwXt9Vot3yn>8@v&3a^zN=%6N;R0zzSF|VhlU}Qq8i0s_Z z!-&A8e^@g!%g(whgKeM6&1cdN99a~2Ue3XBs()0yx;megL7leL?e5lGeAo^+uEE}X`Xm5UDQN?Il5t{rrL^Onym9X8gAFKuQqc?yWY z#abrStWPkgriwm(Tr9R`1D`fs6n>Ioi0DFbr=6?ETtzrr>CcFyGoKLM<0^u49Gej3 z_=p};#L1z9tIo1D=Ps`37ozgY=(<%f-_tL~vt;@sqCe22r%dk`#G?3s`o-aW7<)7Y zNp$cl7!8BgJVc;|&JNYEh8`4T1Qb^(gE{1qXT%zO%E)%I9 z(YBn4{#eTtsa>g18>6olWu-IUVfOB${z$G7VoZe565+d5j=`+8VxWRBLwt>3q%)r( zPWJ9ATO2YpaFwaoiVX~6C`3qe6~Q$Ohx2tbbMB|UMogl~(7%e?IM4K^IHRSWCA^1> G5&sR&--by5 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$EchoMessageHandlerText.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint$EchoMessageHandlerText.class new file mode 100644 index 0000000000000000000000000000000000000000..d159f563e72dceb71141be3c7d85399f576900f3 GIT binary patch literal 1604 zcmb7F%Tg0T6g{1UnPdoWK_$Gzh>!^3C7>Y4v!E(~B@_#G!=wua!VEPTl%McBTvMe` zy0Bci@S`kGPa=?*LR_SKy64_=&pEey^7Gf%Zve)yY#@e=0RzJ^K8@6(4x>884Afv; z$8+_1LdTSj7doZ|T0D8|`f}OHow&B+FPH_}((y{5CU_KxuQ`tN7V~DIAPWM0*+cW4 zd6s!E_X@6cB>l|WGJs@|Mqq8mc5HuEV4(kQDFZtKkwrHr1sbxpBR5Wu_oTON?&Z1D zoOLZTzhio~T9-B>{(((OZOhhyyDkd_b6>8SPA<RNUMY$YnSiPg0w@M$GRuV#I!)h22=>A7EJ=wDN z9n(McC|iGHdcJMu1vYNTD^dNc*X4~#mU3rqWR`55rE|uXd+J$o#a2CUy4kKFWn>&p zXja2q9C0+p@fz(s!hy%-U5H~Ia{`T(_Q&xM?K&0&M*sh8l;IWi>R9BRP*rYTiRzkl zED0nlW2;>sfzI35v18$W)xl^%I=SLmZ#d!E^n>HH?U@$sOWXn>&{fH!oO6|ca-!(r zhs5B4tmUs+b%URu2tuku+-c!zg{u%}BXx;TD*YMZbFMyXfit1Sj^8@oDe3wXlLih*j)s*h|f=C!25#1QPfOgJMkVGrLc;TQ}J2dW$ zK*uQeC;4WaMJ5P36%BxGzlBNMr@cweXpFLjFOk+_zX8-7eb)d0 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoEndpoint.class new file mode 100644 index 0000000000000000000000000000000000000000..fb2cdadf103704c8a4281519d29e5982fc50a38a GIT binary patch literal 1266 zcmb7ETTc@~6#hIf^WvRUgwSZ40KG0w=DVPW$@p0RZWwp$b-9^!V1&RVC zfieMv)N7@rTkl$)Cq2UALF?Q(lAdREKhWHb9*LGAbbTQ!99rfPs)U8%Cd|3=!tv$ceBbiymcS+<9&8EukdC(_3^TxStj39R<+kK2TPH33 zcOtfQ=qb!#R$wcI3Z4_ThlvO!&eY`5YU+|{4b>F3u|wGXKl-2=Mjz_FZ`*ER4hY_2cq&q#q=+Mo3A1% { + + private final RemoteEndpoint.Basic remoteEndpointBasic; + + private EchoMessageHandlerText(RemoteEndpoint.Basic remoteEndpointBasic) { + this.remoteEndpointBasic = remoteEndpointBasic; + } + + @Override + public void onMessage(String message, boolean last) { + try { + if (remoteEndpointBasic != null) { + remoteEndpointBasic.sendText(message, last); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + private static class EchoMessageHandlerBinary + implements MessageHandler.Partial { + + private final RemoteEndpoint.Basic remoteEndpointBasic; + + private EchoMessageHandlerBinary(RemoteEndpoint.Basic remoteEndpointBasic) { + this.remoteEndpointBasic = remoteEndpointBasic; + } + + @Override + public void onMessage(ByteBuffer message, boolean last) { + try { + if (remoteEndpointBasic != null) { + remoteEndpointBasic.sendBinary(message, last); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..de6f561eca4bfe4f4c821bfa01e97b9c4841cb47 GIT binary patch literal 1850 zcmaJ>T~icS5IuK47+D5TP|z4a5#zED#%Nd#i$o!qU>4V~gjDI%u-q)8%gol!ERvt% zd;UPG5>nVPI+C6q1FK~V^ngVTM)X?sc z!bHbbYDV>DR5p6KvFiC=w5E{E&hIItHi84KFk19{{k(a!uN%AWevO*3Vo-5wdv3#% zb4!_u4!uy}cJZy=4};1Z9XYyk7&x00F~Sqy45hQen6pxs^BD zZoNe(vw2d{bxAg~uug=XrXP7ndd~|zlJ0UL=j(mwCBH?BOfL!3bWkicO(9bbnvIHn>PbJZo!6r!sh7f? zzCfXF9P5TtHp`}eP!BvmBG2@(TWd1fOiu%a`q}2&7{j=Y5sX^cu<;eXwy`>%C{Z60qwiLFwnxeAk_ zJ!j|?MyfhmcSEnTqmP1!%+lthU~l=pZftOPIDiV-?0jF5VwZMx=8R*(!uJYuXYtOv z%6TMsS^Ed^^X2@uK>qWjN7{_qx6R%7KCKdjvn_$;c8FxGe3pP zZH!($BXNRF#2;(T@K9m;|7qbSe_g};$0hi&^^}kXQ>H+67^l39iKEqQQGCbt*4K@b`{{`W! Bsl)&P literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.java new file mode 100644 index 0000000..7aef821 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/EchoStreamAnnotation.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.echo; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +import javax.websocket.OnMessage; +import javax.websocket.PongMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** + * The three annotated echo endpoints can be used to test with Autobahn and + * the following command "wstest -m fuzzingclient -s servers.json". See the + * Autobahn documentation for setup and general information. + */ +@ServerEndpoint("/websocket/echoStreamAnnotation") +public class EchoStreamAnnotation { + + Writer writer; + OutputStream stream; + + @OnMessage + public void echoTextMessage(Session session, String msg, boolean last) + throws IOException { + if (writer == null) { + writer = session.getBasicRemote().getSendWriter(); + } + writer.write(msg); + if (last) { + writer.close(); + writer = null; + } + } + + @OnMessage + public void echoBinaryMessage(byte[] msg, Session session, boolean last) + throws IOException { + if (stream == null) { + stream = session.getBasicRemote().getSendStream(); + } + stream.write(msg); + stream.flush(); + if (last) { + stream.close(); + stream = null; + } + } + + /** + * Process a received pong. This is a NO-OP. + * + * @param pm Ignored. + */ + @OnMessage + public void echoPongMessage(PongMessage pm) { + // NO-OP + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/servers.json b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/servers.json new file mode 100644 index 0000000..c816a7d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/echo/servers.json @@ -0,0 +1,20 @@ +{ + "options": {"failByDrop": false}, + "outdir": "./reports/servers", + + "servers": [ + {"agent": "Basic", + "url": "ws://localhost:8080/examples/websocket/echoAnnotation", + "options": {"version": 18}}, + {"agent": "Stream", + "url": "ws://localhost:8080/examples/websocket/echoStreamAnnotation", + "options": {"version": 18}}, + {"agent": "Async", + "url": "ws://localhost:8080/examples/websocket/echoAsyncAnnotation", + "options": {"version": 18}} + ], + + "cases": ["*"], + "exclude-cases": [], + "exclude-agent-cases": {} +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.class new file mode 100644 index 0000000000000000000000000000000000000000..9db474e6d1fefe977aa2bca5f752478a885af20e GIT binary patch literal 1110 zcmaJ(Z&%zL~u3`g*jI@kyXKUDC-D*g&ji)s{1-YjFyEF|eC~8>6t+9wBp<#iEBom8FEFnP^ z&Zo%O(URM4&!f@_Jv+g?*4n3Ypqg8gv)Fa5e!no`cD9I%SqnRPy0{pfue6f_aRCU4 z4o70dkw|eQUcg+M^-2*U!dONI0cZ_Xs2#e;3l`z=*Wwe%p*uYAm`RH$B@2o^JKmAa2dB5ciiDV zIuvA~kC}X;PT1G^0kIjAgU3*g5ax<1awWnQEyR@>uFOhYiE?F5=E}VClQINHbaqW~ rgoxP;jWA<2r4gcLQyyX7Jc7Vzo{mMOK0vfeH2A=nS`KUU7Qo%V^ort8 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java new file mode 100644 index 0000000..4440c9d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.snake; + +public enum Direction { + NONE, NORTH, SOUTH, EAST, WEST +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a5ac3067911402a7d7c14532710d8ee49652ed69 GIT binary patch literal 813 zcmaKqZBNrs6vzK}>(;JzGVy6JohTJHMJf_~qcI^+B5_-d9q@uzcij!UthT1@;3N53 zO^h*SAHWY~JhxG2jF|ME|M}gXhx_#H`CN2z+wd^8Wr+xD7>koso<6}OUm3< z=8leK9V-mB?Vrgk7-rE7|()GMlyTOP;9ji z7_{wpC>Z8CG7`PXn}JCBd=S#id?yZgc)$~>_~&HR&v-DVMmf{E7)(E&B!SqKDygcH zRJ-*Pe#)t=8wFvU%ILT&vQa$Lv8tnGp^bYMEL1Jr$C`x)SZ7#NDNe|vW2YDUlVG$f zML2YmBu*?iD(s;$8_GPw8YTSRtdnon`PJOsU;u-)7eyl34tbi2l%Y1O?+s4qR2b^# zRbW{7`_~^QSw7|AM3ro|+DDyp1D`UKdfw~)3x>vjqx3i#%7};gozNwfd~aW6Y3`Qa zCpmO;>3Kc3wnR_k0zDO0tE&T49t>Q>9BGYciXwTy{%5f1SMwtZAJkX;1WohaL3^2F znXoiNov=JZgHWGgh0w_HJxZwH3a*pZv5XbcRl1DFq))Jg9a0ys;FA_{iI!2$7t_Q% l`2`x6X*6IS>Qtrs4?}5J^U!P51kk7raF>Qjg-k^?;|HlouowUU literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.class new file mode 100644 index 0000000000000000000000000000000000000000..284addb81a29bffde625ea018db44a9d0a597fba GIT binary patch literal 1322 zcmZ`(O-~b16g{u)bZ9e_wg>_R<)dOdMG7Jy0U-usf&op$kf1SPXeV@_PO%*X`7g$m zE({Aad?cC}S1#Q6hm7&O>9iIIP44TwJNM(9b8q|W@7M1D#xNB|2sc9rA|;P>2w~`9 zWH6-SR+ye)8IV;mqGD740@{LYo8|eUQK^^}0kKD0puH6c&RDkP%nB%}g@yErKw!R< zHw9W2E!%v&^J?8JKQq>g^u!lSIit8@lr4GpoB^j`v0~TauDM<*<+e;GTd|ETGb@7~ zt7K0Lv~HNr{rskpGi|5l7MM(3$a!Fu&77N*zVNP=$a=Ye=@N#LVoHHLuT!A_y>(NPfOv$=h0=^d{(peAi=GYLRmdbg{Hj3oW ziMrdw;il3Jdb!SN^l=G8+*KcUk9_&Wg>t_Gd?Fv7ae7x7;pcaYehQ%{j^We0kKzC9 zrnd5oBfztRXD17Gu|xt_=;^Jdp$+Z4v4Go#yUr)sNH)I8ylR`@Q0M{nzaWq~finC_ z<^bC?nWNB>v`N|{+DqE@Hw0JpBO*G2KN`-TLOnd|T5EJg!)r3|tSeu0>4&W7hh)@6 zX@F}OB8NHj<0(6v7{nfQmsxuiX`R_VnRgLof>|n*p*TOhcB985_s-LBO3!?R5;(~G zL_|M96Nxr`fZ{*M{6KI?G8v-1mmUd=7r%Q69Gt^8!ak$aZj3F)iE2XbUW4jWb!=1Q zah))F2&b2m@VO{8C~8FfK}#PrL3+UdK>qrqxY4G61e^Z@ literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.java new file mode 100644 index 0000000..acbfeb7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Location.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.snake; + +public class Location { + + public int x; + public int y; + + public Location(int x, int y) { + this.x = x; + this.y = y; + } + + public Location getAdjacentLocation(Direction direction) { + switch (direction) { + case NORTH: + return new Location(x, y - SnakeAnnotation.GRID_SIZE); + case SOUTH: + return new Location(x, y + SnakeAnnotation.GRID_SIZE); + case EAST: + return new Location(x + SnakeAnnotation.GRID_SIZE, y); + case WEST: + return new Location(x - SnakeAnnotation.GRID_SIZE, y); + case NONE: + // fall through + default: + return this; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Location location = (Location) o; + + if (x != location.x) return false; + if (y != location.y) return false; + + return true; + } + + @Override + public int hashCode() { + int result = x; + result = 31 * result + y; + return result; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.class new file mode 100644 index 0000000000000000000000000000000000000000..afdcf77a6af8f4fb447e357bfdd01543a9008470 GIT binary patch literal 5122 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java new file mode 100644 index 0000000..7a11222 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 websocket.snake; + +import java.io.IOException; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; + +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.Session; + +public class Snake { + + private static final int DEFAULT_LENGTH = 5; + + private final int id; + private final Session session; + + private Direction direction; + private int length = DEFAULT_LENGTH; + private Location head; + private final Deque tail = new ArrayDeque<>(); + private final String hexColor; + + public Snake(int id, Session session) { + this.id = id; + this.session = session; + this.hexColor = SnakeAnnotation.getRandomHexColor(); + resetState(); + } + + private void resetState() { + this.direction = Direction.NONE; + this.head = SnakeAnnotation.getRandomLocation(); + this.tail.clear(); + this.length = DEFAULT_LENGTH; + } + + private synchronized void kill() { + resetState(); + sendMessage("{\"type\": \"dead\"}"); + } + + private synchronized void reward() { + length++; + sendMessage("{\"type\": \"kill\"}"); + } + + + protected void sendMessage(String msg) { + try { + session.getBasicRemote().sendText(msg); + } catch (IOException ioe) { + CloseReason cr = + new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); + try { + session.close(cr); + } catch (IOException ioe2) { + // Ignore + } + } + } + + public synchronized void update(Collection snakes) { + Location nextLocation = head.getAdjacentLocation(direction); + if (nextLocation.x >= SnakeAnnotation.PLAYFIELD_WIDTH) { + nextLocation.x = 0; + } + if (nextLocation.y >= SnakeAnnotation.PLAYFIELD_HEIGHT) { + nextLocation.y = 0; + } + if (nextLocation.x < 0) { + nextLocation.x = SnakeAnnotation.PLAYFIELD_WIDTH; + } + if (nextLocation.y < 0) { + nextLocation.y = SnakeAnnotation.PLAYFIELD_HEIGHT; + } + if (direction != Direction.NONE) { + tail.addFirst(head); + if (tail.size() > length) { + tail.removeLast(); + } + head = nextLocation; + } + + handleCollisions(snakes); + } + + private void handleCollisions(Collection snakes) { + for (Snake snake : snakes) { + boolean headCollision = id != snake.id && snake.getHead().equals(head); + boolean tailCollision = snake.getTail().contains(head); + if (headCollision || tailCollision) { + kill(); + if (id != snake.id) { + snake.reward(); + } + } + } + } + + public synchronized Location getHead() { + return head; + } + + public synchronized Collection getTail() { + return tail; + } + + public synchronized void setDirection(Direction direction) { + this.direction = direction; + } + + public synchronized String getLocationsJson() { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("{\"x\": %d, \"y\": %d}", + Integer.valueOf(head.x), Integer.valueOf(head.y))); + for (Location location : tail) { + sb.append(','); + sb.append(String.format("{\"x\": %d, \"y\": %d}", + Integer.valueOf(location.x), Integer.valueOf(location.y))); + } + return String.format("{\"id\":%d,\"body\":[%s]}", + Integer.valueOf(id), sb.toString()); + } + + public int getId() { + return id; + } + + public String getHexColor() { + return hexColor; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..266344c56a18d41e958b17170f9bee8fc26bceab GIT binary patch literal 4408 zcma)9X>=3U75+w&J+eFoTLBvjvx!Z{1{Ffm1Um%pRxvh3#?(*>V`+>9@{A*mz=V*{ zhSG)ZJKfTz3tiGSfnb}s*}9}{(x&O2?&+R3>Aw7EPfEY{MzZ9Eb7~*InRnk^zkA=k zqqr)#!e)|G0Ti)QYpieUC5r1-n6n4av@Qwg!p65T@?9x3e#d}-az zq;xxBnG8Rf8BUnG8RKD5%&}MQSksT$Vd=p%w}fs-w1#fY3?p|+5oMHr$LU|n%9!!y z;~l9)Jes(bc08d-Ez?wVRHTQvH73l2y;XrbRNKc>dniHdSIp8aA!;&B%a#t%M6qS| zj2MifCL~=R4d?xd8tF76Y!E8F3EN=663c?zM6y(BQqvB*g6gYkVh+;-IfigSE}Aom zWL%a&<#gnakL1u_KZn`Ixg%`YN`K0twjMjOLm!dZ<8@Z?2u<(Gn08{==u4y%%xoSD z;q0BOSjZu3CL(~ru@P!Uqg&|0o)ZrXQwt@>{q?*NZSjg%W2wG-K(n?eP zYy^9pBZsRkl@f_qROm$SP|7+cidFid*!0l>OnQ(%l{HEXSS2aTvQ<3Fa&8-q86%=3 z({ewTd1;g8y^XPCw%B}8E0c;D?Fn&X7R;!v4dUJ_SUW4?w2?Y$q{318Xfxv@R>HKY zxV)h9%yNp=yeosRu zA}YSG;RkqH!w>Nz6+hN6fS<7FH2f4l)9`b!RaTz}CgQ;@%U8$imj`99;3l{_9Xv?@ z@?rH195!OMhF=Kdzr?RJ{91VZ8~m0R^+eF-tq^jD30<&07}sq*xMkn!^!}3?euojJ z_Lz~T__O%Eia%(04$o`&BmTtPn^wvm((q?IPcB0jTz?VoMQJM|4*n`w|Awbot9d&~ zLqBQ+>2cO~n)y5a!JJEv6IQsbr+un~6x2%c|I_jXc>l~rE(M&%tzg-lVCSzZTXfz^ zt_vx+CXeA%$+JV7yu0m5OJ~)yL$ZOZg2K6@V4jqiYSao!IX*h0&Dp`RFx1}Oo}C?2 zOsv*oeS~e3^Qb1&GJCY-+gY&~Mjg%4E*o}5-oNbBqe0u^pmJuC=q!=h`o#6fOXgTh z(wTv@9AygD7xseee4DK&@0ZuMa%ze~k%(yV^XY1n8IPE;lrhX9tzbzgGVA&l4u!y+ zN$O>LWq0!G@wmJp3Id_4^l4$Xgk~k5=)k!#Eo*@(Nb(wp5tOU78FU4e(EoyI7XE=B&DCf?BNW`koeNvJzqw$)jr*p8eKP{0C6hNGCIg>-(U_$y+b^Fb{Cx?w zQ)3r*cfk!0pB)#VjKS5yM}_*-7~B=^XAhq7d(2jUQCo23stFW#PeSb_%VK*@KjGQDT+w(shbnPN1SeY?No5P2(i|{ei{f zxF+w(JZb^qEF+KsLLoe;q@FTVVUL6+z<*X=CPDOxp_jGRP9E`(OnJb2upv9gV3pl*;DFJEMY#qZW4?7*WHh*x^YxrLV&M<2`tWLY{vv@ zE@O#;?)8_kRKYnk^JSTWN3dv%r{2H3=s~RLcULoy!3nI4_It$Zs^|n(Gp&1aLcaR) zdZvEQ`74wDH6AI#eYs$pz*-T5N5Zm+0DzvCGr?6%=Q5@@#Kdl7N*kHf{Y>Z}p&usL zBZT`-0wiGD%vc)9CF;~eiB5hS#ANbLXJZFWBMyTYEaN(eL&RZ-k^*ptKSBP(q*TED z0zxW|s7U??t^X$DFv-PaH2G9u(X<2+EPMU}eg0707;4X&8%b9?kyxX;c0x#G4;WH+BKr;44D zvv?y%u!L6f6}&WSKZjgKS~`kjjL2yoE+z`7b>CFiO<*=Zh6Od{3+~1|vFSeTQqEs_ zZvCUU?i`BGqp0rTJQzWEDR?VgK0y_?F<&PM%I$0cr?7@u4&jV+M6?PTm;#~}qd3m+ zTv$u#Mm{}QO&!OxdDq~10UkxgZB-=-b&8r)s5ckF9i(_^BX=P;QBM3+PU8B0_c&gB r5ep}A1N+>K7oiA$6`4FAErB*m>6r_! iterator = SnakeTimer.getSnakes().iterator(); + iterator.hasNext();) { + Snake snake = iterator.next(); + sb.append(String.format("{\"id\": %d, \"color\": \"%s\"}", + Integer.valueOf(snake.getId()), snake.getHexColor())); + if (iterator.hasNext()) { + sb.append(','); + } + } + SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", + sb.toString())); + } + + + @OnMessage + public void onTextMessage(String message) { + if ("west".equals(message)) { + snake.setDirection(Direction.WEST); + } else if ("north".equals(message)) { + snake.setDirection(Direction.NORTH); + } else if ("east".equals(message)) { + snake.setDirection(Direction.EAST); + } else if ("south".equals(message)) { + snake.setDirection(Direction.SOUTH); + } + } + + + @OnClose + public void onClose() { + SnakeTimer.removeSnake(snake); + SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", + Integer.valueOf(id))); + } + + + @OnError + public void onError(Throwable t) throws Throwable { + // Most likely cause is a user closing their browser. Check to see if + // the root cause is EOF and if it is ignore it. + // Protect against infinite loops. + int count = 0; + Throwable root = t; + while (root.getCause() != null && count < 20) { + root = root.getCause(); + count ++; + } + if (root instanceof EOFException) { + // Assume this is triggered by the user closing their browser and + // ignore it. + } else { + throw t; + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer$1.class b/test.dockerapp/tomcat/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..59e00f4837bf796e33c4af6f6645c1d32d5aa751 GIT binary patch literal 838 zcmaJ=OK;Oa5dJnV2gjw*K!CQiDFjGTz(E{?xJ0dll!8Q}+&9kF-o)9B*6W6U#JML5 z2YvuQ3Nbbn^wQe$ymscB$Buvf{_zvQTfA~n#jcBOJa({`@%<{AH5}lHgQpH!43&3M zN&B9m*zQaiN&`I;44Xr##K&|w6=uw*F!T<*EgHpl_VxA;| zEPKPXm?k<{2tnIX~lm%vI=rPL(B>qc4G2S*aB{ zZj3As7AJg_r=%_z+>uUAAdY2L*XDoV*BKC5j#LoqM5^#a*htSDJoE4zu7_J0c>$MU z`}&+7+UPKJ2RscU+qAm5GU7}q60_=?r$#TENt9Yk8JaV_Rt~xz4)KzDxv6W0dY(14 zGWPRHjCr!4TCNYGUK7iW&AsVztPCi?KTl)n$2ttD zIDe=^n&8e2#|&j*j5gG7`^r6hn$AUF`&TUE$mn%;^Zm{QJvg*i*;Am8rb-J?BgrRD z+kkTS8`yb%>=CWxMve`Vy}u5)jk~1LTKx--QOx1$7btwC1-w9Mt9CGS;C=(T=MPxmtdP0Jdd5Q+XI8;v^_wu;ch2T|5IThy=(wuUQM60(XIsu~=)VpbDdKBU6aunCq} z_+1E4@4{8QD28h)t_uw>iQ#3j>%(GrC5exycvVb4s^Me!xH$R=c~ortq>4|e__T`8 zX!tBXm&E5ar11rT?29VCq+uVd4&oLcf==VhV)%-Nui|SezAlhi3ZOtQIF98_R1Dv@ zdVaL! zNfDoGGlhwB&!0Y1JUOpGnN+Z8!gc(>aDrK*Qm5fg-!Ybiy=?5X={jcJ^DHOGaeFj< z+VB_88#Q5c+AcdrQ1^I#=Knl49`36cgkEq0t897s;)~XT@0v?ikdr8K(*jHWI8Ahp z+m0O^Ck@&CvkDRuZi&XW6m7?vs#g~*Z^l@tP|{O$O`|evc(zza!bGrW)1&^@`d6t* z8l{pnsGu*~dTUUO2X zKq%O;mdES0RW1*Qv9U1)d&%g->m@mER-(+(rro+{T4!yM zM_VMLQs=0^q2mx9)iI7^I*#B;9pA!hI-V2DZ{sx;-_h}1ysqPW_`Z%GprGQ1I(~#7 z>-Y(Ns^fz=#)Mh#P(-(mr^SJv={S#{lP(>hH zey?EQbMb7z4`S~e=o>cBd4&9rJFVabu)(QGfQo0e!Liz@!0Qcg>OAd|Kp z!{e;Xjn54p($T zuZ0pDXpDleMKM9IiavSaGD{>|h)Q`)6Qhz^ooRj~p5`If`B=e4lDLLQM24gdHjC{| z^vzB|`Hs3%bxZbT+2oo}6pY5ZcJo1g!=BR__75`J0&Yuiy{#|_HsUr`xn?I(7Y%>P zx<*Dw?nN@~$VKn!eo0=_^)PeUoHp`=soBl=i2fwf(4X{0F0NG|{@0(Khz_A@xIye{tzu2_epj%~=lx%*SFDr4S^Jt*dWMxLudQZqWRcAn{!)H&Qe0b|rs0@Y zMM35v9r3JT^4hr0-I8LyaE!&hl4zJr57Ch4d(Hq~#ef9*MAPI<6IIUNK0JZLe6x8s z=WWPx%~s0wQMt}@pCURe$K#ab_{$d|bPV4`+by}}JsdlwFpU$O>){5R#3`;uFoDyQ zh{KoAE}!+^MtcK^*U`C*4$g-gVy5yZIVW_sL+I=wSn$Owg;DAp!yW=ZK}o2;A7^lu ztEc#-R-IxtYN*T^4Lj=`e^zD4~O{nti{(yaq$6*|3U{rlaLi`n!k(9=a#YM9=a7258T66g}2ri zCp`-Oif!jd_^^TA;gJTmH?U)Fb&EFKP0`M|8~6Xwvn%mu?4B1y_DwHi&ocT2&V+P$ z6kVL3LXwf#N>}@cY>?a?Aa{?Gv}2_0G)Z`h054)n`j95PLB0VCj@x+ZFmJ&rQj^3q zF5tb?_db4wr{S|_I1`cBg7*JltBPqAGmpN_qw@0NLlKoXxE3MZFTH&v=I!p7xAfs1 zH;|aRasQvUc(9*|JBYnePV_O;gzbLf7$Dj~%wULlmBq6UaQ8D~Lfk2yo0GU{6d%Am z&kB?SNc snakes = + new ConcurrentHashMap<>(); + + protected static synchronized void addSnake(Snake snake) { + if (snakes.size() == 0) { + startTimer(); + } + snakes.put(Integer.valueOf(snake.getId()), snake); + } + + + protected static Collection getSnakes() { + return Collections.unmodifiableCollection(snakes.values()); + } + + + protected static synchronized void removeSnake(Snake snake) { + snakes.remove(Integer.valueOf(snake.getId())); + if (snakes.size() == 0) { + stopTimer(); + } + } + + + protected static void tick() { + StringBuilder sb = new StringBuilder(); + for (Iterator iterator = SnakeTimer.getSnakes().iterator(); + iterator.hasNext();) { + Snake snake = iterator.next(); + snake.update(SnakeTimer.getSnakes()); + sb.append(snake.getLocationsJson()); + if (iterator.hasNext()) { + sb.append(','); + } + } + broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", + sb.toString())); + } + + protected static void broadcast(String message) { + for (Snake snake : SnakeTimer.getSnakes()) { + try { + snake.sendMessage(message); + } catch (IllegalStateException ise) { + // An ISE can occur if an attempt is made to write to a + // WebSocket connection after it has been closed. The + // alternative to catching this exception is to synchronise + // the writes to the clients along with the addSnake() and + // removeSnake() methods that are already synchronised. + } + } + } + + + public static void startTimer() { + gameTimer = new Timer(SnakeTimer.class.getSimpleName() + " Timer"); + gameTimer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + try { + tick(); + } catch (RuntimeException e) { + log.error("Caught to prevent timer from shutting down", e); + } + } + }, TICK_DELAY, TICK_DELAY); + } + + + public static void stopTimer() { + if (gameTimer != null) { + gameTimer.cancel(); + } + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/applet/Clock2.java b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/applet/Clock2.java new file mode 100644 index 0000000..c745815 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/applet/Clock2.java @@ -0,0 +1,230 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +*/ + +import java.applet.Applet; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * Time! + * + * @author Rachel Gollub + */ + +public class Clock2 extends Applet implements Runnable { + private static final long serialVersionUID = 1L; + Thread timer; // The thread that displays clock + int lastxs, lastys, lastxm, + lastym, lastxh, lastyh; // Dimensions used to draw hands + SimpleDateFormat formatter; // Formats the date displayed + String lastdate; // String to hold date displayed + Font clockFaceFont; // Font for number display on clock + Date currentDate; // Used to get date to display + Color handColor; // Color of main hands and dial + Color numberColor; // Color of second hand and numbers + + @Override + public void init() { + lastxs = lastys = lastxm = lastym = lastxh = lastyh = 0; + formatter = new SimpleDateFormat ("EEE MMM dd hh:mm:ss yyyy", Locale.getDefault()); + currentDate = new Date(); + lastdate = formatter.format(currentDate); + clockFaceFont = new Font("Serif", Font.PLAIN, 14); + handColor = Color.blue; + numberColor = Color.darkGray; + + try { + setBackground(new Color(Integer.parseInt(getParameter("bgcolor"),16))); + } catch (Exception e) { + // Ignore + } + try { + handColor = new Color(Integer.parseInt(getParameter("fgcolor1"),16)); + } catch (Exception e) { + // Ignore + } + try { + numberColor = new Color(Integer.parseInt(getParameter("fgcolor2"),16)); + } catch (Exception e) { + // Ignore + } + resize(300,300); // Set clock window size + } + + // Plotpoints allows calculation to only cover 45 degrees of the circle, + // and then mirror + public void plotpoints(int x0, int y0, int x, int y, Graphics g) { + g.drawLine(x0+x,y0+y,x0+x,y0+y); + g.drawLine(x0+y,y0+x,x0+y,y0+x); + g.drawLine(x0+y,y0-x,x0+y,y0-x); + g.drawLine(x0+x,y0-y,x0+x,y0-y); + g.drawLine(x0-x,y0-y,x0-x,y0-y); + g.drawLine(x0-y,y0-x,x0-y,y0-x); + g.drawLine(x0-y,y0+x,x0-y,y0+x); + g.drawLine(x0-x,y0+y,x0-x,y0+y); + } + + // Circle is just Bresenham's algorithm for a scan converted circle + public void circle(int x0, int y0, int r, Graphics g) { + int x,y; + float d; + x=0; + y=r; + d=5/4-r; + plotpoints(x0,y0,x,y,g); + + while (y>x){ + if (d<0) { + d=d+2*x+3; + x++; + } + else { + d=d+2*(x-y)+5; + x++; + y--; + } + plotpoints(x0,y0,x,y,g); + } + } + + // Paint is the main part of the program + @Override + public void paint(Graphics g) { + int xh, yh, xm, ym, xs, ys, s = 0, m = 10, h = 10, xcenter, ycenter; + String today; + + currentDate = new Date(); + SimpleDateFormat formatter = new SimpleDateFormat("s",Locale.getDefault()); + try { + s = Integer.parseInt(formatter.format(currentDate)); + } catch (NumberFormatException n) { + s = 0; + } + formatter.applyPattern("m"); + try { + m = Integer.parseInt(formatter.format(currentDate)); + } catch (NumberFormatException n) { + m = 10; + } + formatter.applyPattern("h"); + try { + h = Integer.parseInt(formatter.format(currentDate)); + } catch (NumberFormatException n) { + h = 10; + } + formatter.applyPattern("EEE MMM dd HH:mm:ss yyyy"); + today = formatter.format(currentDate); + xcenter=80; + ycenter=55; + + // a= s* pi/2 - pi/2 (to switch 0,0 from 3:00 to 12:00) + // x = r(cos a) + xcenter, y = r(sin a) + ycenter + + xs = (int)(Math.cos(s * Math.PI/30 - Math.PI/2) * 45 + xcenter); + ys = (int)(Math.sin(s * Math.PI/30 - Math.PI/2) * 45 + ycenter); + xm = (int)(Math.cos(m * Math.PI/30 - Math.PI/2) * 40 + xcenter); + ym = (int)(Math.sin(m * Math.PI/30 - Math.PI/2) * 40 + ycenter); + xh = (int)(Math.cos((h*30 + m/2) * Math.PI/180 - Math.PI/2) * 30 + xcenter); + yh = (int)(Math.sin((h*30 + m/2) * Math.PI/180 - Math.PI/2) * 30 + ycenter); + + // Draw the circle and numbers + + g.setFont(clockFaceFont); + g.setColor(handColor); + circle(xcenter,ycenter,50,g); + g.setColor(numberColor); + g.drawString("9",xcenter-45,ycenter+3); + g.drawString("3",xcenter+40,ycenter+3); + g.drawString("12",xcenter-5,ycenter-37); + g.drawString("6",xcenter-3,ycenter+45); + + // Erase if necessary, and redraw + + g.setColor(getBackground()); + if (xs != lastxs || ys != lastys) { + g.drawLine(xcenter, ycenter, lastxs, lastys); + g.drawString(lastdate, 5, 125); + } + if (xm != lastxm || ym != lastym) { + g.drawLine(xcenter, ycenter-1, lastxm, lastym); + g.drawLine(xcenter-1, ycenter, lastxm, lastym); } + if (xh != lastxh || yh != lastyh) { + g.drawLine(xcenter, ycenter-1, lastxh, lastyh); + g.drawLine(xcenter-1, ycenter, lastxh, lastyh); } + g.setColor(numberColor); + g.drawString("", 5, 125); + g.drawString(today, 5, 125); + g.drawLine(xcenter, ycenter, xs, ys); + g.setColor(handColor); + g.drawLine(xcenter, ycenter-1, xm, ym); + g.drawLine(xcenter-1, ycenter, xm, ym); + g.drawLine(xcenter, ycenter-1, xh, yh); + g.drawLine(xcenter-1, ycenter, xh, yh); + lastxs=xs; lastys=ys; + lastxm=xm; lastym=ym; + lastxh=xh; lastyh=yh; + lastdate = today; + currentDate=null; + } + + @Override + public void start() { + timer = new Thread(this); + timer.start(); + } + + @Override + public void stop() { + timer = null; + } + + @Override + public void run() { + Thread me = Thread.currentThread(); + while (timer == me) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + repaint(); + } + } + + @Override + public void update(Graphics g) { + paint(g); + } + + @Override + public String getAppletInfo() { + return "Title: A Clock \nAuthor: Rachel Gollub, 1995 \nAn analog clock."; + } + + @Override + public String[][] getParameterInfo() { + String[][] info = { + {"bgcolor", "hexadecimal RGB number", "The background color. Default is the color of your browser."}, + {"fgcolor1", "hexadecimal RGB number", "The color of the hands and dial. Default is blue."}, + {"fgcolor2", "hexadecimal RGB number", "The color of the seconds hand and numbers. Default is dark gray."} + }; + return info; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/debug-taglib.tld b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/debug-taglib.tld new file mode 100644 index 0000000..8f082d3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/debug-taglib.tld @@ -0,0 +1,54 @@ + + + + + + + + 1.0 + 1.2 + debug + http://tomcat.apache.org/debug-taglib + + This tag library defines no tags. Instead, its purpose is encapsulated + in the TagLibraryValidator implementation that simply outputs the XML + version of a JSP page to standard output, whenever this tag library is + referenced in a "taglib" directive in a JSP page. + + + validators.DebugValidator + + + + + log + examples.LogTag + TAGDEPENDENT + + Perform a server side action; Log the message. + + + toBrowser + false + + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/example-taglib.tld b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/example-taglib.tld new file mode 100644 index 0000000..442868e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp/example-taglib.tld @@ -0,0 +1,118 @@ + + + + + + + 1.0 + 1.2 + simple + http://tomcat.apache.org/example-taglib + + A simple tab library for the examples + + + + ShowSource + examples.ShowSource + Display JSP sources + + jspFile + true + true + + + + + + + foo + examples.FooTag + examples.FooTagExtraInfo + JSP + + Perform a server side action; uses 3 mandatory attributes + + + + att1 + true + + + att2 + true + + + att3 + true + + + + + + + log + examples.LogTag + TAGDEPENDENT + + Perform a server side action; Log the message. + + + toBrowser + false + + + + + + + values + examples.ValuesTag + empty + + Accept and return values of different types. This tag is used + to illustrate type coercions. + + + object + false + true + java.lang.Object + + + string + false + true + java.lang.String + + + long + false + true + long + + + double + false + true + double + + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp2/jsp2-example-taglib.tld b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp2/jsp2-example-taglib.tld new file mode 100644 index 0000000..bb2234a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/jsp2/jsp2-example-taglib.tld @@ -0,0 +1,124 @@ + + + + + A tag library exercising SimpleTag handlers. + 1.0 + SimpleTagLibrary + http://tomcat.apache.org/jsp2-example-taglib + + Outputs Hello, World + helloWorld + jsp2.examples.simpletag.HelloWorldSimpleTag + empty + + + Repeats the body of the tag 'num' times + repeat + jsp2.examples.simpletag.RepeatSimpleTag + scriptless + + Current invocation count (1 to num) + count + + + num + true + true + + + + Populates the page context with a BookBean + findBook + jsp2.examples.simpletag.FindBookSimpleTag + empty + + var + true + true + + + + + Takes 3 fragments and invokes them in a random order + + shuffle + jsp2.examples.simpletag.ShuffleSimpleTag + empty + + fragment1 + true + true + + + fragment2 + true + true + + + fragment3 + true + true + + + + Outputs a colored tile + tile + jsp2.examples.simpletag.TileSimpleTag + empty + + color + true + + + label + true + + + + + Tag that echoes all its attributes and body content + + echoAttributes + jsp2.examples.simpletag.EchoAttributesTag + empty + true + + + Reverses the characters in the given String + reverse + jsp2.examples.el.Functions + java.lang.String reverse( java.lang.String ) + + + Counts the number of vowels (a,e,i,o,u) in the given String + countVowels + jsp2.examples.el.Functions + java.lang.String numVowels( java.lang.String ) + + + Converts the string to all caps + caps + jsp2.examples.el.Functions + java.lang.String caps( java.lang.String ) + + + diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/lib/taglibs-standard-impl-1.2.5.jar b/test.dockerapp/tomcat/webapps/examples/WEB-INF/lib/taglibs-standard-impl-1.2.5.jar new file mode 100644 index 0000000000000000000000000000000000000000..9176777787e57984e2a6451fe52f80147bb1830e GIT binary patch literal 206430 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ʾhV}cAI-8%<3#g~gWcPC_1ejD!K_r1jLQR(#s<2aB^bPM z675TF(Qr$}RgnGWFcWI(gZy?_zug_x+ve)a4OLTy;j^)r>0%-e`0)ps{5jxQx-z(~ z$0n{c0V;oZu*kiL7@V|QFCW0;#}&jk`r~X}tcuzBY@sh$*0wEO8M=4sS}pF&JJGak z9U}-7VJC(R-Kt|>?-4ZR-HZuvjDJm0yinCW<#3+}?-OtN0$;nE5^45P_CHJl`CtkP z>_0Ta{eam;-V-FiC-zUl|gS07IhZ6L;tp7-cdH(>K z>MEYZDwqxNqllHMFxFE8{rMjwFHe#kf!Xi%aFqWM?)%q@`2QN0{=X`O-`oc)x+%9Y zOJGPWd%36M4unWn+-iTpd(5}Z=w0)C08J=%I`E9d2qx}Rqg+Q{^b6B2Dk-Ic_i8#K z9NRG^NvepwX#BY!o%^22F!h4_#JQmH$EFhf#Gt*Aq=|~z<~ZPsaUm5LZcmI#k%0`0 z1WtIdzl}8MURWt?k$LjdObkW*a+gP!qV+iMWL|jZb=GFrS7Rf;?;kS;6Vq72e~nB3 z&q##-aUA~#_<8(7UBde6O5-E%K!KtGR*UtV#T4oX5ep(TmoU_TlAHttgAI5tsBBg(TVA(pQiInjYDT_T%CALIh^R8O;@emssCeuzP^(g}s2X{ml93aVz7+W5 z^QY^N@6NLq3*ztgzx+T>Ln;L4_L}JMJC8&G6KU=J5r1BHn=#byZhXE|UiU2VtM~Fk zLg@H)A}&zhdqYfG_4?rTtRMG6TH~I79}dO%jGFMR?2~_&c&A6Nrlw!ec02ncRjpGI z8y~Hp0!MphzA_`O#n;AUZnw3;&v$S9u76K7Q)9Yh zwrX}UV0_DVf%W)KhxiHb_zHK`J3rZ^`73uhVDNAE6$#J}n9zN6`cPo9jeUAlZ+O6a z)NfETK0$fj#Th;ax4+UtO3=KO`&eZ7CkC8gvej=e)E?Ct^ltV=f!#8)nF~OOX>*&! z5+sEgPVj_(2`y>a1fria8{H}lE^4jNAw#XwPOugXN1mTWF$rUg;;&jqocpVT!c+Z-p< zXAdJXt11kgx{^p-I$^A}nrxJ>M|Z?zPNOrbb38{9yexH0rEQBC3Y)cZNd}`FVBAA?;3ZbFb@=;TYhWJ3JbRJewlZk%Sqp8QDq(xv?(Q?Dg8x%qU zg~oEs88vb^w3;%S8p09BTFoI2dm`|-{NfAJKu~jT8C6b$bG*!TbS6PG;7mK|T5V>R zI%)(I6bq|B^gsDk7K#fpNkKxi0vo4NleV(1fMjt?;U+CeJn1_2@#Im}A<{}L*O@0i z$2gY?L*{K9Bxj$YbI%G+l}u@Mvf|KOWiFb5IH;1P>P$krrQ~H*l@$&Sz(vYZWw~8+ zrIys1($Ly5vZNKjO9Qj zt3CZ~N=go=#+1c^nm_aVVDW9jWS7%ggOuoRc6x;_10YZ&Dl76x=CL$1uO`RZc<{C> zk%ktmJ33cdwEX=IMCO;0MUPJ!97tN!qCXfEoFx=_{Ax#q%)KIzJXJ8fm%R*cI0glA zxuUe`(#&IA;C>&fS(b?o>;|!)no@C)*qSB6acYAki2X(^BYJJmqKGah<1GZb{C+F} zUdx{_ua=ffzFuhY=C#@^Kk2Zo7G%2eGvX~V>qxssCwfk$xze|w6{kw&04T|MP{IYh zi|>KH3OCQVk}A%{ld=zCA|Empj`NrlF43*XEUj-%(O(CO6g-a9Y1kfLpcuR5HQJ)T zuBBYC6tkUu@QT`p016Zywpm?;3*HwAgFaFgszJsockYCw73_$}m#4OLoQ1JsQ!Y=j zF{k!8zg3Ej;P%DTBlZ&i7QWvIo|7ckMu3RV%Zmj07S$8pPRJz=%D1uAxE_<66?1H* zpJ}!nvt+fU%{V!};P@}=t>?)@yd7E;EG5NSz|%6MHlZj95*&hfQ0Rbr?b@CPno)EH z7BWkiqJ?JNFjeG0y4;X@b(koZFvWC2D6wK=LZS#d8$hrV21QYdaiANbB=1@`qNGTD z#$ufIYTcZyau3=d>dMEB6pDA3-VoI{fGR0M9H^m#51YjvAdyg>jrBc)IOTLi3Fpt@Y=w@bhU2L5w6)3Yz3xnJN(7XYl1e zH*|mPiPQ~UkN+A*Kh$>cUNag(8jWCW3n%_I)}@JUfgO?JY%GmFQ%~Iq982y`b2SVf zrqrKh5U^_HU6M3FyxuF&3m)|H%~0^UD;HGHm3}&^w&mX&gFnq^HF+i=eC}5u^G)>5gvyDSq$xBSc{{rz#-YnE<|bEg~Y4` zT%|LLD)RdEF*W=8B0_V0kzCfmB0h5ldn9#+Y21Ay#ArwNaa#PI0p(cz)gAUgwQ`XOf> zzyY+z@*cJ2b;TLZ6Sj`rM?L(?f!d}YUSm&&+TS^v_g2wNKkXryO?viy1PADARP|pW ztKnJurpAN1t91Ay__y>=QpndSFgJdUK!{QlMmdcjF%nnqI?T60&M4V&*ZmFi{Ja!= zVJAgqxA_ksdht&OCTBjK#L}w_fB!wJ?BOn)9mR3<>Ml(`vf+rg9p~arSThuI$Mqu7 z{ewU|)|tC+njNHCE?0ok4^g_2WC8Av&nFZ112 zI46d3o_iGw_zAl&0&4LXdupTxe%V)Ftho?~0r??EKhI;5^2)4Ogz&JZPiax_KD?@JP^)x|)Cro?M@K4y%3KVKK~xdI z8y7tEz@kb&oR{&bGhL7qeKCm2OI@tRQ5#f0FWXWZ=6G`a{&137+Hi|@G3E|;GOH_r z?n1A~Os?eOlSIlnqCc>bg*!v0TUp??IGFO9w{7YeM^r%gOSb zFY=W2nt;{MB?&YdTC@b~X5i-!=Y^=;-zIN`ZL5lEa=gqFXp`rGtNc2Mk2Dut^T(L8 z2Sk_il}?ECeJzqg{cf~l(ntkdKUMImi=tEPk)}o!`Twca^Fs$<#lDA+57GZ8K>y#h z`u_rbY(Z4M0jE5TDxZy#C9R*%5$h@Iki-!1;ou?}!>lB5wWe!i9k6!|>+<9_^8~X5 zOAiRYIxLI=a?)i@uiLz?+hVe^2n2e3A!7%%FoAiKq?tp589O!L45>oR1bNMXgpC&% zgOZlpY+y5pQjf$`G0=qxv!+fWumHE4On>ZEPsDWTxRXs6)iK59iw$@-?Z30I~IQ0Vv(k~8s>?%ky9v*mpfbbJxJvQ-Uc1^6 z0{svu|s572RO0&!LP15Sfz2uQE_Y`Y$uuVdYB~&A=;zIkP z>&AR(9C{m8F<^A?M>XupGe=g~u;-RrM!Ti5x$r5S!P20&`aDt*}gN^DSfE<$J z&5ZD#*#r#nhA{xE(?|o;H+2Ej11sAw6p>(zkq6ErY9oI{PA9jNG^%BuQC2%UHUYqR zYMd@7tU;0P{Hndlz2T9t&4tc!nQjqRH9MGsm(J03J-Xw^|3fx;kF@(%NaSaP--uk$mts<(P5uSe*rzO*h@HU3`+NT{|c1;w=5N8*M39S-=gat zkj+EyopQs6(JlXsolp|LEO|#eFV}+eeyd!|z&B2!HP8s!aFZ8IRZr}LTzrdpN1xf3 z;NRif`Z6tl%(1V zPA9?sC2Duiqg6G?0H_b*u~&sudTyHMk3wdq;@Eb5_Gj3C>ALGRhG8S$eE;;Hnj8~- zBd?vK8H0hnfswfhgR_B|wS}P*gOl_3p09zUF@uY<#s9aohW~1Y$rQSrzqD&PgsF@X+rMWPwc&E{&rF0$wr8zM3oq8?4q}q!623Tyo~m3f*Rp zhBeYnttV#o3)jKDEV>|oJNUNW55pNX>vjmk=XUHjk*^npjZ|2#asBhUS54RQ+j7e? zzrfeuBRZf9hdyut*Q9*x4qc5Pex`?xR_|?pKKfN8^Z`AlOOyd$NQBS>;5>H)iI73Y z(|!Y7qybn%&hvg=xG+#*+7P@@PNw~!v%yjnMT%kET3pWJ-Z`{u>py>BXfzmCy(T#= zz>LIrvEj^=)OgqPd$%ozs$?YmtEzo_K$=*X45>>`oA!^dFJEfY)~(=1S__`ZiN&mY z;_3&vd%jcRD;om<+ali^mhoc7lW?Yy=9AcRkPBEO{Dy^M0c(+Hu&zZUV)MAGOVTMt ziYy7*G&hSb%NVfIVK+NtHF@HQE5MOq<*L) z+mbp6!RZwDosJU(9S(~*x5f=g5;cVp9rjXj$Q?vtPPaSAwR$0)3~9EkdWEH>T_g}% z8s)1ju9v1ZY8mlTX*IbXwZmr=2S=fT$ZxwLzKo%fKONkljlV;XpB_ut18n1VH-DvFLD_#E&myT;h**Og+Nsab1YDi zN?RJK15^;21vj9#0v~Y)BUc`pr(`^849#UJ_bQhjT_T&L_iPHV;=OUU(o@Ai z_}!be3xBa4wYW(&r@W5Ucv?In7@er_SuU!*%1`p zYcqMzwi)DweBCRX2;J7%+bS3G6BmILa}hdORtut&*DOdb1DJ|Wm>-SGrr&hiHm}mL zM77;+qC;R(b92!rg^}T>K3al3du-fz8^8X(yFauq*8S}`ZH^~?X>762xu_4|j{nQB zT;$^cc7HSTC2L;&kL%Zpn%=2< zOAnpURxA@-{i2+e)Ut@m{gu4|oX8hh*AeZ=7n}3WffxFGycCH|lZQRsFzUfo@5M>Q z@0~NcLV4rd-w+l(gCqQ=X?zqDeSQ5_DT@N3Z6q_aDO7OIGrbEc}z~}SV)@=CFfJatC*d$(6)w*OPPT;+DfMU7qUX`IplFO|9US8 zPnFkb-kak;Qm2F9+Z621TsOgfvJ$*n!M#w%63Q2>(7!A!<}E`nFmwJG!Qlk>G z*UkHFI6Fb2y(H7U;L*H#WqZ7Mv}FPD7VA7T1Bbe$QN<@vG^Ze_#=@kco0Il9 zwp(Pnsa<`#;*pwb<+R%#SO;DXK z@b=d~>oV`t8Fs$kjc^vY|E!|?ue?(KeYbsQ5SchReTS*3e&3z{zTk?~G@Uk7P(N+6 zM4~F=S0#m^Y_sZBUE{-R7id|hKoI2GSDAj~+Fxz9!jxCW9m>2#xSt8TGX+BeTBdIb zFsGArJf@TkXEv{_cigV|Mm|q=1inBRW5UCcHq~yi(N$;-C5M>16&xUG9KF=5)ebZU z+QZ?!%XVqds2yS0Rn1?t1oisR2WImvGCrAwWo8mFA=IqA0t`s))(ty83u!lr8MK|_ zCs(L9sU21l{~qu8eXTxV9^bRISlWlE)vTHsqThpmT5D`pV}tLo zU0MDeD<9&sBU*4KqAi#Z0FUOOGlM&0$!99fhu5v=;0_eS&fkyd+E)&Vk3a1j$i2J| z*LTWcF4S7ps%00VqLOniPQzta=G(ql~g&7gk6&^jI0!&RB}d}sI|%isy5na5ui!tu?#; zfR$SXK|x_89&D)>v4NHsxxVVfcfCGDY~MkW@_u}FY~TJFyZ~}ccw7^R1GEgx0rTf8 zW*r_jibWdZkHdniplvo$`nPa;Vqz)sqK}{057UAT1l! zW>%V@{!o`1%@T+-*?7&JbhA;H=XCl5bqfNHnX++vU4epN+3Z9uYA#}Bn7_f>&*yJX z1XZ}*8^vTF{1fMFHa#w}1MqLJ1pe=E{$l}oOp-i-regQMp4@78%pIVOWXTAF9k81e zfYq4`yrI|4o@NsC2T8i9zB;i+TBaYGd=yI4Fb?&s(ly_oW{di ztmCl_iQ${bP9|VMUe2VL4@9nN&G79C>`midynK)0SXoo9Z_L+SI`Z| z;#C`lf>MuAnib(E?LHRB_*|=`-(BO5<%B0UNTMxBe1*q>2$9<2@2^3J^a(tlu)i zt`vtKBr88Dkm&lKOwe8mBtLm*paC=go|&(I!a)a;`qzNJGaLJ0{i#PNg0ErA)xa$nB)^mpRaj|#6!21dTjXCTS%65*d&9bA zdzNaFatV3UB7usG{{s9;d5~s7=O2qn@C~o}C)sWH7td34e!86wibLzP)}71dTYZ2) zfFCDD>2vo43sxyB=cEdf$sce_0+sym7!c{Hkg+RJ;En_YV*l4{seJh(NrCb1ao@>N zLk4&gZ$g%$56M}2F=`C=73qe9pV{N~sNli8(W(N7cS7W#Y48E{3Jy1P&TBWRGc-He@ z@yVK)S2R_&uY0q2AHN7#O8=Jj-PVPY`EPxpGcdaScG*1M`T2aWf{gv1NG%Yy|Hw<6 z;SSNzsq6VSQoGUi0y}@{6Z#@P8$9M2m%4Lht*-A4!rOCZc*(t=7H+d$}DKx$XesH?t>mY=>c?f>1PiT=O!i}-(9 zy9%%c~(x`N(fOJTANVjyCxWdv)Hxdf0G=hYblp-Z14F)Zuv^1z74Jv{GDtv=+ zFN=We|9-=>F8Vmw{IbQ7U%tVsbS^c^=-kgSmpCJa8Jw9JATq-OX{ zo{{f}K_-(Hsst7he=(R7|v;=IXY z+-Hi>(QnbIM`Jk!=boWOAA?*-!qynY$|9)@(2GUG(zwjnEGI!2P(^e6>`Z9T+LDH^ zemN;QvgE}-USPWJZRN**W8=GMNY?ucT&LbQ4GD&*G4T=x7WMnulkbO?83#_y30oggsDn2?@W_t zYx5el*~nH3Y2qfN!1F08&kM4Za|bCT=ADT=F#)}*r%@7K%Y31}I5esxGc!>8O1<;( zt9qL1Ej6L4#r21ltP4ZE2enFqzM`6T_F~0D`*>Jp`pLcFOJ`5cwmh^Dst|t}!#!*V zUA@v*`XQ*>S(f;U&x?%C*)f zS;Yh_SgLRjrGAb!t%zZy_0;wq_a1ru6eq<8_N)}Ac6zBSK1D|ImUH-Ent(UM%{={& z1R}%F3`fYiK7GcmWj?O@Mpf72Ar^tf$K}lBR*y{rziCik3Q=2Ia1t>NK@~Ncwqa-) zh<=sn_`;H@tU4&Rs7FZ?d%m!bx=EA#oKYrD8QwJx#oUU+de-4J6h*H;s(j#ozjD|} z>HAf-%^O;M1A%_#gW$#T4T|O0t-(IW=!ony^Ftm>d44Nbz5I26^63q~bPWtm^ER+O zhQB-DWaiDu>Jj*>^ zVIS<}X2)g;Lu8X?m3U7;Tc|H=tVy%8U@Sx4wldGuwPeJ#*`KmsX-jRP7d~6k`1Rg} z!W)KHpB1Swhd&I&JYOodM(Hs6lK88V<~2S0P|a7&_xqQ>pDJTRxhW>ODNFfKsHvGU z-C;J`$n1W|AuFqBcHw?4+TN1E#q_=#r$i;bmz6V=MsZ&9H}ZO7etk9}L_}rLM!G{| zy3I(f{bA82?pCeGLPc+N3GCrt-ghs@fl4!=8oCuoejj`npG!5ibVlIBfmsxth(rQ(Q+<%Zf;eYlibk){5_r zUYR9(%Id1g^en@nrb@T%@i7;$MarYoU`j~VEHU$0quo3{o2(=r;pa1)H3`elut!J= zJDrPg{kVCGmigW%yKN=t387e@azxV!+betZ8@HcoU&H)L+Jx>tcXSHhpis*aG`> z?)%{Ea+S#!>70e#XNqR|5qN**i40Xd)QO$eyLKI2l6S3rJ!5q-FTfMN z5&BZAK^Cr}|A^dqUZLZ))s#$&Jk&EpM)XYa*1V z(1cdCSE|ddf4`UOECndI%e)4`%%qy;J_;Ygfi4wJ$P|jx;(As&+aGVuK zj7ZBzh6hhNw#=QaC2bUtD*38$k#s}T8lLNC{hY(AWJ)7@%}$@pyoTj8{1DwsyL{4S zn(+yfypO}B6rCo_nW4Nc3Hd?H@i`P=o@mS0-A(8z!O)=q6o2q==j4##q(*Y*ehfd82O1!JAekV_vMibd( zaww;}N@>+Qa9KzqO+aQg-NI7z%1DzFgT8tvp8fI3F}z8c8p_uv-J{=(8=FnjBUHAPlx7NISCeRSfqF(NMCpuDw%l)f1tueH9&55WTeWIIC z=3Ik{zG7}qUY>-AhIU@2P97mKliK>c$Frum$q*5|z(-d}#6`dbwuBQMW=;6V&1hfR zq*c$b$$eg^>@-0Ud8`vCR47+<*VL9PfQnx&5inmFQGgobW8f7+Nx8o4UkkX5z@Mk>xGe z`Jgz&0h7`b_GRdC9o3_?_a~+@`rwfK@-ab@qUM`X=(v6eIb=-3QKeqV?U~dU+WGiO;2MIapm>t%E29tv^ns1!8LO(QvcKbucY>CL1ti zkEGp+3&^zQrx47Ibj^@AiYV8;uFy)uq8x9Nd`{bX|a^}oMqcxi;|G5;m|3<2MVVABZz#=71Qtd1@6_3#H;efd{+W>aV`NCR(1Z^0S4=%OpF~c7YLATa z;;*3=iBxYKTL*b27)0KNJz3UjyFd($TnHSYeVVG(U3|*wVV?Sg<9)bA>n3cI_|kN&UQW3%#~)2(OJCRU3)+7 z(=6B_)COb4GkeW;^CTy0PT!4+$hfxPb&aZr3L>^gJ^ZIouyeROJWOQ{x~%IF@~9ilK)J6;|9Dm0`GmA+thp)1wpT5Noo@sX^Mmd#5O z6!f79=sut2$W&`tP&2!3r*gj(TuHU>NSTXDGkJ7~wDAF7+3O@Mq5*9jnp2m#uu7So zo>ZD12}0>63TGzObO?|bo7M@Xc<5paztVH`<+RuHgm^oF3Uy~=$XBmuLt>N4CLF2u zg0eeetsJrE==i{4j%S64>bvw~D)b6rh1iuRzmV1_Mb_Wr1)FWgQL=osy>KpeogS`m z2qXS1A|e0qO;vVBWtBQnO{cO_p?A%Ub8W+zqH%q%@&ac>E@ls@qfJ@D%G`P5jAodo ziT=yuaMcc-*0}7l>gF!zCzR97f^}z%utJ4+6F%gH3Bw1m6epRg+PW&3m6N~nCN%Ng z<(}dS>ex)Z9qDmZ@yvJQ@6jxkcj(Tm3#J=lEQl%{ahA>~)DV&qxh`>{tVIRu5N4cR zHy>;3jf!g8Z+V*C9Fdr~krIHsdg)%Fp2bDY3Rhg3fa>cu60wzjb;+ zRM*heP4!JwY*^Sewx8krYm!qVB*GgfJbmOEqAI|Nc<55B7X|A?)?PkP=kL+Za8veR zuz07sN#kjbo3$#eHYZsg;OdHIEaewM?`1kmTNYN}n1mjj^xWr2yRT&LSB~kEK8D9f zTP$Yj4Y6$}LMKtLvJ3}Ykd}nI6ONrXUFJUXH8_64a$K%mgKd-e)X=euCg~iD(cF)s z`VU`B^gnrs#=Ey0K1A|eMN5H@L&4?7O{~_M*mgC>1-5&aBT2ol2zZCkdIu4DN1%EW zD4wL1pv|I=HaO`s%aF@?{?!?MR3Z|nBE8g@qqrb(eq=*xy_ zTgv+G2u9`|G}2Du)|Ot0loc zby-gER`QYJiob zxjX2dPDA6!zl67fbn(J`GfqE$y-|AO34&hndH%m3ognu>*{Hr zkTj@I3iT~udBRxL`KmpHt1<3PWQj$rD=4xPldMPT_UVSBrn%eJw_i%iuxcq&cD(l5 z;0@iM!l$Z*W*ltFkW_aeluvvMTS^NuV=IoIPkV zb<1?gF+oCUkk5VQY~zZ++^C9>odkcVtX=X#1EZdKf3GNH(6jOR0v*I)J;2x|)%O~^ z7Y*rIySPFu(ziO@v+)p;)iMX=S`MFRf_u_u-x<`%JtlA~q3uy=d+zuF+=lUqNXk~p zfrM4z7H?gWh#D*OEO){ag1IH{tM3$hObRf_GO)Ez-BdXXcc?B=I@jkR*c#U0VymH% zpFwh7U+5nEQw>iaM=(11cq0+K<1kt4irco;?7=nbyeOys9?2oV1nVg$4qkl-GdXKK3k94^6(pd|4 z4;9ArK*hluvybi?v023t_TEx9Ye?D2@nGnkd`k{54Yp#_sBDghk&&`?c$GmFtrsyTNQyh3QRW*aFs-nW>A~$c| zBkAiDrE4T7Ab8DI_T}5tQ0se-T)fp*8|G3tar!gU<{k-!#451N4cvTT*nhrOl6Fyq zon5Tv_9!O&mVBmfL~{70=n)ro`g#2e7hljDUvPPy!c#ZNdRNmZK~iv}xP+cgeP~ySqqlO#0O2X(nU$zR#Bt5)+j0evr zx~5u|yGrq8(}k|bUA;^R@iYSm%LMyAF(W?B`YoTSmpq>!x$Bg&J6f!R}-bkSM;%_TPTb))WNxPX7 zGt+vT!A5ySdDCoM?){HoCnlXM?h6(q-!S%DO`k(H*l9aiAx64X9Yg0{S;CEee!Vwcrh{)C5Xzn@9Qjr z@^ImoLY~P#X#-b}b9r4);9!|Vu~Yb>)*y$ok=c9EL-axVSu5NZ)BPH8!t+;+HSd;j zQF7y6<4>W6ccG1Sr9$9YB?*Hq&Nx>%?>CXT-E|F6?IXb+eQF)VOdVaO-8_@ ze}2<7{|S?k8oy%7O;aYgL&Vdxo|MoWdqXM%c1t&BQMHmUBBDnmZwn=9PvgmC%-4wM zj%jJi-g|qUe}K5nP=znFZhAIbLbf#FF_H26Y@U2kx|2jFn_IE)CNbzL#ix!b-qduU zDAN#EmsB{^S{GP)70U$;yGn{8A1kkml&XN3%&THr%wQm&&W?%WB6ALAXYCmrYCgt~ zlb!h)69T*+nQ_UE-JEt`7#ci)Hw27%m1DSS41&2;$ZhT~pw(K95h*nr&ar;#8MR>L zcZcJRon}%qaJ@!Q(O7Z62)|STT|twDxEe-DK}vdYki;etg5JzDo>+Rml{M*&^TdnD zGtvDj3H~<>EOLe8t(7I@^Iue{UlJI~ONXgxj!uLNO?z>hF?TsFQq%|(qnmgPMLT** zP2yZLT|S#IxpLS4(~!(3<*wQjpX^X6B;3RAds0$*bPGw{O^#n;_HO#*(sBG{Vk~SR zay_%d@Of87&BKr-bxsv5DlgKG%E5UZuLXTrcTC2qCVBGNi1KH=w;E5ZN6JdbUH3iV zh~C5BFSnBA5zu0~>J~Kavl{zV=kfYFWy9zDHqI$6#_ta=@}Mr_3=itpDd<&NL=em# z9!(5ZB%xoAPUj76J1vN#A}&dkB@@5TBu0%wmUfkgv)G6bcI-gC~u5AFsx8apx&M-Q>I!dh~S0$c)!H ziFf2)AEL(}n@X>2Y&>JWU|7HLa=?L#61VWxs{q`2^AN^jZ0RwXz(J_XeOkN{!pQqJ z^2G}R%`J|%lwaW|H!*@M@}SYCg0X|F-F~ynf{$bfJN0`ITknGRefO?Z9_Z28uZiT(CD$E2 z%*&b|Pi<}}4JW_{0%D!CB2kFEy5PxRkCIZiq*VzMn#*CzxvV3-v=8glLY=P(C04$b z9h(|;aF)BGpEri$UNV>ccD&B5%3HIty3ut0;buYtkAf!SO5?T9n=_l6W1k;I)h%~9 zqJ%YjuFW>-8V!b{8<93~GQd+j)a)poCb-ZV*#xFu=q~f3wGyQ`K+dStyytlMwu%2u zl>O7rO2W${X#A%gCSr{q(TKftm1w46HgJU&)~PIYY{0?-2Ou zzCXq^sq|q*m0^Q!z>noi6!!D21030m0?`TUn490M*|6DOf3%tZ%9W`{=|kfRKVhAM z7i#G7&?o9mN3LXkROhZ5!f=`Gc5o=N!^kZmaQEQw@WVTvOOeW_mQt6Lm+qaLw}E&E8054ra7T#eTq{OXey!HmCuyEQ96o23 zjK*oNO-0BtfN?%2XA$3lC#V)vzmFVa4puUrTGO2iidiudgGFeyJTz2(BiHbp-Km&i zq z&KKr9%f3pLu(lkQ^EQfX^=@VNyMZkAd2{mD7gx?bI?Z|b_36FU`bm)l7k&nmOWx~W&{F5)iVyy`nEBv`*2r~t4 zf9Cxx`)orx9rJwFdQY&A()aPV4)$C}+Uk{O!-EM02KWZ74ktVbD-~~+3jH)fG#f&e z#B(8!NU4pT&YC@&A|M6|BX3_7r^Hp2ETq*Y&)`VSd%Q-ZpS#w;*;vGHW)Uapzq*o1 zT<|!&R~`SRW%h?uZoH=&gYjy#=Ige2`Afx^fe%jA&?_g?S+b%lmiC-sn$^&1Y{*>T zp5x%i{I0I~4hFfcEQX62#|0Z39EK3g=aIVi#6=Ybku}iIDUN*%&#PWP%ZdMlAtA6& zv-M(r@MsmhzymYcgdZ>YkqkvjwjIOLIeQ~D>$D7+%L;NGof_t){goOt#KZU;?vboxC*1Jxgj&&>mLsAh)9Uc<++>7|=YcQK(-iX`@AF=LE9+-&{G_*l=E{)8@rVfXSQkR-NVd50$g36EreW93PA3HM zWZ&k`*pSaW5tnx1wsvYNt_|xqoN66cK0}i7Nuo0nOfN}hF|Ev>QLQ}5>saq@u~!kL zD49&+7U1iks!fTj8|gTulyCm=@dueO;u8OY59mwu4?mo5hCR!BM0J*%Y#0W)FZKDF zx8#-YOgfg=mppiGvlE8|;&PwrBI=BEJv2xCLZ!)oDIM#SFHvn*R_@C#!1yD=&2RW(Bsfs7@D_PT3xmNek-+x;rMVq z+TpQso>!zkYQv`Sp|uW`%;rk%MtI6Zr#awaA zh&9%GkaAvIohh_~{(8L9Dl?hli}M+d{TkY=guJ0S+CjRk8qJqV0vn<629A7JS#_2< zFB_#_sw*PXW+iIZDluX;eK812iuNiRXef7zNEKXm3-)rK)5!?4$sTZsjH7;*qtlF4 z5_8{@c*yVz`^BTP9p7sp=zVPJ?tIMM%)AyKi-jmAl+d2aHoXllNm`v}icj;NZY3q6 z)NM2CiMo3+Z#M2u)}=b;+i`^+ohNdH^F0}taL3*g%QD3$;1Fq+sopE@_itiQjIB$yl55hs-2<1tx9{aYlyYmQKop;z z^Cnu*Z7I80c87tGZqoT@Yq1&b zc0BkvH-}z6jvJz^99@0d#*W`DRVMwss%1EO;BGGtLz1=5i`t&2tE6aQw^Th3^`biU zTZML(TM?6z*|M~fx+}?wGTp`?$l|eba;Y?-Ue=l^PX3sYdW5RmS;bk|X;t^>eVAAC zAbU|y0ZB?WlZpAm=Y{e#H`Yosbd*?HF7ixMXkH>Zk{KbaKxaOWBiLWh{XmMgXTF4h z)*0TJ#H2F(#BH`OwB&LESGpbz=S;hJS@XR5#ETA+^~J>$S*De~vT6g%r95LIRNMjz<0rxycQ# z`NEaf$I;MV3mAz8HbiK@&6FUld~wp`_08fll{}Swj>pXVVyD@1JCkqm2P8TXRf{y%}f9Hoc$II*3=Uf=>U`~pDi({Yhl)T&Kbj0~6C%RzGO@p8eO4zm>=Oc5!*&TLD~ zhT^sKIPJAB$Isc?+-R*O`-0JVE;N8I>$vJ2V{_cbTG;F3#B{4d@MajV{X-@QI_K}d}^5Q?rZ zc@&?lEOtnfs5AY9Rkq&i4X(9E4IJKaJr86zAKcO~d3sj=HroIE8A|2@!6B9IXZltW!-H~Y?)cwfXb+l|dRTQR zXhN1SBw3Bwu7%YRo4E-VFVg=+vC*eOMZCGP)tXGfaT*~#MNx%%Kx*k>=@@U|+m-Ki-otPG{Pok8y z#w3oF#h;BkZjsP^@~!z`;1<3xRDoCQIMz|&ijM2Ukm^Yy{PaOVJEp}zkHoT2W%IC4 zV(sC!`@#jOF0ID>Y~zekdM~qBZNxtI)UQ+j|SFN+Zq&*{D;cUZW;4tV$%W0u z)@&zEM0TQB@QaFaX=yVK7$z;BS%O+^v6k_&RP4=uf7Of`YfLHwwxm)As(m z^)+0k|%AEC(1Jc0@Ynql7QBf;i~M0R80 zFr{0!641Xo&CV$E#BN(}k9`=JYz`!Q0m5L2#i4V-Eu9 zwg&wRB^{{K)*D($2$Ko>&5s1VuK4nHW(t%q4ZsQ=0K zRs=X}p^p`Xi-HmW{7wi#GcO~NhuAwp4p^S&+5~ftW;qlTQ3Ra+6r^!XtRZ^@Zu3-K-Zbhcf}c zGQcSj$5X24@529L_XlMuh>NKu$Q^&$&6bioU|PA(0LKTIrtmiYL8vT6635cs-Wj?l zP?+7_W#&UDD6`-LW=q=|Q#o=#(oj=d2)K8CFOeoPbe_}#`eXn}avKgvj}^!v$=W-~ zfCC>iT^$_kom_rz_TL%kavFkG`+*8wK;lwCz?-f7Pk0heP7qH8@ZuW8#s1e_@;kAE z4qGO6136!T62P*}?Qs_cYtn3vj^; zOaRQ?wl%iK|Hj3S(LX2~RN0qv^MN%K{b3F4E&quP4JgD+)z0=W#;A?jw&Dh~U;@Sh z(Gm2Y{3m!Vdl|dGSfYPcil8RY{t8$fiEqU z9;DH<>}{ZS&cA}p?s&KEz1H~-2DTVPX~}=_`8P1NZ~(I{@RlsZ z0jxImigTK|BKpK&Xy1Z~t~LS_UkCr+nb=(qBe_SrZNLc6Qte!y#g6|67Ip{Y`_%t9 z4k-NzFll)Nd2Qb!2d3g`Yb)X6;$(Hn)dec!VG4EF3T(Thb}QOh;Q-WL@BvGhZO#2X za;T~EPijD-IkWDCukjncSP%|qhsOkR0M|p_%_C4SR zXMy`8&Jw?(AqxkyciVgJ=A>kaIRs=;8W6juu5;zJlK7zL6@{~VRF)AnL5eB-v>>|zHtA&!6%K#d%Rt|inC zOs)5oXbS*<{b($|zJGq5r#&zlsI~sF>Zw)<(|iR2UpWX$;s}KAB1c%#)y~Wo`rCIo zcXy(!Q4Rkx5G8m(0S3`wKhh&51_IjdSlD+oI95UBf*n*YBoQPd;y?-u%+p~I7ioyg zZ|Qc&6JgE^odUJ$8c@uWM!@qF_#g08Tw#}>PWu|gh zh%NNra~gKq`kUcNlNVsvvcW?HF$B@(6_5f_1_uy*AXFeGE>=yX zz<%V9eWBD(J+~DBxg!*qBVtT%*FhG_8TwZXNv$AeCk1MZ2GtxX1U0%{L>}${2IAAr z&1(r%c^#+{RFAf`O-rNzHK2~JP-hnzJ5zfzE4%$e6%|LrDgyw02S5>(I%?(;YY+77nCS1wMy3hB}v#h10TvK@IHf_IC$U z6!fPZAjixDI~CtHf+#4O{zw5H2yF{s_dF97bYL{_yyA~MW69{eN(C(9AsDJ1Ap|+X zz{?<-KkBl3$1Bu=g+>w}hAYq;VkmYGM@ou+!Tz#Ro8UN=WdOu`1(r&P$p$6rzaj3P zY+{?%?g;?tj)QQ5DB)AEfI46mYHOUfg4T~f`L`KJQ8^#u7ogK@M=V~;Z&s1)Lo%Yo_~`~RfA5u709Ikj1w`DUd%%Z4Xo>3ZC$_`|JV6? zI}<4(>HGGr89fsKlHc;Rf7qyNxSB$eQ>gwOTwt3RBy`44CNO;I@PT#`&YM{QCa+714TNIPk>y zkGLf|8q-7s9IXd98sdU|7CFK);P}OTGfM^P=Q2q!N;6=T5RK5{8B!wrsw)GP?H)Vy z@!mO}1u4u1fFZ7q@IeXWfU#psR|@8PVhAk?qQSv{paNq@j89qpNMR^yg6o?gPF7oI z%4xblOl|h6mGz0ya-##O{DD-6u9ZCW9}zW8!S03Kbt!O%G%pmGhA@~JOCs1E>DYfm z-5u{+7wuC8Amv>kCF0~5e;O&gzfX?EJ6#NXfM`y@gAt)x=8%PQ-hYnM#Pt3s3ve=Q z5HR==v{?87DJT#Y_cTd$BL64MAnvaJF;P7C87Yt-QP3PL3iowq=Un{?dN5L6V59^P zWEwz4MaIj1l?QgW2Z3}=%_g8ZdQj;=d}wKU6e$!vh%IE>!LU0M*Omak<0}nwo)#;gYpj$AYBSRSiyJ{ly7&jj*(XY`v8@^20RUUqtRwoJIw2AOKOS)G zDMh^zmpKcNpc0rV*vh!A84@2HMAda~&!&FP;Oz^<*cubWgf>fhaD?CU(%l`cgQWod z3czRr7=qhmKtXv*esGN6rQbc3^`aQt$91Ez(jtkRPQhuJR-o}w)b@&kgD0Te_8 zTgrnYfC}uMGF*E^fPE7nd;|!HdvBDf500>J*xMQaK>bH!`1SqsOP=OH5WAH^73RBe zf&t(4fHI;Pr5&8;&x*yKy5Y-w+YZ!>a`=zX5k_}l#{Vry?uj$fGG|H+yxIgLaKvdV zJ|mJiKkH0;B4u>;`b_|>MgI{)Qi0e1Z8ixq!`4vzstfK3;+))L=m|iq|1haHXAcar zzk}bZeSf$Pke3Dd8qvWYvm*oXvkthYB>GlQXEOlI)-oD#mOsgb9L!(FW#GnAhuJTc zAr@Sgcn=J;qwcq-RMJoSUYP)}tA|Oo{ zkOt9qqvQ?@g;?j=9Z2^@I!!c?=?wrw%$B%{2L}45xU)OPmdOJ0KN_OtqMknx#%>jz zp4uDojDT^lUfwYQ(my!St!mDm7NzGf@GS&Te+76)w5UntgR{M_(dw9zeH;N0@BT2_ zPE}+e_Svd3nZIz`7)WpvWGcj%j;nECh=10~dn#*daDR_6)sK<>{YSUfUtpkCf0XNP zK0)aM)iM-6pcjtcgnoQeYyX|v?|rT^3cK6mDC_#d*4|H=Kd39|{+;^oW#wMfFC>i9 zR08U2KppG|ynE^Yo%+v>Wm&-T0^-aF#3R8jhJB}LK+StUYO%b{sJJzL zTbr6V5$NgxfGf)x&^l@HicMJ5Yb2?rG82$o2h$Vq+hl7!q z0(;*9`Mt`hP7Ix#pFx%EFzHUOuW&>T0O5}Lo%N)Gqv3BQz?g3BgF`eMLSUi$nhj9; zmYROavAdd3=P11kfr>tY4;T3S+sdvSjJzz&Wgjh_VqEpzN+Al&0IIyX$B?>R{A09c}l~Q7Uh)mJZMnHmDyX>S*yg zQuO!Lkr&NNu`b}g1b^r#CkYvp-E{;tzfQH~ZhzWQf9k=gg9x{ej<#PIi>RZiTS(F0 zS4Z1#+(fja=saXlcGuCCZ~cy+)c-mf_^kqLVBF7@UBTwMKLY6X8_y7#MK3%6xg9rn z?ugEsH3J2)zcRZu?b~^W+D?e=m**fBRpqJ=0I~ZON;^TeU#!7~pmhD(gMe(m zm1igI?UyYejzH$41JDK*zcpRhE5U3(5g(EId_5A>e_h|OllSe1s3TI(0+rjpj_+^Y zf1R-wK*Rkw7sc%1n7?C<<8xquiozcCM`u0OVB@iq|=@}B#_d3;h zC*1aP@DO);3Unh0_s6-SJF&JOK!NBCvHb_f`W@ZSKqdiuCBRR;Bnry4$*tJ-e{*%E A2mk;8 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/lib/taglibs-standard-spec-1.2.5.jar b/test.dockerapp/tomcat/webapps/examples/WEB-INF/lib/taglibs-standard-spec-1.2.5.jar new file mode 100644 index 0000000000000000000000000000000000000000..d54786732bcb5c48f907f5ce1436502aeb48ddef GIT binary patch literal 40153 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 GasLZO9-U_Z literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/displayProducts.tag b/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/displayProducts.tag new file mode 100644 index 0000000..41e8c35 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/displayProducts.tag @@ -0,0 +1,55 @@ + +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ attribute name="normalPrice" fragment="true" %> +<%@ attribute name="onSale" fragment="true" %> +<%@ variable name-given="name" %> +<%@ variable name-given="price" %> +<%@ variable name-given="origPrice" %> +<%@ variable name-given="salePrice" %> + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/helloWorld.tag b/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/helloWorld.tag new file mode 100644 index 0000000..192bf53 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/helloWorld.tag @@ -0,0 +1,17 @@ + +Hello, world! diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/panel.tag b/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/panel.tag new file mode 100644 index 0000000..f4f30d0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/tags/panel.tag @@ -0,0 +1,29 @@ + +<%@ attribute name="color" %> +<%@ attribute name="bgcolor" %> +<%@ attribute name="title" %> + + + + + + + +
    ${title}
    + +
    diff --git a/test.dockerapp/tomcat/webapps/examples/WEB-INF/web.xml b/test.dockerapp/tomcat/webapps/examples/WEB-INF/web.xml new file mode 100644 index 0000000..3e74cb4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/WEB-INF/web.xml @@ -0,0 +1,407 @@ + + + + + + Servlet and JSP Examples. + + Servlet and JSP Examples + + + + Timing Filter + filters.ExampleFilter + + attribute + filters.ExampleFilter + + + + + Request Dumper Filter + org.apache.catalina.filters.RequestDumperFilter + + + + + Set Character Encoding + org.apache.catalina.filters.SetCharacterEncodingFilter + true + + encoding + UTF-8 + + + ignore + false + + + + + Compression Filter + compressionFilters.CompressionFilter + + compressionThreshold + 128 + + + compressionBuffer + 8192 + + + compressionMimeTypes + text/html,text/plain,text/xml + + + debug + 0 + + + + + + + + + Set Character Encoding + /* + + + + + + + + + listeners.ContextListener + + + listeners.SessionListener + + + + + async.AsyncStockContextListener + + + + + + ServletToJsp + ServletToJsp + + + ChatServlet + chat.ChatServlet + + + CompressionFilterTestServlet + compressionFilters.CompressionFilterTestServlet + + + HelloWorldExample + HelloWorldExample + + + RequestInfoExample + RequestInfoExample + + + RequestHeaderExample + RequestHeaderExample + + + RequestParamExample + RequestParamExample + + + CookieExample + CookieExample + + + SessionExample + SessionExample + + + + ChatServlet + /servlets/chat/chat + + + CompressionFilterTestServlet + /CompressionTest + + + HelloWorldExample + /servlets/servlet/HelloWorldExample + + + RequestInfoExample + /servlets/servlet/RequestInfoExample/* + + + RequestHeaderExample + /servlets/servlet/RequestHeaderExample + + + RequestParamExample + /servlets/servlet/RequestParamExample + + + CookieExample + /servlets/servlet/CookieExample + + + SessionExample + /servlets/servlet/SessionExample + + + ServletToJsp + /servletToJsp + + + + + + http://tomcat.apache.org/debug-taglib + + + /WEB-INF/jsp/debug-taglib.tld + + + + + + http://tomcat.apache.org/example-taglib + + + /WEB-INF/jsp/example-taglib.tld + + + + + + http://tomcat.apache.org/jsp2-example-taglib + + + /WEB-INF/jsp2/jsp2-example-taglib.tld + + + + + + Special property group for JSP Configuration JSP example. + + JSPConfiguration + /jsp/jsp2/misc/config.jsp + true + ISO-8859-1 + true + /jsp/jsp2/misc/prelude.jspf + /jsp/jsp2/misc/coda.jspf + + + + + Example Security Constraint - part 1 + + Protected Area - Allow methods + + /jsp/security/protected/* + + + DELETE + GET + POST + PUT + + + + tomcat + role1 + + + + Example Security Constraint - part 2 + + Protected Area - Deny methods + + /jsp/security/protected/* + DELETE + GET + POST + PUT + + + + + + + + FORM + Example Form-Based Authentication Area + + /jsp/security/protected/login.jsp + /jsp/security/protected/error.jsp + + + + + + role1 + + + tomcat + + + + + + minExemptions + java.lang.Integer + 1 + + + foo/name1 + java.lang.String + value1 + + + foo/bar/name2 + java.lang.Boolean + true + + + name3 + java.lang.Integer + 1 + + + foo/name4 + java.lang.Integer + 10 + + + + + async0 + async.Async0 + true + + + async0 + /async/async0 + + + async1 + async.Async1 + true + + + async1 + /async/async1 + + + async2 + async.Async2 + true + + + async2 + /async/async2 + + + async3 + async.Async3 + true + + + async3 + /async/async3 + + + stock + async.AsyncStockServlet + true + + + stock + /async/stockticker + + + + + bytecounter + nonblocking.ByteCounter + true + + + bytecounter + /servlets/nonblocking/bytecounter + + + numberwriter + nonblocking.NumberWriter + true + + + numberwriter + /servlets/nonblocking/numberwriter + + + + index.html + index.xhtml + index.htm + index.jsp + + + + + websocket.drawboard.DrawboardContextListener + + + diff --git a/test.dockerapp/tomcat/webapps/examples/index.html b/test.dockerapp/tomcat/webapps/examples/index.html new file mode 100644 index 0000000..0799e10 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/index.html @@ -0,0 +1,30 @@ + + + +Apache Tomcat Examples + + +

    +

    Apache Tomcat Examples

    +

    +
    + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp new file mode 100644 index 0000000..b7e3da6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp @@ -0,0 +1,26 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page session="false"%> +Output from async1.jsp +Type is <%=request.getDispatcherType()%> +<% +System.out.println("Inside Async 1"); + if (request.isAsyncStarted()) { + request.getAsyncContext().complete(); + } +%> +Completed async request at <%=new java.sql.Date(System.currentTimeMillis())%> \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp.html new file mode 100644 index 0000000..503ae68 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/async/async1.jsp.html @@ -0,0 +1,27 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page session="false"%>
    +Output from async1.jsp
    +Type is <%=request.getDispatcherType()%>
    +<%
    +System.out.println("Inside Async 1");
    +  if (request.isAsyncStarted()) {
    +    request.getAsyncContext().complete();
    +  }
    +%>
    +Completed async request at <%=new java.sql.Date(System.currentTimeMillis())%>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp new file mode 100644 index 0000000..fd54054 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp @@ -0,0 +1,20 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page session="false"%> +Output from async3.jsp +Type is <%=request.getDispatcherType()%> +Completed async 3 request at <%=new java.sql.Date(System.currentTimeMillis())%> \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp.html new file mode 100644 index 0000000..f0d0a5b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/async/async3.jsp.html @@ -0,0 +1,21 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page session="false"%>
    +Output from async3.jsp
    +Type is <%=request.getDispatcherType()%>
    +Completed async 3 request at <%=new java.sql.Date(System.currentTimeMillis())%>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp new file mode 100644 index 0000000..be2d713 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp @@ -0,0 +1,69 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page session="false"%> + +
    +Use cases:
    +
    +1. Simple dispatch
    + - servlet does startAsync()
    + - background thread calls ctx.dispatch()
    +   "> Async 0 
    +
    +2. Simple dispatch
    + - servlet does startAsync()
    + - background thread calls dispatch(/path/to/jsp)
    +   "> Async 1 
    +
    +3. Simple dispatch
    + - servlet does startAsync()
    + - background thread calls writes and calls complete()
    +   "> Async 2 
    +
    +4. Simple dispatch
    + - servlet does a startAsync()
    + - servlet calls dispatch(/path/to/jsp)
    + - servlet calls complete()
    +   "> Async 3 
    +
    +3. Timeout s1
    + - servlet does a startAsync()
    + - servlet does a setAsyncTimeout
    + - returns - waits for timeout to happen should return error page
    +
    +4. Timeout s2
    + - servlet does a startAsync()
    + - servlet does a setAsyncTimeout
    + - servlet does a addAsyncListener
    + - returns - waits for timeout to happen and listener invoked
    +
    +5. Dispatch to asyncSupported=false servlet
    + - servlet1 does a startAsync()
    + - servlet1 dispatches to dispatch(/servlet2)
    + - the container calls complete() after servlet2 is complete
    + - TODO
    +
    +6. Chained dispatch
    + - servlet1 does a startAsync
    + - servlet1 does a dispatch to servlet2 (asyncsupported=true)
    + - servlet2 does a dispatch to servlet3 (asyncsupported=true)
    + - servlet3 does a dispatch to servlet4 (asyncsupported=false)
    +
    +
    +7. Stock ticker
    +   "> StockTicker 
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp.html new file mode 100644 index 0000000..778b643 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/async/index.jsp.html @@ -0,0 +1,70 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page session="false"%>
    +
    +<pre>
    +Use cases:
    +
    +1. Simple dispatch
    + - servlet does startAsync()
    + - background thread calls ctx.dispatch()
    +   <a href="<%=response.encodeURL("/examples/async/async0")%>"> Async 0 </a>
    +
    +2. Simple dispatch
    + - servlet does startAsync()
    + - background thread calls dispatch(/path/to/jsp)
    +   <a href="<%=response.encodeURL("/examples/async/async1")%>"> Async 1 </a>
    +
    +3. Simple dispatch
    + - servlet does startAsync()
    + - background thread calls writes and calls complete()
    +   <a href="<%=response.encodeURL("/examples/async/async2")%>"> Async 2 </a>
    +
    +4. Simple dispatch
    + - servlet does a startAsync()
    + - servlet calls dispatch(/path/to/jsp)
    + - servlet calls complete()
    +   <a href="<%=response.encodeURL("/examples/async/async3")%>"> Async 3 </a>
    +
    +3. Timeout s1
    + - servlet does a startAsync()
    + - servlet does a setAsyncTimeout
    + - returns - waits for timeout to happen should return error page
    +
    +4. Timeout s2
    + - servlet does a startAsync()
    + - servlet does a setAsyncTimeout
    + - servlet does a addAsyncListener
    + - returns - waits for timeout to happen and listener invoked
    +
    +5. Dispatch to asyncSupported=false servlet
    + - servlet1 does a startAsync()
    + - servlet1 dispatches to dispatch(/servlet2)
    + - the container calls complete() after servlet2 is complete
    + - TODO
    +
    +6. Chained dispatch
    + - servlet1 does a startAsync
    + - servlet1 does a dispatch to servlet2 (asyncsupported=true)
    + - servlet2 does a dispatch to servlet3 (asyncsupported=true)
    + - servlet3 does a dispatch to servlet4 (asyncsupported=false)
    +
    +
    +7. Stock ticker
    +   <a href="<%=response.encodeURL("/examples/async/stockticker")%>"> StockTicker </a>
    +</pre>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/Entries.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/Entries.java.html new file mode 100644 index 0000000..03f9a0c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/Entries.java.html @@ -0,0 +1,61 @@ +Source Code
    /*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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 cal;
    +
    +import java.util.Hashtable;
    +
    +import javax.servlet.http.HttpServletRequest;
    +
    +public class Entries {
    +
    +    private final Hashtable<String, Entry> entries;
    +    private static final String[] time = { "8am", "9am", "10am", "11am",
    +            "12pm", "1pm", "2pm", "3pm", "4pm", "5pm", "6pm", "7pm", "8pm" };
    +    public static final int rows = 12;
    +
    +    public Entries() {
    +        entries = new Hashtable<>(rows);
    +        for (int i = 0; i < rows; i++) {
    +            entries.put(time[i], new Entry(time[i]));
    +        }
    +    }
    +
    +    public int getRows() {
    +        return rows;
    +    }
    +
    +    public Entry getEntry(int index) {
    +        return this.entries.get(time[index]);
    +    }
    +
    +    public int getIndex(String tm) {
    +        for (int i = 0; i < rows; i++)
    +            if (tm.equals(time[i]))
    +                return i;
    +        return -1;
    +    }
    +
    +    public void processRequest(HttpServletRequest request, String tm) {
    +        int index = getIndex(tm);
    +        if (index >= 0) {
    +            String descr = request.getParameter("description");
    +            entries.get(time[index]).setDescription(descr);
    +        }
    +    }
    +
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/Entry.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/Entry.java.html new file mode 100644 index 0000000..7183a0a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/Entry.java.html @@ -0,0 +1,54 @@ +Source Code
    /*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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 cal;
    +
    +public class Entry {
    +
    +    final String hour;
    +    String description;
    +
    +    public Entry(String hour) {
    +        this.hour = hour;
    +        this.description = "";
    +
    +    }
    +
    +    public String getHour() {
    +        return this.hour;
    +    }
    +
    +    public String getColor() {
    +        if (description.equals("")) {
    +            return "lightblue";
    +        }
    +        return "red";
    +    }
    +
    +    public String getDescription() {
    +        if (description.equals("")) {
    +            return "None";
    +        }
    +        return this.description;
    +    }
    +
    +    public void setDescription(String descr) {
    +        description = descr;
    +    }
    +
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/JspCalendar.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/JspCalendar.java.html new file mode 100644 index 0000000..118996e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/JspCalendar.java.html @@ -0,0 +1,152 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 cal;
    +
    +import java.util.Calendar;
    +import java.util.Date;
    +
    +public class JspCalendar {
    +    final Calendar  calendar;
    +
    +    public JspCalendar() {
    +        calendar = Calendar.getInstance();
    +        Date trialTime = new Date();
    +        calendar.setTime(trialTime);
    +    }
    +
    +
    +    public int getYear() {
    +        return calendar.get(Calendar.YEAR);
    +    }
    +
    +    public String getMonth() {
    +        int m = getMonthInt();
    +        String[] months = new String [] { "January", "February", "March",
    +                                        "April", "May", "June",
    +                                        "July", "August", "September",
    +                                        "October", "November", "December" };
    +        if (m > 12)
    +            return "Unknown to Man";
    +
    +        return months[m - 1];
    +
    +    }
    +
    +    public String getDay() {
    +        int x = getDayOfWeek();
    +        String[] days = new String[] {"Sunday", "Monday", "Tuesday", "Wednesday",
    +                                      "Thursday", "Friday", "Saturday"};
    +
    +        if (x > 7)
    +            return "Unknown to Man";
    +
    +        return days[x - 1];
    +
    +    }
    +
    +    public int getMonthInt() {
    +        return 1 + calendar.get(Calendar.MONTH);
    +    }
    +
    +    public String getDate() {
    +        return getMonthInt() + "/" + getDayOfMonth() + "/" +  getYear();
    +    }
    +
    +    public String getCurrentDate() {
    +        Date dt = new Date ();
    +        calendar.setTime (dt);
    +        return getMonthInt() + "/" + getDayOfMonth() + "/" +  getYear();
    +
    +    }
    +
    +    public String getNextDate() {
    +        calendar.set (Calendar.DAY_OF_MONTH, getDayOfMonth() + 1);
    +        return getDate ();
    +    }
    +
    +    public String getPrevDate() {
    +        calendar.set (Calendar.DAY_OF_MONTH, getDayOfMonth() - 1);
    +        return getDate ();
    +    }
    +
    +    public String getTime() {
    +        return getHour() + ":" + getMinute() + ":" + getSecond();
    +    }
    +
    +    public int getDayOfMonth() {
    +        return calendar.get(Calendar.DAY_OF_MONTH);
    +    }
    +
    +    public int getDayOfYear() {
    +        return calendar.get(Calendar.DAY_OF_YEAR);
    +    }
    +
    +    public int getWeekOfYear() {
    +        return calendar.get(Calendar.WEEK_OF_YEAR);
    +    }
    +
    +    public int getWeekOfMonth() {
    +        return calendar.get(Calendar.WEEK_OF_MONTH);
    +    }
    +
    +    public int getDayOfWeek() {
    +        return calendar.get(Calendar.DAY_OF_WEEK);
    +    }
    +
    +    public int getHour() {
    +        return calendar.get(Calendar.HOUR_OF_DAY);
    +    }
    +
    +    public int getMinute() {
    +        return calendar.get(Calendar.MINUTE);
    +    }
    +
    +
    +    public int getSecond() {
    +        return calendar.get(Calendar.SECOND);
    +    }
    +
    +
    +    public int getEra() {
    +        return calendar.get(Calendar.ERA);
    +    }
    +
    +    public String getUSTimeZone() {
    +        String[] zones = new String[] {"Hawaii", "Alaskan", "Pacific",
    +                                       "Mountain", "Central", "Eastern"};
    +
    +        return zones[10 + getZoneOffset()];
    +    }
    +
    +    public int getZoneOffset() {
    +        return calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000);
    +    }
    +
    +
    +    public int getDSTOffset() {
    +        return calendar.get(Calendar.DST_OFFSET)/(60*60*1000);
    +    }
    +
    +
    +    public int getAMPM() {
    +        return calendar.get(Calendar.AM_PM);
    +    }
    +}
    +
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/TableBean.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/TableBean.java.html new file mode 100644 index 0000000..00a8a04 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/TableBean.java.html @@ -0,0 +1,102 @@ +Source Code
    /*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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 cal;
    +
    +import java.util.Hashtable;
    +
    +import javax.servlet.http.HttpServletRequest;
    +
    +public class TableBean {
    +
    +    final Hashtable<String, Entries> table;
    +    final JspCalendar JspCal;
    +    Entries entries;
    +    String date;
    +    String name = null;
    +    String email = null;
    +    boolean processError = false;
    +
    +    public TableBean() {
    +        this.table = new Hashtable<>(10);
    +        this.JspCal = new JspCalendar();
    +        this.date = JspCal.getCurrentDate();
    +    }
    +
    +    public void setName(String nm) {
    +        this.name = nm;
    +    }
    +
    +    public String getName() {
    +        return this.name;
    +    }
    +
    +    public void setEmail(String mail) {
    +        this.email = mail;
    +    }
    +
    +    public String getEmail() {
    +        return this.email;
    +    }
    +
    +    public String getDate() {
    +        return this.date;
    +    }
    +
    +    public Entries getEntries() {
    +        return this.entries;
    +    }
    +
    +    public void processRequest(HttpServletRequest request) {
    +
    +        // Get the name and e-mail.
    +        this.processError = false;
    +        if (name == null || name.equals(""))
    +            setName(request.getParameter("name"));
    +        if (email == null || email.equals(""))
    +            setEmail(request.getParameter("email"));
    +        if (name == null || email == null || name.equals("")
    +                || email.equals("")) {
    +            this.processError = true;
    +            return;
    +        }
    +
    +        // Get the date.
    +        String dateR = request.getParameter("date");
    +        if (dateR == null)
    +            date = JspCal.getCurrentDate();
    +        else if (dateR.equalsIgnoreCase("next"))
    +            date = JspCal.getNextDate();
    +        else if (dateR.equalsIgnoreCase("prev"))
    +            date = JspCal.getPrevDate();
    +
    +        entries = table.get(date);
    +        if (entries == null) {
    +            entries = new Entries();
    +            table.put(date, entries);
    +        }
    +
    +        // If time is provided add the event.
    +        String time = request.getParameter("time");
    +        if (time != null)
    +            entries.processRequest(request, time);
    +    }
    +
    +    public boolean getProcessError() {
    +        return this.processError;
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp new file mode 100644 index 0000000..e6b8a49 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp @@ -0,0 +1,94 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page contentType="text/html; charset=UTF-8" %> + + + Calendar: A JSP APPLICATION + + + + + +<%@ page language="java" import="cal.*" %> + + +<% + table.processRequest(request); + if (table.getProcessError() == false) { +%> + + +
    + + + + +
    prev + Calendar:<%= table.getDate() %> next +
    + + + + + + + + +<% + for(int i=0; i + + + + +<% + } +%> + +
    Time Appointment
    + > + <%= entr.getHour() %> + > + <% out.print(util.HTMLFilter.filter(entr.getDescription())); %> +
    +
    + + + + + + +
    <% out.print(util.HTMLFilter.filter(table.getName())); %> : + <% out.print(util.HTMLFilter.filter(table.getEmail())); %>
    +
    + +<% + } else { +%> + + You must enter your name and email address correctly. + +<% + } +%> + + + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp.html new file mode 100644 index 0000000..7daddf0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal1.jsp.html @@ -0,0 +1,95 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<HTML>
    +<HEAD><TITLE>
    +    Calendar: A JSP APPLICATION
    +</TITLE></HEAD>
    +
    +
    +<BODY BGCOLOR="white">
    +
    +<%@ page language="java" import="cal.*" %>
    +<jsp:useBean id="table" scope="session" class="cal.TableBean" />
    +
    +<%
    +    table.processRequest(request);
    +    if (table.getProcessError() == false) {
    +%>
    +
    +<!-- html table goes here -->
    +<CENTER>
    +<TABLE WIDTH=60% BGCOLOR=yellow CELLPADDING=15>
    +<TR>
    +<TD ALIGN=CENTER> <A HREF=cal1.jsp?date=prev> prev </A>
    +<TD ALIGN=CENTER> Calendar:<%= table.getDate() %></TD>
    +<TD ALIGN=CENTER> <A HREF=cal1.jsp?date=next> next </A>
    +</TR>
    +</TABLE>
    +
    +<!-- the main table -->
    +<TABLE WIDTH=60% BGCOLOR=lightblue BORDER=1 CELLPADDING=10>
    +<TR>
    +<TH> Time </TH>
    +<TH> Appointment </TH>
    +</TR>
    +<FORM METHOD=POST ACTION=cal1.jsp>
    +<%
    +    for(int i=0; i<table.getEntries().getRows(); i++) {
    +       cal.Entry entr = table.getEntries().getEntry(i);
    +%>
    +    <TR>
    +    <TD>
    +    <A HREF=cal2.jsp?time=<%= entr.getHour() %>>
    +        <%= entr.getHour() %> </A>
    +    </TD>
    +    <TD BGCOLOR=<%= entr.getColor() %>>
    +    <% out.print(util.HTMLFilter.filter(entr.getDescription())); %>
    +    </TD>
    +    </TR>
    +<%
    +    }
    +%>
    +</FORM>
    +</TABLE>
    +<BR>
    +
    +<!-- footer -->
    +<TABLE WIDTH=60% BGCOLOR=yellow CELLPADDING=15>
    +<TR>
    +<TD ALIGN=CENTER>  <% out.print(util.HTMLFilter.filter(table.getName())); %> :
    +             <% out.print(util.HTMLFilter.filter(table.getEmail())); %> </TD>
    +</TR>
    +</TABLE>
    +</CENTER>
    +
    +<%
    +    } else {
    +%>
    +<font size=5>
    +    You must enter your name and email address correctly.
    +</font>
    +<%
    +    }
    +%>
    +
    +
    +</BODY>
    +</HTML>
    +
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp new file mode 100644 index 0000000..e7e14d8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp @@ -0,0 +1,45 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page contentType="text/html; charset=UTF-8" %> + + + Calendar: A JSP APPLICATION + + + + + + +<% + String time = request.getParameter ("time"); +%> + + Please add the following event: +

    Date <%= table.getDate() %> +
    Time <%= util.HTMLFilter.filter(time) %>

    +
    +
    +
    +
    +
    +

    Description of the event

    +
    +
    + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp.html new file mode 100644 index 0000000..2cc191b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/cal2.jsp.html @@ -0,0 +1,46 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<HTML>
    +<HEAD><TITLE>
    +    Calendar: A JSP APPLICATION
    +</TITLE></HEAD>
    +
    +
    +<BODY BGCOLOR="white">
    +<jsp:useBean id="table" scope="session" class="cal.TableBean" />
    +
    +<%
    +    String time = request.getParameter ("time");
    +%>
    +
    +<FONT SIZE=5> Please add the following event:
    +<BR> <h3> Date <%= table.getDate() %>
    +<BR> Time <%= util.HTMLFilter.filter(time) %> </h3>
    +</FONT>
    +<FORM METHOD=POST ACTION=cal1.jsp>
    +<BR>
    +<BR> <INPUT NAME="date" TYPE=HIDDEN VALUE="current">
    +<BR> <INPUT NAME="time" TYPE=HIDDEN VALUE="<%= util.HTMLFilter.filter(time) %>">
    +<BR> <h2> Description of the event <INPUT NAME="description" TYPE=TEXT SIZE=20> </h2>
    +<BR> <INPUT TYPE=SUBMIT VALUE="submit">
    +</FORM>
    +
    +</BODY>
    +</HTML>
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/calendar.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/calendar.html new file mode 100644 index 0000000..a0a3ea1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/calendar.html @@ -0,0 +1,43 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Calendar Example.
    +

    cal1.jsp +

    +

    cal2.jsp +

    + +
    +

    Beans. +

    TableBean +

    +

    Entries +

    +

    Entry +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/cal/login.html b/test.dockerapp/tomcat/webapps/examples/jsp/cal/login.html new file mode 100644 index 0000000..2c4aa55 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/cal/login.html @@ -0,0 +1,47 @@ + + + + + Login page for the calendar. + + + +
    + + Please Enter the following information: + +
    +
    + + Name + +
    + Email + +
    + + +
    +
    + Note: This application does not implement the complete +functionality of a typical calendar application. It demonstrates a way JSP can +be used with html tables and forms. + +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/CheckTest.html b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/CheckTest.html new file mode 100644 index 0000000..284d9ec --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/CheckTest.html @@ -0,0 +1,56 @@ + + + + + +checkbox.CheckTest Bean Properties + + +

    +checkbox.CheckTest Bean Properties +

    +
    +
    +
    public class CheckTest
    extends Object
    + +

    +


    + +

    + + + + + + + + + +
    +Properties Summary
    + +String +CheckTest:fruit +
    +
    + +Multi +
    +


    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/check.html b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/check.html new file mode 100644 index 0000000..b6d6b3b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/check.html @@ -0,0 +1,38 @@ + + + + + + +
    +
    + +Check all Favorite fruits:
    + + Apples
    + Grapes
    + Oranges
    + Melons
    + + +
    + +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp new file mode 100644 index 0000000..a8400e9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp @@ -0,0 +1,63 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + +<%! String[] fruits; %> + + + +
    +The checked fruits (got using request) are:
    +<% + fruits = request.getParameterValues("fruit"); +%> +
      +<% + if (fruits != null) { + for (int i = 0; i < fruits.length; i++) { +%> +
    • +<% + out.println (util.HTMLFilter.filter(fruits[i])); + } + } else out.println ("none selected"); +%> +
    +
    +
    + +The checked fruits (got using beans) are
    + +<% + fruits = foo.getFruit(); +%> +
      +<% + if (!fruits[0].equals("1")) { + for (int i = 0; i < fruits.length; i++) { +%> +
    • +<% + out.println (util.HTMLFilter.filter(fruits[i])); + } + } else out.println ("none selected"); +%> +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp.html new file mode 100644 index 0000000..4dd0d9b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/checkresult.jsp.html @@ -0,0 +1,64 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<body bgcolor="white">
    +<font size=5 color="red">
    +<%! String[] fruits; %>
    +<jsp:useBean id="foo" scope="page" class="checkbox.CheckTest" />
    +
    +<jsp:setProperty name="foo" property="fruit" param="fruit" />
    +<hr>
    +The checked fruits (got using request) are: <br>
    +<%
    +    fruits = request.getParameterValues("fruit");
    +%>
    +<ul>
    +<%
    +    if (fruits != null) {
    +      for (int i = 0; i < fruits.length; i++) {
    +%>
    +<li>
    +<%
    +          out.println (util.HTMLFilter.filter(fruits[i]));
    +      }
    +    } else out.println ("none selected");
    +%>
    +</ul>
    +<br>
    +<hr>
    +
    +The checked fruits (got using beans) are <br>
    +
    +<%
    +        fruits = foo.getFruit();
    +%>
    +<ul>
    +<%
    +    if (!fruits[0].equals("1")) {
    +      for (int i = 0; i < fruits.length; i++) {
    +%>
    +<li>
    +<%
    +          out.println (util.HTMLFilter.filter(fruits[i]));
    +      }
    +    } else out.println ("none selected");
    +%>
    +</ul>
    +</font>
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/cresult.html b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/cresult.html new file mode 100644 index 0000000..b6a28d6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/checkbox/cresult.html @@ -0,0 +1,34 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Checkbox Example +

    + +

    Property Sheet for CheckTest +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/colors/ColorGameBean.html b/test.dockerapp/tomcat/webapps/examples/jsp/colors/ColorGameBean.html new file mode 100644 index 0000000..172bc66 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/colors/ColorGameBean.html @@ -0,0 +1,116 @@ + + + + + +colors.ColorGameBean Bean Properties + + +

    +colors.ColorGameBean Bean Properties +

    +
    +
    +
    public class ColorGameBean
    extends Object
    + +

    +


    + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Properties Summary
    + +String +ColorGameBean:color2 +
    +
    + +Single +
    + +String +ColorGameBean:color1 +
    +
    + +Single +
    + +int +ColorGameBean:attempts +
    +
    + +Single +
    + +boolean +ColorGameBean:hint +
    +
    + +Single +
    + +boolean +ColorGameBean:success +
    +
    + +Single +
    + +boolean +ColorGameBean:hintTaken +
    +
    + +Single +
    +


    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/colors/clr.html b/test.dockerapp/tomcat/webapps/examples/jsp/colors/clr.html new file mode 100644 index 0000000..e411f59 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/colors/clr.html @@ -0,0 +1,34 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Color Example +

    + +

    Property Sheet for ColorGameBean +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/colors/colors.html b/test.dockerapp/tomcat/webapps/examples/jsp/colors/colors.html new file mode 100644 index 0000000..900651e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/colors/colors.html @@ -0,0 +1,47 @@ + + + + + + +
    +This web page is an example using JSP and BEANs. +

    +Guess my favorite two colors + +

    If you fail to guess both of them - you get yellow on red. + +

    If you guess one of them right, either your foreground or + your background will change to the color that was guessed right. + +

    Guess them both right and your browser foreground/background + will change to my two favorite colors to display this page. + +


    +
    +Color #1: +
    +Color #2: +

    + + +

    + +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp new file mode 100644 index 0000000..ec3af88 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp @@ -0,0 +1,70 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + + +<% + cb.processRequest(); +%> + +> +> +

    + +<% if (cb.getHint()==true) { %> + +

    Hint #1: Vampires prey at night! +

    Hint #2: Nancy without the n. + +<% } %> + +<% if (cb.getSuccess()==true) { %> + +

    CONGRATULATIONS!! + <% if (cb.getHintTaken()==true) { %> + +

    ( although I know you cheated and peeked into the hints) + + <% } %> + +<% } %> + +

    Total attempts so far: <%= cb.getAttempts() %> +

    + +

    + +

    + +Color #1: + +
    + +Color #2: + +

    + + + + +

    + +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp.html new file mode 100644 index 0000000..7ef38ae --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/colors/colrs.jsp.html @@ -0,0 +1,71 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +
    +<jsp:useBean id="cb" scope="session" class="colors.ColorGameBean" />
    +<jsp:setProperty name="cb" property="*" />
    +
    +<%
    +    cb.processRequest();
    +%>
    +
    +<body bgcolor=<%= cb.getColor1() %>>
    +<font size=6 color=<%= cb.getColor2() %>>
    +<p>
    +
    +<% if (cb.getHint()==true) { %>
    +
    +    <p> Hint #1: Vampires prey at night!
    +    <p>  <p> Hint #2: Nancy without the n.
    +
    +<% } %>
    +
    +<% if  (cb.getSuccess()==true) { %>
    +
    +    <p> CONGRATULATIONS!!
    +    <% if  (cb.getHintTaken()==true) { %>
    +
    +        <p> ( although I know you cheated and peeked into the hints)
    +
    +    <% } %>
    +
    +<% } %>
    +
    +<p> Total attempts so far: <%= cb.getAttempts() %>
    +<p>
    +
    +<p>
    +
    +<form method=POST action=colrs.jsp>
    +
    +Color #1: <input type=text name= color1 size=16>
    +
    +<br>
    +
    +Color #2: <input type=text name= color2 size=16>
    +
    +<p>
    +
    +<input type=submit name=action value="Submit">
    +<input type=submit name=action value="Hint">
    +
    +</form>
    +
    +</font>
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.html b/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.html new file mode 100644 index 0000000..683ab4d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.html @@ -0,0 +1,31 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Date Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp new file mode 100644 index 0000000..d6c6b86 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp @@ -0,0 +1,41 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + +<%@ page session="false"%> + + + + + +
      +
    • Day of month: is +
    • Year: is +
    • Month: is +
    • Time: is +
    • Date: is +
    • Day: is +
    • Day Of Year: is +
    • Week Of Year: is +
    • era: is +
    • DST Offset: is +
    • Zone Offset: is +
    +
    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp.html new file mode 100644 index 0000000..3f2abfc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/dates/date.jsp.html @@ -0,0 +1,42 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +
    +<%@ page session="false"%>
    +
    +<body bgcolor="white">
    +<jsp:useBean id='clock' scope='page' class='dates.JspCalendar' type="dates.JspCalendar" />
    +
    +<font size=4>
    +<ul>
    +<li>    Day of month: is  <jsp:getProperty name="clock" property="dayOfMonth"/>
    +<li>    Year: is  <jsp:getProperty name="clock" property="year"/>
    +<li>    Month: is  <jsp:getProperty name="clock" property="month"/>
    +<li>    Time: is  <jsp:getProperty name="clock" property="time"/>
    +<li>    Date: is  <jsp:getProperty name="clock" property="date"/>
    +<li>    Day: is  <jsp:getProperty name="clock" property="day"/>
    +<li>    Day Of Year: is  <jsp:getProperty name="clock" property="dayOfYear"/>
    +<li>    Week Of Year: is  <jsp:getProperty name="clock" property="weekOfYear"/>
    +<li>    era: is  <jsp:getProperty name="clock" property="era"/>
    +<li>    DST Offset: is  <jsp:getProperty name="clock" property="DSTOffset"/>
    +<li>    Zone Offset: is  <jsp:getProperty name="clock" property="zoneOffset"/>
    +</ul>
    +</font>
    +
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/error/er.html b/test.dockerapp/tomcat/webapps/examples/jsp/error/er.html new file mode 100644 index 0000000..af78159 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/error/er.html @@ -0,0 +1,31 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Error Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp new file mode 100644 index 0000000..d188456 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp @@ -0,0 +1,44 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + <%@ page errorPage="errorpge.jsp" %> + + <% + String name = null; + + if (request.getParameter("name") == null) { + %> + <%@ include file="error.html" %> + <% + } else { + foo.setName(request.getParameter("name")); + if (foo.getName().equalsIgnoreCase("integra")) + name = "acura"; + if (name.equalsIgnoreCase("acura")) { + %> + +

    Yes!!! Acura is my favorite car. + + <% + } + } + %> + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp.html new file mode 100644 index 0000000..3d607a5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/error/err.jsp.html @@ -0,0 +1,45 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<body bgcolor="lightblue">
    +
    +    <%@ page errorPage="errorpge.jsp" %>
    +    <jsp:useBean id="foo" scope="request" class="error.Smart" />
    +    <%
    +        String name = null;
    +
    +        if (request.getParameter("name") == null) {
    +    %>
    +    <%@ include file="error.html" %>
    +    <%
    +        } else {
    +          foo.setName(request.getParameter("name"));
    +          if (foo.getName().equalsIgnoreCase("integra"))
    +              name = "acura";
    +          if (name.equalsIgnoreCase("acura")) {
    +    %>
    +
    +    <H1> Yes!!! <a href="http://www.acura.com">Acura</a> is my favorite car.
    +
    +    <%
    +          }
    +        }
    +    %>
    +</body>
    +</html>
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/error/error.html b/test.dockerapp/tomcat/webapps/examples/jsp/error/error.html new file mode 100644 index 0000000..b1b029c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/error/error.html @@ -0,0 +1,37 @@ + + + + + +

    This example uses errorpage directive

    +
    +

    Select my favourite car.

    +
    + + +
    +
    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp new file mode 100644 index 0000000..5c6eb0a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp @@ -0,0 +1,25 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + + <%@ page isErrorPage="true" %> +

    The exception <%= exception.getMessage() %> tells me you + made a wrong choice. + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp.html new file mode 100644 index 0000000..3d690dc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/error/errorpge.jsp.html @@ -0,0 +1,26 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +
    +<body bgcolor="red">
    +
    +    <%@ page isErrorPage="true" %>
    +    <h1> The exception <%= exception.getMessage() %> tells me you
    +         made a wrong choice.
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp new file mode 100644 index 0000000..092d9b4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp @@ -0,0 +1,33 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + +<% + double freeMem = Runtime.getRuntime().freeMemory(); + double totlMem = Runtime.getRuntime().totalMemory(); + double percent = freeMem/totlMem; + if (percent < 0.5) { +%> + + + +<% } else { %> + + + +<% } %> + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp.html new file mode 100644 index 0000000..32f8bf7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/forward/forward.jsp.html @@ -0,0 +1,34 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<%
    +   double freeMem = Runtime.getRuntime().freeMemory();
    +   double totlMem = Runtime.getRuntime().totalMemory();
    +   double percent = freeMem/totlMem;
    +   if (percent < 0.5) {
    +%>
    +
    +<jsp:forward page="one.jsp"/>
    +
    +<% } else { %>
    +
    +<jsp:forward page="two.html"/>
    +
    +<% } %>
    +
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/forward/fwd.html b/test.dockerapp/tomcat/webapps/examples/jsp/forward/fwd.html new file mode 100644 index 0000000..b3b0219 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/forward/fwd.html @@ -0,0 +1,30 @@ + + + +Untitled Document + + + + +

    + +

    Source Code for Forward Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp new file mode 100644 index 0000000..c7f0004 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp @@ -0,0 +1,23 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + + +VM Memory usage < 50%. + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp.html new file mode 100644 index 0000000..af18501 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/forward/one.jsp.html @@ -0,0 +1,24 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +
    +<body bgcolor="white">
    +<font color="red">
    +
    +VM Memory usage &lt; 50%.
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/forward/two.html b/test.dockerapp/tomcat/webapps/examples/jsp/forward/two.html new file mode 100644 index 0000000..24f4c08 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/forward/two.html @@ -0,0 +1,23 @@ + + + + + + +VM Memory usage > 50%. + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/images/code.gif b/test.dockerapp/tomcat/webapps/examples/jsp/images/code.gif new file mode 100644 index 0000000000000000000000000000000000000000..93af2cd130aa61cb2f235cdd6f0e75ab444819ef GIT binary patch literal 292 zcmZ?wbhEHblwgoxIP#z2z<~q*(`NopOZ#sOM8;>*(#{wIk?|P@o$6#>Qz3K*V4S1Pnk5hzS72pDc_ZB|0DiWTyk`LIs7s6iv0@q;(ETk{*X8*p&Sz zS?%Jy|7uNwX5dT_rVVU*FIJccbhvMP#4t}Kw7uYTuBh_VnCTjt97)}qgEke3iU+j# zdTyN*!`HsV>FFn-s95XDrdAynk)$>kVJ;@##Ikl#0e5yDZsrM%j-vc*EJY@UJi>F- w^aL|Jc?Bj;=4WLO5adbda@4El6|}Iev#dyLst@fxxV)*dq0M4 zuU27uS$av`))UvZFOHHZ*ItST2O0$7;7H? zm&+9jg_V_+QmIrfmut0JNgWD>N~y#dv!$ejV3mcCNeF_Fs91zF06g0g%rptkdaf-6 zF_0xVM$i_FQ|#InC0H;@)orLVf()pw6mqsDEh%itRj8`R2I3~Mg(*yIbHb?sbqyn3 zQYZyCsY->?M4l}qr>- z0I$VBAEL|c3!Aa23>>`6zgZI-x?7(TmI_v%;048`BL-aEhiAV!!lj_8tNy{ zuHVlON6V>(=ELvD+RJkuyyRyVcEVSxb@v=^_xJ8_AXukA`|R1H)q9Ptr@mW4Q_jP; zvV-p8YH%TPuI2Q*17~mjF+W7_4*dGfOe`P2(>42bIlAt3wjaL+tnW9`gI6%iQm3_`St79 z-o1NEOG}%Ynk*G1wxrosIqNvqnY}xbY&!4YDJiK~ zJ(;s9MkiB^52u^X3e}4;R!E2p+p%-!hY#;puU_5J(UF~5hI=BBG{#Lvgqddaj4L|MyUuVNmX8s!x@$*GmKAWm@dju`F)!E?FkWEJ!v~>q2rkrCo+srXPOl_ z%Qhqnd)o;{>dBr+GdY)Hd?eH4Y?_gmy6CENz$sYS8sNdpXzI(A}*9~tCVk}QfaGLWv5u{sM6}9(dD7r z@1sB4-)wP+NvOW!q(HrLD-Bs`DHBr@I~!{YGgDnHEd_CLQC?0yRu&^gNo_HaP3{as z4k`WCR@Sj14g@J)V0GL@AIQ}vG=ali- zu;5@51Cxx6M#6zZO)Ojz79R=}nphY`Bw`LEBrvn{E4WN>C}3*k64OgKu^^GTollOV zjzQ4r2#1iW&m4z|PDi^Mb)t4uFe(?^_7TL=o*=wO{(2ujnO+w8c$v4zM`LSsN<)3n~&tajt5>p6MrRUH;*T;EHtq`6t7F{rJhOalziPnL~6|&I^G> zE?r`Oldqh(n0cgM!F7^J=cWB#)AW3=U1Sbc^PO$+_w|#Pmx}^woI0gcCxoo@UUo=p z{;iFR1y+Tu3gb+Q#4vn(x+N>Q)$&RbyXeH}5khoAZ zgHYWn8m8H>&V#9A@nKri+6f7CAZX^n(t)JHP^8RL7z)bJ*uqp1CeXrcK^P~G{tuqV z^BsQQ$2pwh@zEn}1p^F%5QJd}Aw&paj0qu>(zUfUmSs7P<9S{Xgle@~tJOqNtk>(3 zB+0U@D2l48nx^TxZWsoa&$A3e34s7$jDj$XWIqfUmW{ZO5C9=SDAKGTH2r`GRm|~r z5L$j98>Zp~kYOR42b6JwQ1b%S^%chx9UoE#D+ZEvK&b8ovKvT_U$;Hc_5{o0Esv@u zV|vtZNi@a@L^X--U`fN84f8w{M0eXUG$N)K%8oDDURAev)u`Ei)$*#g&zml%+l*qc z5u_%u5lz+^!=({{P?YDX?hsigszo##*Hy@JNK{Z=MY4eu6Y@37k1~gfg@L4*NB(TMHD`z5Mi$4{3$K3Fd0=2+ z2&SJ^4mHd1^M91~z5jb@w)hR4@9nxce6>IZv*odP-zSex6`o(pw(oi7X69J;zL6Ew zmMCYwj%&NFbnm5LWxe~Y@k3x5DnB+pXsm90nHrr#zm +To get the current time in ms diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp new file mode 100644 index 0000000..bb476c7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp @@ -0,0 +1,17 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +--%><%= System.currentTimeMillis() %> diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp.html new file mode 100644 index 0000000..2a1ac7b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/include/foo.jsp.html @@ -0,0 +1,18 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +
    +--%><%= System.currentTimeMillis() %>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/include/inc.html b/test.dockerapp/tomcat/webapps/examples/jsp/include/inc.html new file mode 100644 index 0000000..fedaed0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/include/inc.html @@ -0,0 +1,30 @@ + + + +Untitled Document + + + + +

    + +

    Source Code for Include Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp new file mode 100644 index 0000000..62a8c22 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp @@ -0,0 +1,30 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + + + +<%@ page buffer="5kb" autoFlush="false" %> + +

    In place evaluation of another JSP which gives you the current time: <%@ include file="foo.jsp" %> + +

    by including the output of another JSP: +:-) + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp.html new file mode 100644 index 0000000..4f529c1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/include/include.jsp.html @@ -0,0 +1,31 @@ +Source Code

    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +
    +<body bgcolor="white">
    +
    +<font color="red">
    +
    +<%@ page buffer="5kb" autoFlush="false" %>
    +
    +<p>In place evaluation of another JSP which gives you the current time: <%@ include file="foo.jsp" %>
    +
    +<p> <jsp:include page="foo.html" flush="true"/> by including the output of another JSP: <jsp:include page="foo.jsp" flush="true"/>
    +:-)
    +
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/index.html b/test.dockerapp/tomcat/webapps/examples/jsp/index.html new file mode 100644 index 0000000..f61d5bf --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/index.html @@ -0,0 +1,370 @@ + + + + + + JSP Examples + + + +

    JSP +Samples

    +

    This is a collection of samples demonstrating the usage of different +parts of the Java Server Pages (JSP) specification. Both JSP 2.0 and +JSP 1.2 examples are presented below. +

    These examples will only work when these pages are being served by a +servlet engine; of course, we recommend +Tomcat. +They will not work if you are viewing these pages via a +"file://..." URL. +

    To navigate your way through the examples, the following icons will +help:

    +
      +
    • Execute the example
    • +
    • Look at the source code for the example
    • + +
    • Return to this screen
    • +
    + +

    Tip: For session scoped beans to work, the cookies must be enabled. +This can be done using browser options.

    +

    JSP 2.0 Examples

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Expression Language
    Basic ArithmeticExecuteSource
    Basic ComparisonsExecuteSource
    Implicit ObjectsExecuteSource
    FunctionsExecuteSource
    Composite ExpressionsExecuteSource

    SimpleTag Handlers and JSP Fragments
    Hello World TagExecuteSource
    Repeat TagExecuteSource
    Book ExampleExecuteSource

    Tag Files
    Hello World Tag FileExecuteSource
    Panel Tag FileExecuteSource
    Display Products ExampleExecuteSource

    New JSP XML Syntax (.jspx)
    XHTML Basic ExampleExecuteSource
    SVG (Scalable Vector Graphics)ExecuteSource

    Other JSP 2.0 Features
    <jsp:attribute> and <jsp:body>ExecuteSource
    Shuffle ExampleExecuteSource
    Attributes With Dynamic NamesExecuteSource
    JSP ConfigurationExecuteSource
    + +

    JSP 1.2 Examples

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NumberguessExecuteSource
    DateExecuteSource
    SnoopExecuteSource
    ErrorPageExecuteSource
    CartsExecuteSource
    CheckboxExecuteSource
    ColorExecuteSource
    CalendarExecuteSource
    IncludeExecuteSource
    ForwardExecuteSource
    PluginExecuteSource
    JSP-Servlet-JSPExecuteSource
    Custom tag exampleExecuteSource
    XML syntax exampleExecuteSource
    + +

    Tag Plugins

    + + + + + + + + + + + + + + + + + + + + +
    If + + Execute + + + Source +
    ForEach + + Execute + + + Source +
    Choose + + Execute + + + Source +
    + +

    Other Examples

    + + + + + + + + + + + +
    FORM Authentication + Execute +
    Example that demonstrates protecting a resource and + using Form-Based authentication. To access the page the user must + have role of either "tomcat" or "role1". By default no user + is configured to have these roles.
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/Functions.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/Functions.java.html new file mode 100644 index 0000000..aa84ccc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/Functions.java.html @@ -0,0 +1,46 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.el;
    +
    +import java.util.Locale;
    +
    +/**
    + * Defines the functions for the jsp2 example tag library.
    + *
    + * <p>Each function is defined as a static method.</p>
    + */
    +public class Functions {
    +    public static String reverse( String text ) {
    +        return new StringBuilder( text ).reverse().toString();
    +    }
    +
    +    public static int numVowels( String text ) {
    +        String vowels = "aeiouAEIOU";
    +        int result = 0;
    +        for( int i = 0; i < text.length(); i++ ) {
    +            if( vowels.indexOf( text.charAt( i ) ) != -1 ) {
    +                result++;
    +            }
    +        }
    +        return result;
    +    }
    +
    +    public static String caps( String text ) {
    +        return text.toUpperCase(Locale.ENGLISH);
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesBean.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesBean.java.html new file mode 100644 index 0000000..3744236 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesBean.java.html @@ -0,0 +1,53 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples;
    +
    +/**
    + * Accept and display a value.
    + */
    +public class ValuesBean {
    +    private String string;
    +    private double doubleValue;
    +    private long longValue;
    +
    +    public String getStringValue() {
    +        return this.string;
    +    }
    +
    +    public void setStringValue(String string) {
    +        this.string = string;
    +    }
    +
    +    public double getDoubleValue() {
    +        return doubleValue;
    +    }
    +
    +    public void setDoubleValue(double doubleValue) {
    +        this.doubleValue = doubleValue;
    +    }
    +
    +    public long getLongValue() {
    +        return longValue;
    +    }
    +
    +    public void setLongValue(long longValue) {
    +        this.longValue = longValue;
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesTag.java.html new file mode 100644 index 0000000..490d212 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/ValuesTag.java.html @@ -0,0 +1,80 @@ +Source Code
    /*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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 examples;
    +
    +import java.io.IOException;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.JspTagException;
    +import javax.servlet.jsp.JspWriter;
    +import javax.servlet.jsp.tagext.TagSupport;
    +
    +/**
    + * Accept and display a value.
    + */
    +public class ValuesTag extends TagSupport {
    +
    +    private static final long serialVersionUID = 1L;
    +
    +    // Using "-1" as the default value,
    +    // in the assumption that it won't be used as the value.
    +    // Cannot use null here, because null is an important case
    +    // that should be present in the tests.
    +    private Object objectValue = "-1";
    +    private String stringValue = "-1";
    +    private long longValue = -1;
    +    private double doubleValue = -1;
    +
    +    public void setObject(Object objectValue) {
    +        this.objectValue = objectValue;
    +    }
    +
    +    public void setString(String stringValue) {
    +        this.stringValue = stringValue;
    +    }
    +
    +    public void setLong(long longValue) {
    +        this.longValue = longValue;
    +    }
    +
    +    public void setDouble(double doubleValue) {
    +        this.doubleValue = doubleValue;
    +    }
    +
    +    @Override
    +    public int doEndTag() throws JspException {
    +        JspWriter out = pageContext.getOut();
    +
    +        try {
    +            if (!"-1".equals(objectValue)) {
    +                out.print(objectValue);
    +            } else if (!"-1".equals(stringValue)) {
    +                out.print(stringValue);
    +            } else if (longValue != -1) {
    +                out.print(longValue);
    +            } else if (doubleValue != -1) {
    +                out.print(doubleValue);
    +            } else {
    +                out.print("-1");
    +            }
    +        } catch (IOException ex) {
    +            throw new JspTagException("IOException: " + ex.toString(), ex);
    +        }
    +        return super.doEndTag();
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.html new file mode 100644 index 0000000..8a2f0a6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.html @@ -0,0 +1,30 @@ + + + +View Source Code + + + + +

    + +

    Source Code for Basic Arithmetic Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp new file mode 100644 index 0000000..757e809 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp @@ -0,0 +1,88 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + JSP 2.0 Expression Language - Basic Arithmetic + + +

    JSP 2.0 Expression Language - Basic Arithmetic

    +
    + This example illustrates basic Expression Language arithmetic. + Addition (+), subtraction (-), multiplication (*), division (/ or div), + and modulus (% or mod) are all supported. Error conditions, like + division by zero, are handled gracefully. +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EL ExpressionResult
    \${1}${1}
    \${1 + 2}${1 + 2}
    \${1.2 + 2.3}${1.2 + 2.3}
    \${1.2E4 + 1.4}${1.2E4 + 1.4}
    \${-4 - 2}${-4 - 2}
    \${21 * 2}${21 * 2}
    \${3/4}${3/4}
    \${3 div 4}${3 div 4}
    \${3/0}${3/0}
    \${10%4}${10%4}
    \${10 mod 4}${10 mod 4}
    \${(1==2) ? 3 : 4}${(1==2) ? 3 : 4}
    +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp.html new file mode 100644 index 0000000..b8e1a69 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-arithmetic.jsp.html @@ -0,0 +1,89 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Expression Language - Basic Arithmetic</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Expression Language - Basic Arithmetic</h1>
    +    <hr>
    +    This example illustrates basic Expression Language arithmetic.
    +    Addition (+), subtraction (-), multiplication (*), division (/ or div),
    +    and modulus (% or mod) are all supported.  Error conditions, like
    +    division by zero, are handled gracefully.
    +    <br>
    +    <blockquote>
    +      <code>
    +        <table border="1">
    +          <thead>
    +        <td><b>EL Expression</b></td>
    +        <td><b>Result</b></td>
    +      </thead>
    +      <tr>
    +        <td>\${1}</td>
    +        <td>${1}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1 + 2}</td>
    +        <td>${1 + 2}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1.2 + 2.3}</td>
    +        <td>${1.2 + 2.3}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1.2E4 + 1.4}</td>
    +        <td>${1.2E4 + 1.4}</td>
    +      </tr>
    +      <tr>
    +        <td>\${-4 - 2}</td>
    +        <td>${-4 - 2}</td>
    +      </tr>
    +      <tr>
    +        <td>\${21 * 2}</td>
    +        <td>${21 * 2}</td>
    +      </tr>
    +      <tr>
    +        <td>\${3/4}</td>
    +        <td>${3/4}</td>
    +      </tr>
    +      <tr>
    +        <td>\${3 div 4}</td>
    +        <td>${3 div 4}</td>
    +      </tr>
    +      <tr>
    +        <td>\${3/0}</td>
    +        <td>${3/0}</td>
    +      </tr>
    +      <tr>
    +        <td>\${10%4}</td>
    +        <td>${10%4}</td>
    +      </tr>
    +      <tr>
    +        <td>\${10 mod 4}</td>
    +        <td>${10 mod 4}</td>
    +      </tr>
    +    <tr>
    +      <td>\${(1==2) ? 3 : 4}</td>
    +      <td>${(1==2) ? 3 : 4}</td>
    +    </tr>
    +    </table>
    +      </code>
    +    </blockquote>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.html new file mode 100644 index 0000000..60fb40a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.html @@ -0,0 +1,30 @@ + + + +View Source Code + + + + +

    + +

    Source Code for Basic Comparisons Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp new file mode 100644 index 0000000..d72f724 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp @@ -0,0 +1,116 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + JSP 2.0 Expression Language - Basic Comparisons + + +

    JSP 2.0 Expression Language - Basic Comparisons

    +
    + This example illustrates basic Expression Language comparisons. + The following comparison operators are supported: +
      +
    • Less-than (< or lt)
    • +
    • Greater-than (> or gt)
    • +
    • Less-than-or-equal (<= or le)
    • +
    • Greater-than-or-equal (>= or ge)
    • +
    • Equal (== or eq)
    • +
    • Not Equal (!= or ne)
    • +
    +
    + Numeric + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EL ExpressionResult
    \${1 < 2}${1 < 2}
    \${1 lt 2}${1 lt 2}
    \${1 > (4/2)}${1 > (4/2)}
    \${1 gt (4/2)}${1 gt (4/2)}
    \${4.0 >= 3}${4.0 >= 3}
    \${4.0 ge 3}${4.0 ge 3}
    \${4 <= 3}${4 <= 3}
    \${4 le 3}${4 le 3}
    \${100.0 == 100}${100.0 == 100}
    \${100.0 eq 100}${100.0 eq 100}
    \${(10*10) != 100}${(10*10) != 100}
    \${(10*10) ne 100}${(10*10) ne 100}
    +
    +
    + Alphabetic + + + + + + + + + + + + + + + + + + +
    EL ExpressionResult
    \${'a' < 'b'}${'a' < 'b'}
    \${'hip' > 'hit'}${'hip' > 'hit'}
    \${'4' > 3}${'4' > 3}
    +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp.html new file mode 100644 index 0000000..d20471e --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/basic-comparisons.jsp.html @@ -0,0 +1,117 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Expression Language - Basic Comparisons</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Expression Language - Basic Comparisons</h1>
    +    <hr>
    +    This example illustrates basic Expression Language comparisons.
    +    The following comparison operators are supported:
    +    <ul>
    +      <li>Less-than (&lt; or lt)</li>
    +      <li>Greater-than (&gt; or gt)</li>
    +      <li>Less-than-or-equal (&lt;= or le)</li>
    +      <li>Greater-than-or-equal (&gt;= or ge)</li>
    +      <li>Equal (== or eq)</li>
    +      <li>Not Equal (!= or ne)</li>
    +    </ul>
    +    <blockquote>
    +      <u><b>Numeric</b></u>
    +      <code>
    +        <table border="1">
    +          <thead>
    +        <td><b>EL Expression</b></td>
    +        <td><b>Result</b></td>
    +      </thead>
    +      <tr>
    +        <td>\${1 &lt; 2}</td>
    +        <td>${1 < 2}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1 lt 2}</td>
    +        <td>${1 lt 2}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1 &gt; (4/2)}</td>
    +        <td>${1 > (4/2)}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1 gt (4/2)}</td>
    +        <td>${1 gt (4/2)}</td>
    +      </tr>
    +      <tr>
    +        <td>\${4.0 &gt;= 3}</td>
    +        <td>${4.0 >= 3}</td>
    +      </tr>
    +      <tr>
    +        <td>\${4.0 ge 3}</td>
    +        <td>${4.0 ge 3}</td>
    +      </tr>
    +      <tr>
    +        <td>\${4 &lt;= 3}</td>
    +        <td>${4 <= 3}</td>
    +      </tr>
    +      <tr>
    +        <td>\${4 le 3}</td>
    +        <td>${4 le 3}</td>
    +      </tr>
    +      <tr>
    +        <td>\${100.0 == 100}</td>
    +        <td>${100.0 == 100}</td>
    +      </tr>
    +      <tr>
    +        <td>\${100.0 eq 100}</td>
    +        <td>${100.0 eq 100}</td>
    +      </tr>
    +      <tr>
    +        <td>\${(10*10) != 100}</td>
    +        <td>${(10*10) != 100}</td>
    +      </tr>
    +      <tr>
    +        <td>\${(10*10) ne 100}</td>
    +        <td>${(10*10) ne 100}</td>
    +      </tr>
    +    </table>
    +      </code>
    +      <br>
    +      <u><b>Alphabetic</b></u>
    +      <code>
    +        <table border="1">
    +          <thead>
    +            <td><b>EL Expression</b></td>
    +            <td><b>Result</b></td>
    +          </thead>
    +          <tr>
    +            <td>\${'a' &lt; 'b'}</td>
    +            <td>${'a' < 'b'}</td>
    +          </tr>
    +          <tr>
    +            <td>\${'hip' &gt; 'hit'}</td>
    +            <td>${'hip' > 'hit'}</td>
    +          </tr>
    +          <tr>
    +            <td>\${'4' &gt; 3}</td>
    +            <td>${'4' > 3}</td>
    +          </tr>
    +        </table>
    +      </code>
    +    </blockquote>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.html new file mode 100644 index 0000000..5900008 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.html @@ -0,0 +1,31 @@ + + + +View Source Code + + + + +

    + +

    Source Code for composite.jsp

    +

    Source Code for ValuesTag.java

    +

    Source Code for ValuesBean.java

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp new file mode 100644 index 0000000..ae671d4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp @@ -0,0 +1,110 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="my" uri="http://tomcat.apache.org/example-taglib" %> + + + + JSP 2.0 Expression Language - Composite Expressions + + +

    JSP 2.0 Expression Language - Composite Expressions

    +
    + This example illustrates EL composite expressions. Composite expressions + are formed by grouping together multiple EL expressions. Each of them is + evaluated from left to right, coerced to String, all those strings are + concatenated, and the result is coerced to the expected type. + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EL ExpressionTypeResult
    \${'hello'} wo\${'rld'}String${values.stringValue}
    \${'hello'} wo\${'rld'}String
    \${1+2}.\${220}Double${values.doubleValue}
    \${1+2}.\${220}Double
    000\${1}\${7}Long${values.longValue}
    000\${1}\${7}Long
    \${undefinedFoo}hello world\${undefinedBar}String${values.stringValue}
    \${undefinedFoo}hello world\${undefinedBar}String
    \${undefinedFoo}\${undefinedBar}Double${values.doubleValue}
    \${undefinedFoo}\${undefinedBar}Double
    \${undefinedFoo}\${undefinedBar}Long${values.longValue}
    \${undefinedFoo}\${undefinedBar}Long
    +
    +
    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp.html new file mode 100644 index 0000000..375555f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/composite.jsp.html @@ -0,0 +1,111 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="my" uri="http://tomcat.apache.org/example-taglib" %>
    +
    +<html>
    +  <head>
    +    <title>JSP 2.0 Expression Language - Composite Expressions</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Expression Language - Composite Expressions</h1>
    +    <hr>
    +    This example illustrates EL composite expressions. Composite expressions
    +    are formed by grouping together multiple EL expressions. Each of them is
    +    evaluated from left to right, coerced to String, all those strings are
    +    concatenated, and the result is coerced to the expected type.
    +
    +    <jsp:useBean id="values" class="jsp2.examples.ValuesBean" />
    +
    +    <blockquote>
    +      <code>
    +        <table border="1">
    +          <thead>
    +        <td><b>EL Expression</b></td>
    +        <td><b>Type</b></td>
    +        <td><b>Result</b></td>
    +      </thead>
    +      <tr>
    +        <td>\${'hello'} wo\${'rld'}</td>
    +        <td>String</td>
    +        <td><jsp:setProperty name="values" property="stringValue" value="${'hello'} wo${'rld'}"/>${values.stringValue}</td>
    +      </tr>
    +      <tr>
    +        <td>\${'hello'} wo\${'rld'}</td>
    +        <td>String</td>
    +        <td><my:values string="${'hello'} wo${'rld'}"/></td>
    +      </tr>
    +      <tr>
    +        <td>\${1+2}.\${220}</td>
    +        <td>Double</td>
    +        <td><jsp:setProperty name="values" property="doubleValue" value="${1+2}.${220}"/>${values.doubleValue}</td>
    +      </tr>
    +      <tr>
    +        <td>\${1+2}.\${220}</td>
    +        <td>Double</td>
    +        <td><my:values double="${1+2}.${220}"/></td>
    +      </tr>
    +      <tr>
    +        <td>000\${1}\${7}</td>
    +        <td>Long</td>
    +        <td><jsp:setProperty name="values" property="longValue" value="000${1}${7}"/>${values.longValue}</td>
    +      </tr>
    +      <tr>
    +        <td>000\${1}\${7}</td>
    +        <td>Long</td>
    +        <td><my:values long="000${1}${7}"/></td>
    +      </tr>
    +      <!--
    +         Undefined values are to be coerced to String, to be "",
    +         https://bz.apache.org/bugzilla/show_bug.cgi?id=47413
    +       -->
    +      <tr>
    +        <td>\${undefinedFoo}hello world\${undefinedBar}</td>
    +        <td>String</td>
    +        <td><jsp:setProperty name="values" property="stringValue" value="${undefinedFoo}hello world${undefinedBar}"/>${values.stringValue}</td>
    +      </tr>
    +      <tr>
    +        <td>\${undefinedFoo}hello world\${undefinedBar}</td>
    +        <td>String</td>
    +        <td><my:values string="${undefinedFoo}hello world${undefinedBar}"/></td>
    +      </tr>
    +      <tr>
    +        <td>\${undefinedFoo}\${undefinedBar}</td>
    +        <td>Double</td>
    +        <td><jsp:setProperty name="values" property="doubleValue" value="${undefinedFoo}${undefinedBar}"/>${values.doubleValue}</td>
    +      </tr>
    +      <tr>
    +        <td>\${undefinedFoo}\${undefinedBar}</td>
    +        <td>Double</td>
    +        <td><my:values double="${undefinedFoo}${undefinedBar}"/></td>
    +      </tr>
    +      <tr>
    +        <td>\${undefinedFoo}\${undefinedBar}</td>
    +        <td>Long</td>
    +        <td><jsp:setProperty name="values" property="longValue" value="${undefinedFoo}${undefinedBar}"/>${values.longValue}</td>
    +      </tr>
    +      <tr>
    +        <td>\${undefinedFoo}\${undefinedBar}</td>
    +        <td>Long</td>
    +        <td><my:values long="${undefinedFoo}${undefinedBar}"/></td>
    +      </tr>
    +    </table>
    +      </code>
    +    </blockquote>
    +  </body>
    +</html>
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.html new file mode 100644 index 0000000..726dda3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.html @@ -0,0 +1,32 @@ + + + +View Source Code + + + + +

    + +

    Source Code for functions.jsp +

    +

    Source Code for Functions.java +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp new file mode 100644 index 0000000..12b3fa9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp @@ -0,0 +1,67 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page contentType="text/html; charset=UTF-8" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%> + + + + JSP 2.0 Expression Language - Functions + + +

    JSP 2.0 Expression Language - Functions

    +
    + An upgrade from the JSTL expression language, the JSP 2.0 EL also + allows for simple function invocation. Functions are defined + by tag libraries and are implemented by a Java programmer as + static methods. + +
    + Change Parameter +
    + foo = + +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    EL ExpressionResult
    \${param["foo"]}${fn:escapeXml(param["foo"])} 
    \${my:reverse(param["foo"])}${my:reverse(fn:escapeXml(param["foo"]))} 
    \${my:reverse(my:reverse(param["foo"]))}${my:reverse(my:reverse(fn:escapeXml(param["foo"])))} 
    \${my:countVowels(param["foo"])}${my:countVowels(fn:escapeXml(param["foo"]))} 
    +
    +
    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp.html new file mode 100644 index 0000000..1a3cdb4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/functions.jsp.html @@ -0,0 +1,68 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%>
    +
    +<html>
    +  <head>
    +    <title>JSP 2.0 Expression Language - Functions</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Expression Language - Functions</h1>
    +    <hr>
    +    An upgrade from the JSTL expression language, the JSP 2.0 EL also
    +    allows for simple function invocation.  Functions are defined
    +    by tag libraries and are implemented by a Java programmer as
    +    static methods.
    +
    +    <blockquote>
    +      <u><b>Change Parameter</b></u>
    +      <form action="functions.jsp" method="GET">
    +          foo = <input type="text" name="foo" value="${fn:escapeXml(param["foo"])}">
    +          <input type="submit">
    +      </form>
    +      <br>
    +      <code>
    +        <table border="1">
    +          <thead>
    +            <td><b>EL Expression</b></td>
    +            <td><b>Result</b></td>
    +          </thead>
    +          <tr>
    +            <td>\${param["foo"]}</td>
    +            <td>${fn:escapeXml(param["foo"])}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${my:reverse(param["foo"])}</td>
    +            <td>${my:reverse(fn:escapeXml(param["foo"]))}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${my:reverse(my:reverse(param["foo"]))}</td>
    +            <td>${my:reverse(my:reverse(fn:escapeXml(param["foo"])))}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${my:countVowels(param["foo"])}</td>
    +            <td>${my:countVowels(fn:escapeXml(param["foo"]))}&nbsp;</td>
    +          </tr>
    +        </table>
    +      </code>
    +    </blockquote>
    +  </body>
    +</html>
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.html new file mode 100644 index 0000000..15268db --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.html @@ -0,0 +1,31 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for Implicit Objects Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp new file mode 100644 index 0000000..b557714 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp @@ -0,0 +1,90 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page contentType="text/html; charset=UTF-8" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + + + JSP 2.0 Expression Language - Implicit Objects + + +

    JSP 2.0 Expression Language - Implicit Objects

    +
    + This example illustrates some of the implicit objects available + in the Expression Language. The following implicit objects are + available (not all illustrated here): +
      +
    • pageContext - the PageContext object
    • +
    • pageScope - a Map that maps page-scoped attribute names to + their values
    • +
    • requestScope - a Map that maps request-scoped attribute names + to their values
    • +
    • sessionScope - a Map that maps session-scoped attribute names + to their values
    • +
    • applicationScope - a Map that maps application-scoped attribute + names to their values
    • +
    • param - a Map that maps parameter names to a single String + parameter value
    • +
    • paramValues - a Map that maps parameter names to a String[] of + all values for that parameter
    • +
    • header - a Map that maps header names to a single String + header value
    • +
    • headerValues - a Map that maps header names to a String[] of + all values for that header
    • +
    • initParam - a Map that maps context initialization parameter + names to their String parameter value
    • +
    • cookie - a Map that maps cookie names to a single Cookie object.
    • +
    + +
    + Change Parameter +
    + foo = + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EL ExpressionResult
    \${param.foo}${fn:escapeXml(param["foo"])} 
    \${param["foo"]}${fn:escapeXml(param["foo"])} 
    \${header["host"]}${fn:escapeXml(header["host"])} 
    \${header["accept"]}${fn:escapeXml(header["accept"])} 
    \${header["user-agent"]}${fn:escapeXml(header["user-agent"])} 
    +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp.html new file mode 100644 index 0000000..db967e7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/el/implicit-objects.jsp.html @@ -0,0 +1,91 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    +
    +<html>
    +  <head>
    +    <title>JSP 2.0 Expression Language - Implicit Objects</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Expression Language - Implicit Objects</h1>
    +    <hr>
    +    This example illustrates some of the implicit objects available
    +    in the Expression Language.  The following implicit objects are
    +    available (not all illustrated here):
    +    <ul>
    +      <li>pageContext - the PageContext object</li>
    +      <li>pageScope - a Map that maps page-scoped attribute names to
    +          their values</li>
    +      <li>requestScope - a Map that maps request-scoped attribute names
    +          to their values</li>
    +      <li>sessionScope - a Map that maps session-scoped attribute names
    +          to their values</li>
    +      <li>applicationScope - a Map that maps application-scoped attribute
    +          names to their values</li>
    +      <li>param - a Map that maps parameter names to a single String
    +          parameter value</li>
    +      <li>paramValues - a Map that maps parameter names to a String[] of
    +          all values for that parameter</li>
    +      <li>header - a Map that maps header names to a single String
    +          header value</li>
    +      <li>headerValues - a Map that maps header names to a String[] of
    +          all values for that header</li>
    +      <li>initParam - a Map that maps context initialization parameter
    +          names to their String parameter value</li>
    +      <li>cookie - a Map that maps cookie names to a single Cookie object.</li>
    +    </ul>
    +
    +    <blockquote>
    +      <u><b>Change Parameter</b></u>
    +      <form action="implicit-objects.jsp" method="GET">
    +          foo = <input type="text" name="foo" value="${fn:escapeXml(param["foo"])}">
    +          <input type="submit">
    +      </form>
    +      <br>
    +      <code>
    +        <table border="1">
    +          <thead>
    +            <td><b>EL Expression</b></td>
    +            <td><b>Result</b></td>
    +          </thead>
    +          <tr>
    +            <td>\${param.foo}</td>
    +            <td>${fn:escapeXml(param["foo"])}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${param["foo"]}</td>
    +            <td>${fn:escapeXml(param["foo"])}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${header["host"]}</td>
    +            <td>${fn:escapeXml(header["host"])}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${header["accept"]}</td>
    +            <td>${fn:escapeXml(header["accept"])}&nbsp;</td>
    +          </tr>
    +          <tr>
    +            <td>\${header["user-agent"]}</td>
    +            <td>${fn:escapeXml(header["user-agent"])}&nbsp;</td>
    +          </tr>
    +        </table>
    +      </code>
    +    </blockquote>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/FooBean.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/FooBean.java.html new file mode 100644 index 0000000..a5ddf41 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/FooBean.java.html @@ -0,0 +1,37 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples;
    +
    +public class FooBean {
    +    private String bar;
    +
    +    public FooBean() {
    +        bar = "Initial value";
    +    }
    +
    +    public String getBar() {
    +        return this.bar;
    +    }
    +
    +    public void setBar(String bar) {
    +        this.bar = bar;
    +    }
    +
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/HelloWorldSimpleTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/HelloWorldSimpleTag.java.html new file mode 100644 index 0000000..8c0bd4d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/HelloWorldSimpleTag.java.html @@ -0,0 +1,35 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import java.io.IOException;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +/**
    + * SimpleTag handler that prints "Hello, world!"
    + */
    +public class HelloWorldSimpleTag extends SimpleTagSupport {
    +    @Override
    +    public void doTag() throws JspException, IOException {
    +        getJspContext().getOut().write( "Hello, world!" );
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/ShuffleSimpleTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/ShuffleSimpleTag.java.html new file mode 100644 index 0000000..8d36084 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/ShuffleSimpleTag.java.html @@ -0,0 +1,88 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import java.io.IOException;
    +import java.util.Random;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.tagext.JspFragment;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +/**
    + * SimpleTag handler that accepts takes three attributes of type
    + * JspFragment and invokes then in a random order.
    + */
    +public class ShuffleSimpleTag extends SimpleTagSupport {
    +    // No need for this to use SecureRandom
    +    private static final Random random = new Random();
    +
    +    private JspFragment fragment1;
    +    private JspFragment fragment2;
    +    private JspFragment fragment3;
    +
    +    @Override
    +    public void doTag() throws JspException, IOException {
    +        switch(random.nextInt(6)) {
    +            case 0:
    +                fragment1.invoke( null );
    +                fragment2.invoke( null );
    +                fragment3.invoke( null );
    +                break;
    +            case 1:
    +                fragment1.invoke( null );
    +                fragment3.invoke( null );
    +                fragment2.invoke( null );
    +                break;
    +            case 2:
    +                fragment2.invoke( null );
    +                fragment1.invoke( null );
    +                fragment3.invoke( null );
    +                break;
    +            case 3:
    +                fragment2.invoke( null );
    +                fragment3.invoke( null );
    +                fragment1.invoke( null );
    +                break;
    +            case 4:
    +                fragment3.invoke( null );
    +                fragment1.invoke( null );
    +                fragment2.invoke( null );
    +                break;
    +            case 5:
    +                fragment3.invoke( null );
    +                fragment2.invoke( null );
    +                fragment1.invoke( null );
    +                break;
    +        }
    +    }
    +
    +    public void setFragment1( JspFragment fragment1 ) {
    +        this.fragment1 = fragment1;
    +    }
    +
    +    public void setFragment2( JspFragment fragment2 ) {
    +        this.fragment2 = fragment2;
    +    }
    +
    +    public void setFragment3( JspFragment fragment3 ) {
    +        this.fragment3 = fragment3;
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/TileSimpleTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/TileSimpleTag.java.html new file mode 100644 index 0000000..75d6daf --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/TileSimpleTag.java.html @@ -0,0 +1,49 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import java.io.IOException;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +/**
    + * Displays a tile as a single cell in a table.
    + */
    +public class TileSimpleTag extends SimpleTagSupport {
    +    private String color;
    +    private String label;
    +
    +    @Override
    +    public void doTag() throws JspException, IOException {
    +        getJspContext().getOut().write(
    +                "<td width=\"32\" height=\"32\" bgcolor=\"" + this.color +
    +                "\"><font color=\"#ffffff\"><center>" + this.label +
    +                "</center></font></td>" );
    +    }
    +
    +    public void setColor( String color ) {
    +        this.color = color;
    +    }
    +
    +    public void setLabel( String label ) {
    +        this.label = label;
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.html new file mode 100644 index 0000000..df1b6e6 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.html @@ -0,0 +1,37 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for jspattribute.jsp +

    + +

    Source Code for HelloWorldSimpleTag.java +

    + +

    Source Code for FooBean.java +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp new file mode 100644 index 0000000..8050b34 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp @@ -0,0 +1,46 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%> + + + + JSP 2.0 Examples - jsp:attribute and jsp:body + + +

    JSP 2.0 Examples - jsp:attribute and jsp:body

    +
    +

    The new <jsp:attribute> and <jsp:body> + standard actions can be used to specify the value of any standard + action or custom action attribute.

    +

    This example uses the <jsp:attribute> + standard action to use the output of a custom action invocation + (one that simply outputs "Hello, World!") to set the value of a + bean property. This would normally require an intermediary + step, such as using JSTL's <c:set> action.

    +
    + + Bean created! Setting foo.bar...
    + + + + + +
    +
    + Result: ${foo.bar} + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp.html new file mode 100644 index 0000000..9596997 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/jspattribute.jsp.html @@ -0,0 +1,47 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%>
    +
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - jsp:attribute and jsp:body</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - jsp:attribute and jsp:body</h1>
    +    <hr>
    +    <p>The new &lt;jsp:attribute&gt; and &lt;jsp:body&gt;
    +    standard actions can be used to specify the value of any standard
    +    action or custom action attribute.</p>
    +    <p>This example uses the &lt;jsp:attribute&gt;
    +    standard action to use the output of a custom action invocation
    +    (one that simply outputs "Hello, World!") to set the value of a
    +    bean property.  This would normally require an intermediary
    +    step, such as using JSTL's &lt;c:set&gt; action.</p>
    +    <br>
    +    <jsp:useBean id="foo" class="jsp2.examples.FooBean">
    +      Bean created!  Setting foo.bar...<br>
    +      <jsp:setProperty name="foo" property="bar">
    +        <jsp:attribute name="value">
    +          <my:helloWorld/>
    +        </jsp:attribute>
    +      </jsp:setProperty>
    +    </jsp:useBean>
    +    <br>
    +    Result: ${foo.bar}
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.html new file mode 100644 index 0000000..5711860 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.html @@ -0,0 +1,37 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for shuffle.jsp +

    + +

    Source Code for ShuffleSimpleTag.java +

    + +

    Source Code for TileSimpleTag.java +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp new file mode 100644 index 0000000..737ff65 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp @@ -0,0 +1,90 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%> + + + + JSP 2.0 Examples - Shuffle Example + + +

    JSP 2.0 Examples - Shuffle Example

    +
    +

    Try reloading the page a few times. Both the rows and the columns + are shuffled and appear different each time.

    +

    Here's how the code works. The SimpleTag handler called + <my:shuffle> accepts three attributes. Each attribute is a + JSP Fragment, meaning it is a fragment of JSP code that can be + dynamically executed by the shuffle tag handler on demand. The + shuffle tag handler executes the three fragments in a random order. + To shuffle both the rows and the columns, the shuffle tag is used + with itself as a parameter.

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp.html new file mode 100644 index 0000000..dcb137d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspattribute/shuffle.jsp.html @@ -0,0 +1,91 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%>
    +
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Shuffle Example</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Shuffle Example</h1>
    +    <hr>
    +    <p>Try reloading the page a few times.  Both the rows and the columns
    +    are shuffled and appear different each time.</p>
    +    <p>Here's how the code works.  The SimpleTag handler called
    +    &lt;my:shuffle&gt; accepts three attributes.  Each attribute is a
    +    JSP Fragment, meaning it is a fragment of JSP code that can be
    +    dynamically executed by the shuffle tag handler on demand.  The
    +    shuffle tag handler executes the three fragments in a random order.
    +    To shuffle both the rows and the columns, the shuffle tag is used
    +    with itself as a parameter.</p>
    +    <hr>
    +    <blockquote>
    +     <font color="#ffffff">
    +      <table>
    +        <my:shuffle>
    +          <jsp:attribute name="fragment1">
    +            <tr>
    +              <my:shuffle>
    +                <jsp:attribute name="fragment1">
    +                  <my:tile color="#ff0000" label="A"/>
    +                </jsp:attribute>
    +                <jsp:attribute name="fragment2">
    +                  <my:tile color="#00ff00" label="B"/>
    +                </jsp:attribute>
    +                <jsp:attribute name="fragment3">
    +                  <my:tile color="#0000ff" label="C"/>
    +                </jsp:attribute>
    +              </my:shuffle>
    +            </tr>
    +          </jsp:attribute>
    +          <jsp:attribute name="fragment2">
    +            <tr>
    +              <my:shuffle>
    +                <jsp:attribute name="fragment1">
    +                  <my:tile color="#ff0000" label="1"/>
    +                </jsp:attribute>
    +                <jsp:attribute name="fragment2">
    +                  <my:tile color="#00ff00" label="2"/>
    +                </jsp:attribute>
    +                <jsp:attribute name="fragment3">
    +                  <my:tile color="#0000ff" label="3"/>
    +                </jsp:attribute>
    +              </my:shuffle>
    +            </tr>
    +          </jsp:attribute>
    +          <jsp:attribute name="fragment3">
    +            <tr>
    +              <my:shuffle>
    +                <jsp:attribute name="fragment1">
    +                  <my:tile color="#ff0000" label="!"/>
    +                </jsp:attribute>
    +                <jsp:attribute name="fragment2">
    +                  <my:tile color="#00ff00" label="@"/>
    +                </jsp:attribute>
    +                <jsp:attribute name="fragment3">
    +                  <my:tile color="#0000ff" label="#"/>
    +                </jsp:attribute>
    +              </my:shuffle>
    +            </tr>
    +          </jsp:attribute>
    +        </my:shuffle>
    +      </table>
    +     </font>
    +    </blockquote>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.html new file mode 100644 index 0000000..f9df6a4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.html @@ -0,0 +1,31 @@ + + + + + +View Source Code + + + +

    ExecuteReturn

    + +

    Source Code for XHTML Basic Example

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx new file mode 100644 index 0000000..fc1e45f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx @@ -0,0 +1,48 @@ + + + + + + + JSPX - XHTML Basic Example + + +

    JSPX - XHTML Basic Example

    + This example illustrates how to use JSPX to produce an XHTML basic + document suitable for use with mobile phones, televisions, + PDAs, vending machines, pagers, car navigation systems, + mobile game machines, digital book readers, smart watches, etc. +

    + JSPX lets you create dynamic documents in a pure XML syntax compatible + with existing XML tools. The XML syntax in JSP 1.2 was awkward and + required &lt;jsp:root&gt; to be the root element of the document. + This is no longer the case in JSP 2.0. +

    + This particular example uses + namespace declarations to make the output of this page a valid XHTML + document. +

    + Just to prove this is live, here's some dynamic content: + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx.html new file mode 100644 index 0000000..6b38336 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/basic.jspx.html @@ -0,0 +1,49 @@ +Source Code

    <?xml version="1.0" encoding="UTF-8"?>
    +<!--
    +  Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<html xmlns:jsp="http://java.sun.com/JSP/Page"
    +      xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
    +      xmlns="http://www.w3.org/1999/xhtml">
    +  <jsp:output doctype-root-element="html"
    +              doctype-public="-//W3C//DTD XHTML Basic 1.0//EN"
    +              doctype-system="http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd"/>
    +  <jsp:directive.page contentType="application/xhtml+xml" />
    +  <head>
    +    <title>JSPX - XHTML Basic Example</title>
    +  </head>
    +  <body>
    +    <h1>JSPX - XHTML Basic Example</h1>
    +    This example illustrates how to use JSPX to produce an XHTML basic
    +    document suitable for use with mobile phones, televisions,
    +    PDAs, vending machines, pagers, car navigation systems,
    +    mobile game machines, digital book readers, smart watches, etc.
    +    <p/>
    +    JSPX lets you create dynamic documents in a pure XML syntax compatible
    +    with existing XML tools.  The XML syntax in JSP 1.2 was awkward and
    +    required &amp;lt;jsp:root&amp;gt; to be the root element of the document.
    +    This is no longer the case in JSP 2.0.
    +    <p/>
    +    This particular example uses
    +    namespace declarations to make the output of this page a valid XHTML
    +    document.
    +    <p/>
    +    Just to prove this is live, here's some dynamic content:
    +    <jsp:useBean id="now" class="java.util.Date" />
    +    <fmt:formatDate value="${now}" pattern="MMMM d, yyyy, H:mm:ss"/>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/svgexample.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/svgexample.html new file mode 100644 index 0000000..f7d591a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/svgexample.html @@ -0,0 +1,46 @@ + + + + + JSP 2.0 SVG Example + + +

    JSP 2.0 SVG Example

    + This example uses JSP 2.0's new, simplified JSPX syntax to render a + Scalable Vector Graphics (SVG) document. When you view the source, + notice the lack of a <jsp:root> element! The text to be rendered + can be modified by changing the value of the name parameter. +

    + SVG has many potential uses, such as searchable images, or images + customized with the name of your site's visitor (e.g. a "Susan's Store" + tab image). JSPX is a natural fit for generating dynamic XML content + such as SVG. +

    + To execute this example you will need a browser with basic SVG support. Any + remotely recent browser should have this. +

      +
    1. Use this URL: + textRotate.jspx?name=JSPX
    2. +
    3. Customize by changing the name=JSPX parameter
    4. +
    +

    + The following is a screenshot of the resulting image, for those using a + browser without SVG support:
    + [Screenshot image] + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.html new file mode 100644 index 0000000..5b3befe --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.html @@ -0,0 +1,32 @@ + + + + + +View Source Code + + + +

    Execute Return

    + +

    Source Code for SVG (Scalable Vector Graphics) +Example

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jpg b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9e987367bc83c25aedf1c7afd76f34de4a229f82 GIT binary patch literal 26729 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 V=J@~b5&mDv+y9Wy0{Ca)e*sFkE8PG9 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx new file mode 100644 index 0000000..c543887 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx @@ -0,0 +1,53 @@ + + + + + + JSP 2.0 JSPX + + + + + JSP 2.0 XML Syntax (.jspx) Demo + + Try changing the name parameter! + + + + <g opacity="0.95" transform="scale(1.05) rotate(15)"> + + ${name} + + + </g> + + ${name} + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx.html new file mode 100644 index 0000000..0e6c820 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/jspx/textRotate.jspx.html @@ -0,0 +1,54 @@ +Source Code
    <?xml version="1.0" encoding="UTF-8"?>
    +<!--
    +  Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<!--
    +  - This example is based off the textRotate.svg example that comes
    +  - with Apache Batik.  The original example was written by Bill Haneman.
    +  - This version by Mark Roth.
    +  -->
    +<svg xmlns="http://www.w3.org/2000/svg"
    +     width="450" height="500" viewBox="0 0 450 500"
    +     xmlns:c="http://java.sun.com/jsp/jstl/core"
    +     xmlns:fn="http://java.sun.com/jsp/jstl/functions"
    +     xmlns:jsp="http://java.sun.com/JSP/Page">
    +  <jsp:directive.page contentType="image/svg+xml" />
    +  <title>JSP 2.0 JSPX</title>
    +  <!-- select name parameter, or default to JSPX -->
    +  <c:set var="name" value='${empty fn:escapeXml(param["name"]) ? "JSPX" : fn:escapeXml(param["name"])}'/>
    +  <g id="testContent">
    +    <text class="title" x="50%" y="10%" font-size="15" text-anchor="middle" >
    +            JSP 2.0 XML Syntax (.jspx) Demo</text>
    +    <text class="title" x="50%" y="15%" font-size="15" text-anchor="middle" >
    +            Try changing the name parameter!</text>
    +    <g opacity="1.0" transform="translate(225, 250)" id="rotatedText">
    +      <c:forEach var="i" begin="1" end="24">
    +        <jsp:text>
    +          <![CDATA[<g opacity="0.95" transform="scale(1.05) rotate(15)">]]>
    +        </jsp:text>
    +        <text x="0" y="0" transform="scale(1.6, 1.6)" fill="DarkSlateBlue"
    +              text-anchor="middle" font-size="40" font-family="Serif"
    +              id="words">${name}</text>
    +      </c:forEach>
    +      <c:forEach var="i" begin="1" end="24">
    +        <jsp:text><![CDATA[</g>]]></jsp:text>
    +      </c:forEach>
    +      <text style="font-size:75;font-family:Serif;fill:white"
    +            text-anchor="middle">${name}</text>
    +    </g>
    +  </g>
    +</svg>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/EchoAttributesTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/EchoAttributesTag.java.html new file mode 100644 index 0000000..aa053c7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/EchoAttributesTag.java.html @@ -0,0 +1,58 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import java.io.IOException;
    +import java.util.ArrayList;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.JspWriter;
    +import javax.servlet.jsp.tagext.DynamicAttributes;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +/**
    + * SimpleTag handler that echoes all its attributes
    + */
    +public class EchoAttributesTag
    +    extends SimpleTagSupport
    +    implements DynamicAttributes
    +{
    +    private final ArrayList<String> keys = new ArrayList<>();
    +    private final ArrayList<Object> values = new ArrayList<>();
    +
    +    @Override
    +    public void doTag() throws JspException, IOException {
    +        JspWriter out = getJspContext().getOut();
    +        for( int i = 0; i < keys.size(); i++ ) {
    +            String key = keys.get( i );
    +            Object value = values.get( i );
    +            out.println( "<li>" + key + " = " + value + "</li>" );
    +        }
    +    }
    +
    +    @Override
    +    public void setDynamicAttribute( String uri, String localName,
    +        Object value )
    +        throws JspException
    +    {
    +        keys.add( localName );
    +        values.add( value );
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf new file mode 100644 index 0000000..d767de5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf @@ -0,0 +1,21 @@ + +
    +
    +This banner included with <include-coda> +
    +
    diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf.html new file mode 100644 index 0000000..3a82576 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/coda.jspf.html @@ -0,0 +1,22 @@ +Source Code
    <!--
    +  Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<hr>
    +<center>
    +This banner included with &lt;include-coda&gt;
    +</center>
    +<hr>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.html new file mode 100644 index 0000000..707d68f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.html @@ -0,0 +1,35 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for config.jsp +

    +

    Source Code for prelude.jspf +

    +

    Source Code for coda.jspf +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp new file mode 100644 index 0000000..0372889 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp @@ -0,0 +1,32 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%> +

    JSP 2.0 Examples - JSP Configuration

    +
    +

    Using a <jsp-property-group> element in the web.xml + deployment descriptor, this JSP page has been configured in the + following ways:

    +
      +
    • Uses <include-prelude> to include the top banner.
    • +
    • Uses <include-coda> to include the bottom banner.
    • +
    • Uses <scripting-invalid> true to disable + <% scripting %> elements
    • +
    • Uses <el-ignored> true to disable ${EL} elements
    • +
    • Uses <page-encoding> ISO-8859-1 to set the page encoding (though this is the default anyway)
    • +
    + There are various other configuration options that can be used. + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp.html new file mode 100644 index 0000000..6ce33ff --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/config.jsp.html @@ -0,0 +1,33 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%>
    +    <h1>JSP 2.0 Examples - JSP Configuration</h1>
    +    <hr>
    +    <p>Using a &lt;jsp-property-group&gt; element in the web.xml
    +    deployment descriptor, this JSP page has been configured in the
    +    following ways:</p>
    +    <ul>
    +      <li>Uses &lt;include-prelude&gt; to include the top banner.</li>
    +      <li>Uses &lt;include-coda&gt; to include the bottom banner.</li>
    +      <li>Uses &lt;scripting-invalid&gt; true to disable
    +          &lt;% scripting %&gt; elements</li>
    +      <li>Uses &lt;el-ignored&gt; true to disable ${EL} elements</li>
    +      <li>Uses &lt;page-encoding&gt; ISO-8859-1 to set the page encoding (though this is the default anyway)</li>
    +    </ul>
    +    There are various other configuration options that can be used.
    +
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.html new file mode 100644 index 0000000..4fa1bf1 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.html @@ -0,0 +1,33 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for dynamicattrs.jsp +

    +

    Source Code for EchoAttributesTag.java +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp new file mode 100644 index 0000000..251c49d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp @@ -0,0 +1,44 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%> + + + JSP 2.0 Examples - Dynamic Attributes + + +

    JSP 2.0 Examples - Dynamic Attributes

    +
    +

    This JSP page invokes a custom tag that accepts a dynamic set + of attributes. The tag echoes the name and value of all attributes + passed to it.

    +
    +

    Invocation 1 (six attributes)

    +
      + +
    +

    Invocation 2 (zero attributes)

    +
      + +
    +

    Invocation 3 (three attributes)

    +
      + +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp.html new file mode 100644 index 0000000..8f5ee18 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/dynamicattrs.jsp.html @@ -0,0 +1,45 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="my" uri="http://tomcat.apache.org/jsp2-example-taglib"%>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Dynamic Attributes</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Dynamic Attributes</h1>
    +    <hr>
    +    <p>This JSP page invokes a custom tag that accepts a dynamic set
    +    of attributes.  The tag echoes the name and value of all attributes
    +    passed to it.</p>
    +    <hr>
    +    <h2>Invocation 1 (six attributes)</h2>
    +    <ul>
    +      <my:echoAttributes x="1" y="2" z="3" r="red" g="green" b="blue"/>
    +    </ul>
    +    <h2>Invocation 2 (zero attributes)</h2>
    +    <ul>
    +      <my:echoAttributes/>
    +    </ul>
    +    <h2>Invocation 3 (three attributes)</h2>
    +    <ul>
    +      <my:echoAttributes dogName="Scruffy"
    +                         catName="Fluffy"
    +                         blowfishName="Puffy"/>
    +    </ul>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf new file mode 100644 index 0000000..05f7c84 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf @@ -0,0 +1,21 @@ + +
    +
    +This banner included with <include-prelude> +
    +
    diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf.html new file mode 100644 index 0000000..8b2bcd0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/misc/prelude.jspf.html @@ -0,0 +1,22 @@ +Source Code
    <!--
    +  Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<hr>
    +<center>
    +This banner included with &lt;include-prelude&gt;
    +</center>
    +<hr>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/BookBean.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/BookBean.java.html new file mode 100644 index 0000000..5c99dad --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/BookBean.java.html @@ -0,0 +1,45 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples;
    +
    +public class BookBean {
    +    private final String title;
    +    private final String author;
    +    private final String isbn;
    +
    +    public BookBean( String title, String author, String isbn ) {
    +        this.title = title;
    +        this.author = author;
    +        this.isbn = isbn;
    +    }
    +
    +    public String getTitle() {
    +        return this.title;
    +    }
    +
    +    public String getAuthor() {
    +        return this.author;
    +    }
    +
    +    public String getIsbn() {
    +        return this.isbn;
    +    }
    +
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/FindBookSimpleTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/FindBookSimpleTag.java.html new file mode 100644 index 0000000..4deafca --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/FindBookSimpleTag.java.html @@ -0,0 +1,47 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +import jsp2.examples.BookBean;
    +
    +/**
    + * SimpleTag handler that pretends to search for a book, and stores
    + * the result in a scoped variable.
    + */
    +public class FindBookSimpleTag extends SimpleTagSupport {
    +    private String var;
    +
    +    private static final String BOOK_TITLE = "The Lord of the Rings";
    +    private static final String BOOK_AUTHOR = "J. R. R. Tolkein";
    +    private static final String BOOK_ISBN = "0618002251";
    +
    +    @Override
    +    public void doTag() throws JspException {
    +        BookBean book = new BookBean( BOOK_TITLE, BOOK_AUTHOR, BOOK_ISBN );
    +        getJspContext().setAttribute( this.var, book );
    +    }
    +
    +    public void setVar( String var ) {
    +        this.var = var;
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/Functions.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/Functions.java.html new file mode 100644 index 0000000..aa84ccc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/Functions.java.html @@ -0,0 +1,46 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.el;
    +
    +import java.util.Locale;
    +
    +/**
    + * Defines the functions for the jsp2 example tag library.
    + *
    + * <p>Each function is defined as a static method.</p>
    + */
    +public class Functions {
    +    public static String reverse( String text ) {
    +        return new StringBuilder( text ).reverse().toString();
    +    }
    +
    +    public static int numVowels( String text ) {
    +        String vowels = "aeiouAEIOU";
    +        int result = 0;
    +        for( int i = 0; i < text.length(); i++ ) {
    +            if( vowels.indexOf( text.charAt( i ) ) != -1 ) {
    +                result++;
    +            }
    +        }
    +        return result;
    +    }
    +
    +    public static String caps( String text ) {
    +        return text.toUpperCase(Locale.ENGLISH);
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/HelloWorldSimpleTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/HelloWorldSimpleTag.java.html new file mode 100644 index 0000000..8c0bd4d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/HelloWorldSimpleTag.java.html @@ -0,0 +1,35 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import java.io.IOException;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +/**
    + * SimpleTag handler that prints "Hello, world!"
    + */
    +public class HelloWorldSimpleTag extends SimpleTagSupport {
    +    @Override
    +    public void doTag() throws JspException, IOException {
    +        getJspContext().getOut().write( "Hello, world!" );
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/RepeatSimpleTag.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/RepeatSimpleTag.java.html new file mode 100644 index 0000000..12913fc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/RepeatSimpleTag.java.html @@ -0,0 +1,45 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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 jsp2.examples.simpletag;
    +
    +import java.io.IOException;
    +
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.tagext.SimpleTagSupport;
    +
    +/**
    + * SimpleTag handler that accepts a num attribute and
    + * invokes its body 'num' times.
    + */
    +public class RepeatSimpleTag extends SimpleTagSupport {
    +    private int num;
    +
    +    @Override
    +    public void doTag() throws JspException, IOException {
    +        for (int i=0; i<num; i++) {
    +            getJspContext().setAttribute("count", String.valueOf( i + 1 ) );
    +            getJspBody().invoke(null);
    +        }
    +    }
    +
    +    public void setNum(int num) {
    +        this.num = num;
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.html new file mode 100644 index 0000000..2841acf --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.html @@ -0,0 +1,37 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for the Book Example JSP +

    +

    Source Code for the FindBook SimpleTag Handler +

    +

    Source Code for BookBean +

    +

    Source Code for the EL Functions +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp new file mode 100644 index 0000000..ba07cfb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp @@ -0,0 +1,55 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="my" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %> + + + JSP 2.0 Examples - Book SimpleTag Handler + + +

    JSP 2.0 Examples - Book SimpleTag Handler

    +
    +

    Illustrates a semi-realistic use of SimpleTag and the Expression + Language. First, a <my:findBook> tag is invoked to populate + the page context with a BookBean. Then, the books fields are printed + in all caps.

    +
    + Result:
    + + + + + + + + + + + + + + + + + + + + + + +
    FieldValueCapitalized
    Title${book.title}${my:caps(book.title)}
    Author${book.author}${my:caps(book.author)}
    ISBN${book.isbn}${my:caps(book.isbn)}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp.html new file mode 100644 index 0000000..51c27a0 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/book.jsp.html @@ -0,0 +1,56 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="my" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Book SimpleTag Handler</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Book SimpleTag Handler</h1>
    +    <hr>
    +    <p>Illustrates a semi-realistic use of SimpleTag and the Expression
    +    Language.  First, a &lt;my:findBook&gt; tag is invoked to populate
    +    the page context with a BookBean.  Then, the books fields are printed
    +    in all caps.</p>
    +    <br>
    +    <b><u>Result:</u></b><br>
    +    <my:findBook var="book"/>
    +    <table border="1">
    +        <thead>
    +        <td><b>Field</b></td>
    +        <td><b>Value</b></td>
    +        <td><b>Capitalized</b></td>
    +    </thead>
    +    <tr>
    +        <td>Title</td>
    +        <td>${book.title}</td>
    +        <td>${my:caps(book.title)}</td>
    +    </tr>
    +    <tr>
    +        <td>Author</td>
    +        <td>${book.author}</td>
    +        <td>${my:caps(book.author)}</td>
    +    </tr>
    +    <tr>
    +        <td>ISBN</td>
    +        <td>${book.isbn}</td>
    +        <td>${my:caps(book.isbn)}</td>
    +    </tr>
    +    </table>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.html new file mode 100644 index 0000000..20cadf8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.html @@ -0,0 +1,33 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for the Hello World Tag Example JSP +

    +

    Source Code for the Hello World SimpleTag Handler +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp new file mode 100644 index 0000000..d9f22a2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp @@ -0,0 +1,31 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %> + + + JSP 2.0 Examples - Hello World SimpleTag Handler + + +

    JSP 2.0 Examples - Hello World SimpleTag Handler

    +
    +

    This tag handler simply echos "Hello, World!" It's an example of + a very basic SimpleTag handler with no body.

    +
    + Result: + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp.html new file mode 100644 index 0000000..76f3973 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/hello.jsp.html @@ -0,0 +1,32 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Hello World SimpleTag Handler</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Hello World SimpleTag Handler</h1>
    +    <hr>
    +    <p>This tag handler simply echos "Hello, World!"  It's an example of
    +    a very basic SimpleTag handler with no body.</p>
    +    <br>
    +    <b><u>Result:</u></b>
    +    <mytag:helloWorld/>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.html new file mode 100644 index 0000000..a56bfcd --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.html @@ -0,0 +1,33 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for the Repeat Tag Example JSP +

    +

    Source Code for the Repeat SimpleTag Handler +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp new file mode 100644 index 0000000..b12d0a9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp @@ -0,0 +1,39 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %> + + + JSP 2.0 Examples - Repeat SimpleTag Handler + + +

    JSP 2.0 Examples - Repeat SimpleTag Handler

    +
    +

    This tag handler accepts a "num" parameter and repeats the body of the + tag "num" times. It's a simple example, but the implementation of + such a tag in JSP 2.0 is substantially simpler than the equivalent + JSP 1.2-style classic tag handler.

    +

    The body of the tag is encapsulated in a "JSP Fragment" and passed + to the tag handler, which then executes it five times, inside a + for loop. The tag handler passes in the current invocation in a + scoped variable called count, which can be accessed using the EL.

    +
    + Result:
    + + Invocation ${count} of 5
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp.html new file mode 100644 index 0000000..bd40cab --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/simpletag/repeat.jsp.html @@ -0,0 +1,40 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Repeat SimpleTag Handler</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Repeat SimpleTag Handler</h1>
    +    <hr>
    +    <p>This tag handler accepts a "num" parameter and repeats the body of the
    +    tag "num" times.  It's a simple example, but the implementation of
    +    such a tag in JSP 2.0 is substantially simpler than the equivalent
    +    JSP 1.2-style classic tag handler.</p>
    +    <p>The body of the tag is encapsulated in a "JSP Fragment" and passed
    +    to the tag handler, which then executes it five times, inside a
    +    for loop.  The tag handler passes in the current invocation in a
    +    scoped variable called count, which can be accessed using the EL.</p>
    +    <br>
    +    <b><u>Result:</u></b><br>
    +    <mytag:repeat num="5">
    +      Invocation ${count} of 5<br>
    +    </mytag:repeat>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/displayProducts.tag.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/displayProducts.tag.html new file mode 100644 index 0000000..dd488f2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/displayProducts.tag.html @@ -0,0 +1,56 @@ +Source Code
    <!--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    +<%@ attribute name="normalPrice" fragment="true" %>
    +<%@ attribute name="onSale" fragment="true" %>
    +<%@ variable name-given="name" %>
    +<%@ variable name-given="price" %>
    +<%@ variable name-given="origPrice" %>
    +<%@ variable name-given="salePrice" %>
    +
    +<table border="1">
    +  <tr>
    +    <td>
    +      <c:set var="name" value="Hand-held Color PDA"/>
    +      <c:set var="price" value="$298.86"/>
    +      <jsp:invoke fragment="normalPrice"/>
    +    </td>
    +    <td>
    +      <c:set var="name" value="4-Pack 150 Watt Light Bulbs"/>
    +      <c:set var="origPrice" value="$2.98"/>
    +      <c:set var="salePrice" value="$2.32"/>
    +      <jsp:invoke fragment="onSale"/>
    +    </td>
    +    <td>
    +      <c:set var="name" value="Digital Cellular Phone"/>
    +      <c:set var="price" value="$68.74"/>
    +      <jsp:invoke fragment="normalPrice"/>
    +    </td>
    +    <td>
    +      <c:set var="name" value="Baby Grand Piano"/>
    +      <c:set var="price" value="$10,800.00"/>
    +      <jsp:invoke fragment="normalPrice"/>
    +    </td>
    +    <td>
    +      <c:set var="name" value="Luxury Car w/ Leather Seats"/>
    +      <c:set var="origPrice" value="$23,980.00"/>
    +      <c:set var="salePrice" value="$21,070.00"/>
    +      <jsp:invoke fragment="onSale"/>
    +    </td>
    +  </tr>
    +</table>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.html new file mode 100644 index 0000000..f29a379 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.html @@ -0,0 +1,33 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for hello.jsp +

    +

    Source Code for helloWorld.tag +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp new file mode 100644 index 0000000..9b260f5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp @@ -0,0 +1,35 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> + + + JSP 2.0 Examples - Hello World Using a Tag File + + +

    JSP 2.0 Examples - Hello World Using a Tag File

    +
    +

    This JSP page invokes a custom tag that simply echos "Hello, World!" + The custom tag is generated from a tag file in the /WEB-INF/tags + directory.

    +

    Notice that we did not need to write a TLD for this tag. We just + created /WEB-INF/tags/helloWorld.tag, imported it using the taglib + directive, and used it!

    +
    + Result: + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp.html new file mode 100644 index 0000000..b431f30 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/hello.jsp.html @@ -0,0 +1,36 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Hello World Using a Tag File</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Hello World Using a Tag File</h1>
    +    <hr>
    +    <p>This JSP page invokes a custom tag that simply echos "Hello, World!"
    +    The custom tag is generated from a tag file in the /WEB-INF/tags
    +    directory.</p>
    +    <p>Notice that we did not need to write a TLD for this tag.  We just
    +    created /WEB-INF/tags/helloWorld.tag, imported it using the taglib
    +    directive, and used it!</p>
    +    <br>
    +    <b><u>Result:</u></b>
    +    <tags:helloWorld/>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/helloWorld.tag.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/helloWorld.tag.html new file mode 100644 index 0000000..f29726f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/helloWorld.tag.html @@ -0,0 +1,18 @@ +Source Code
    <!--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +Hello, world!
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.html new file mode 100644 index 0000000..1f03b9c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.html @@ -0,0 +1,33 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for panel.jsp +

    +

    Source Code for panel.tag +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp new file mode 100644 index 0000000..d963877 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp @@ -0,0 +1,58 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> + + + JSP 2.0 Examples - Panels using Tag Files + + +

    JSP 2.0 Examples - Panels using Tag Files

    +
    +

    This JSP page invokes a custom tag that draws a + panel around the contents of the tag body. Normally, such a tag + implementation would require a Java class with many println() statements, + outputting HTML. Instead, we can use a .tag file as a template, + and we don't need to write a single line of Java or even a TLD!

    +
    + + + + + + +
    + + First panel.
    +
    +
    + + Second panel.
    + Second panel.
    + Second panel.
    + Second panel.
    +
    +
    + + Third panel.
    + + A panel in a panel. + + Third panel.
    +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp.html new file mode 100644 index 0000000..584393d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.jsp.html @@ -0,0 +1,59 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Panels using Tag Files</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Panels using Tag Files</h1>
    +    <hr>
    +    <p>This JSP page invokes a custom tag that draws a
    +    panel around the contents of the tag body.  Normally, such a tag
    +    implementation would require a Java class with many println() statements,
    +    outputting HTML.  Instead, we can use a .tag file as a template,
    +    and we don't need to write a single line of Java or even a TLD!</p>
    +    <hr>
    +    <table border="0">
    +      <tr valign="top">
    +        <td>
    +          <tags:panel color="#ff8080" bgcolor="#ffc0c0" title="Panel 1">
    +            First panel.<br/>
    +          </tags:panel>
    +        </td>
    +        <td>
    +          <tags:panel color="#80ff80" bgcolor="#c0ffc0" title="Panel 2">
    +            Second panel.<br/>
    +            Second panel.<br/>
    +            Second panel.<br/>
    +            Second panel.<br/>
    +          </tags:panel>
    +        </td>
    +        <td>
    +          <tags:panel color="#8080ff" bgcolor="#c0c0ff" title="Panel 3">
    +            Third panel.<br/>
    +            <tags:panel color="#ff80ff" bgcolor="#ffc0ff" title="Inner">
    +              A panel in a panel.
    +            </tags:panel>
    +            Third panel.<br/>
    +          </tags:panel>
    +        </td>
    +      </tr>
    +    </table>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.tag.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.tag.html new file mode 100644 index 0000000..aec91c3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/panel.tag.html @@ -0,0 +1,30 @@ +Source Code
    <!--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<%@ 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>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.html new file mode 100644 index 0000000..72ae49f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.html @@ -0,0 +1,33 @@ + + + +View Source Code + + + + +

    +

    + +

    Source Code for products.jsp +

    +

    Source Code for displayProducts.tag +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp new file mode 100644 index 0000000..7f32ffb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp @@ -0,0 +1,54 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> + + + JSP 2.0 Examples - Display Products Tag File + + +

    JSP 2.0 Examples - Display Products Tag File

    +
    +

    This JSP page invokes a tag file that displays a listing of + products. The custom tag accepts two fragments that enable + customization of appearance. One for when the product is on sale + and one for normal price.

    +

    The tag is invoked twice, using different styles

    +
    +

    Products

    + + + Item: ${name}
    + Price: ${price} +
    + + Item: ${name}
    + Was: ${origPrice}
    + Now: ${salePrice} +
    +
    +
    +

    Products (Same tag, alternate style)

    + + + ${name} @ ${price} ea. + + + ${name} @ ${salePrice} ea. (was: ${origPrice}) + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp.html new file mode 100644 index 0000000..6d6fc10 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsp2/tagfiles/products.jsp.html @@ -0,0 +1,55 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
    +<html>
    +  <head>
    +    <title>JSP 2.0 Examples - Display Products Tag File</title>
    +  </head>
    +  <body>
    +    <h1>JSP 2.0 Examples - Display Products Tag File</h1>
    +    <hr>
    +    <p>This JSP page invokes a tag file that displays a listing of
    +    products.  The custom tag accepts two fragments that enable
    +    customization of appearance.  One for when the product is on sale
    +    and one for normal price.</p>
    +    <p>The tag is invoked twice, using different styles</p>
    +    <hr>
    +    <h2>Products</h2>
    +    <tags:displayProducts>
    +      <jsp:attribute name="normalPrice">
    +        Item: ${name}<br/>
    +        Price: ${price}
    +      </jsp:attribute>
    +      <jsp:attribute name="onSale">
    +        Item: ${name}<br/>
    +        <font color="red"><strike>Was: ${origPrice}</strike></font><br/>
    +        <b>Now: ${salePrice}</b>
    +      </jsp:attribute>
    +    </tags:displayProducts>
    +    <hr>
    +    <h2>Products (Same tag, alternate style)</h2>
    +    <tags:displayProducts>
    +      <jsp:attribute name="normalPrice">
    +        <b>${name}</b> @ ${price} ea.
    +      </jsp:attribute>
    +      <jsp:attribute name="onSale">
    +        <b>${name}</b> @ ${salePrice} ea. (was: ${origPrice})
    +      </jsp:attribute>
    +    </tags:displayProducts>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/ServletToJsp.java.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/ServletToJsp.java.html new file mode 100644 index 0000000..0a38037 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/ServletToJsp.java.html @@ -0,0 +1,40 @@ +Source Code
    /*
    +* Licensed to the Apache Software Foundation (ASF) under one or more
    +* contributor license agreements.  See the NOTICE file distributed with
    +* this work for additional information regarding copyright ownership.
    +* The ASF licenses this file to You 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.
    +*/
    +
    +import javax.servlet.http.HttpServlet;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +
    +public class ServletToJsp extends HttpServlet {
    +
    +    private static final long serialVersionUID = 1L;
    +
    +    @Override
    +    public void doGet (HttpServletRequest request,
    +            HttpServletResponse response) {
    +
    +       try {
    +           // Set the attribute and Forward to hello.jsp
    +           request.setAttribute ("servletName", "servletToJsp");
    +           getServletConfig().getServletContext().getRequestDispatcher(
    +                   "/jsp/jsptoserv/hello.jsp").forward(request, response);
    +       } catch (Exception ex) {
    +           ex.printStackTrace ();
    +       }
    +    }
    +}
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp new file mode 100644 index 0000000..8b2a43f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp @@ -0,0 +1,26 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + +

    +I have been invoked by +<% out.print (request.getAttribute("servletName").toString()); %> +Servlet. +

    + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp.html new file mode 100644 index 0000000..6ed7176 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/hello.jsp.html @@ -0,0 +1,27 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<body bgcolor="white">
    +
    +<h1>
    +I have been invoked by
    +<% out.print (request.getAttribute("servletName").toString()); %>
    +Servlet.
    +</h1>
    +
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp new file mode 100644 index 0000000..db68a6f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp @@ -0,0 +1,23 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + + + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp.html new file mode 100644 index 0000000..a5dc22c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jsptoservlet.jsp.html @@ -0,0 +1,24 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<body bgcolor="white">
    +
    +<!-- Forward to a servlet -->
    +<jsp:forward page="/servletToJsp" />
    +
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jts.html b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jts.html new file mode 100644 index 0000000..a4e1679 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/jsptoserv/jts.html @@ -0,0 +1,36 @@ + + + + + +Untitled Document + + + + +

    Execute
    + Return

    + +

    Source Code for JSP calling servlet

    + +

    Source Code for Servlet calling JSP

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.html b/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.html new file mode 100644 index 0000000..1c5a484 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.html @@ -0,0 +1,34 @@ + + + +Untitled Document + + + + +

    + +

    Source Code for Numguess Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp new file mode 100644 index 0000000..d9c61b9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp @@ -0,0 +1,69 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + + Number Guess Game + Written by Jason Hunter, CTO, K&A Software + http://www.servlets.com +--%> + +<%@ page import = "num.NumberGuessBean" %> + + + + + +Number Guess + + + +<% if (numguess.getSuccess()) { %> + + Congratulations! You got it. + And after just <%= numguess.getNumGuesses() %> tries.

    + + <% numguess.reset(); %> + + Care to try again? + +<% } else if (numguess.getNumGuesses() == 0) { %> + + Welcome to the Number Guess game.

    + + I'm thinking of a number between 1 and 100.

    + +

    + What's your guess? + +
    + +<% } else { %> + + Good guess, but nope. Try <%= numguess.getHint() %>. + + You have made <%= numguess.getNumGuesses() %> guesses.

    + + I'm thinking of a number between 1 and 100.

    + +

    + What's your guess? + +
    + +<% } %> + +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp.html new file mode 100644 index 0000000..e764041 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/num/numguess.jsp.html @@ -0,0 +1,70 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +
    +  Number Guess Game
    +  Written by Jason Hunter, CTO, K&A Software
    +  http://www.servlets.com
    +--%>
    +
    +<%@ page import = "num.NumberGuessBean" %>
    +
    +<jsp:useBean id="numguess" class="num.NumberGuessBean" scope="session"/>
    +<jsp:setProperty name="numguess" property="*"/>
    +
    +<html>
    +<head><title>Number Guess</title></head>
    +<body bgcolor="white">
    +<font size=4>
    +
    +<% if (numguess.getSuccess()) { %>
    +
    +  Congratulations!  You got it.
    +  And after just <%= numguess.getNumGuesses() %> tries.<p>
    +
    +  <% numguess.reset(); %>
    +
    +  Care to <a href="numguess.jsp">try again</a>?
    +
    +<% } else if (numguess.getNumGuesses() == 0) { %>
    +
    +  Welcome to the Number Guess game.<p>
    +
    +  I'm thinking of a number between 1 and 100.<p>
    +
    +  <form method=get>
    +  What's your guess? <input type=text name=guess>
    +  <input type=submit value="Submit">
    +  </form>
    +
    +<% } else { %>
    +
    +  Good guess, but nope.  Try <b><%= numguess.getHint() %></b>.
    +
    +  You have made <%= numguess.getNumGuesses() %> guesses.<p>
    +
    +  I'm thinking of a number between 1 and 100.<p>
    +
    +  <form method=get>
    +  What's your guess? <input type=text name=guess>
    +  <input type=submit value="Submit">
    +  </form>
    +
    +<% } %>
    +
    +</font>
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/plugin/applet/Clock2.class b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/applet/Clock2.class new file mode 100644 index 0000000000000000000000000000000000000000..2fd4a4d5e6adb362ff685e688bbffeca9b6f0ff6 GIT binary patch literal 5869 zcmZ`-3w)bZ760EaU-ErTzP4G|x2;=SG8m)FU}GB;*1_oBD|T$I6IW5TuSwR1rAbXv zXi-EICn_Q$uOZ4nWQwR8tX)9?6-7Y7_xp+O_Zy$c{GaZCAs;$wAqB|a|0AsG(K@PG^t%5cQOn2qr;j$$GV8xINcVGExKquyuz zq@W)W^rIFYv+=1gV)(SIKU0UfcwC^*3iLUFp0MzF8&8G_J{88(_(GVJFUs;63(wm4 zl8rCR>MLP<6<-tR>t<&sV0In=&$&r>zG2~;Hg1-4zh&bV8{alNH$VTlx#myYcm9*l zKOV++@ZC`7#y8SRKvv%ib*|S7nCs32LY=Gqm7MZ@8Gax~{m{mbWbtDg&)N8ijh_nk zXEuIr;TK_Sz%RvwUkUVU8GaM=r647%-&**c?Ek$Cf3WdK3xBfkXB&U9@mCvvv+=xz zzgzf+g?}nUi|Inf%U+Z&6f^nUE4tPzs0$S8*X47?l9wx8ABDTK0Ku{2Voh_3QtlnWm_Siw|)k%0<^K;52vVbCj;M0B$+ zx|AL%E$zt+4rSBpy;6Fk-oQg_IV45QR3&;!g-ouW^!j8rpWM6AOOhp5QfTzWd6$=# z3W7T#$>BmFohyl0dcda-monLoU?T4P@vdyL+7|y_~{Lkwz#zWK1fAhqC$7P(G6@kz;OK7yl+r+f?v|1~SRwD$&6hIfKI}2Q|WPlwZHX z3DfN66(lo-r0CZq5~tZB0u>#hQv5bD0){-QpfIcLr8egj=KC}q9=;d+``a**Ob?Y9 zX|&Xk2rx!v7-3KtqcTYJ7!ox~K4KK<7P)ddHmuPK6fEUa-l&e`f3Y|)7a8Q#j!|2n zc4o1ZAL5-9hN+D)m}cfMFKF)YkRLns{pr%0AqH2eE4L@FFtcq@jn36*igMdFuiy=) zdA`4MR@?aOUXUaH>tFyGg$6CD8tx8q z$UAru#~fUWy^K6fucQk-+QSO5hY}PVWHIQl3cS|A5C>%lRKRO1Qma|QJL~IDN(MP9 zpiD~z9TifRNU2_V{eeCc)*7iYUjzzZ_Ms8XR1SH;AxCg%c-5 zOdDj5imDk?-LrXft$S3=Q75RGj&fy~rDi*7jtV@aaMiTsXZAFb zySj9r5$7>U#0xZlHQuQ$RSFBIVV(92-w|4OiOzoM!S;|>D5klbtn;jOOs@&(7jBM?sPiyC`T@Iben!4 zM*f;{oJj<5Zwtf-cHGyJ=ycX5<9|o}+MfJ--t3~oUzw?Jh!%DhH zyQsA?R%sWLW-3g%txBY6^Xtn`4!=~?1d>*^`hW@+v*|S3mf3cJC}S1Uy4hkrpK?1{ zbb8Uicj~KfG2vJ9(P!W_99eSo1CWhE&+Hm{W((0X`-z^}T=dLNqi41QJ+tiVnZ;et zYzTU0iPtj=Jm(0{WTWCZ%+*rPtb+(9jzS$KVBj*2A&rdVa>9@HL0*HFk- zLpf;*rAbp}sMGjw948+}fDQZgxC(K+5w~DJ=i6}z4{{D@cU-{VAixr|(qBt(23BGj zHe)&Oas_YgOmd%1{tikwhZ4@EjPohwJW5$ZIqNBDEspR_|0p)rxb(5IOJ7IXCm{3> zTxC(p&gwv4vqy5|MJbne65_`FO~H9ByPI8ecX=Ae0;0HXZrNR)YEUU3mGV)VG37H> zP$|kHN>3HWRC9|k%2b0A@kH$|%MuPMp(mmygJ&V?sOZaRQ#Tf33%zwAp{?}PHa;?5 z&aS*2x1mRSVzqBn*%LI6KJ3#0x1XNu)8VxrR}%_|@puyIy)-^$O z5KS88hEjq()yG~FI#w&<;IT)Bc)-3*ege7Rl1*O_G1c3;)1;k&Aa@2VQU3vVqOz6)Zm$&+5Koe|`Dz1kTep4x+J z@ithHK#IV85p$F>;%)=|!pDg39rHi*R+RbuY@pqahTH4-g=;cV=V+Usqa6)R4dtYq zz@m2hAncAtvNbit7LVh!Da5*isOxAHfux>(JT+XQhDlvgOYNwSZflQ3&u({IdtYqn zrLi+|v1NPSIf3Ofv0|?qd290e_Rw*pvoy&OlI7MN&(&V$GLIvXizLkzbi>is0k3lmR>?ej9Oow7i0ed`(=+D@s)?w@vDI!QdV0!r zLd=%)7sooeY};L3u5lwaiP2M-UZk#dBOzIyt~V#fv5qp_5QSL>;J6ln(4A;qEC&fv z*339LZH67ak}_PAa8Nb}37B`{RK3|u30g3+-Hn($r3TYXIB)=w7S6^Lo`7Jc@KiCR z_$IFRk6zqVUj{@yrkGV$O?*?qtSFq-Z$d>ZajZ>>df%WFJYmL3Wfx zGh0idg*_(GR4>g!v4KeKUcgFx780zrTbWh~Cf^``)+EYF`WMz?uoFgDduFloEnqoa z&a^v=mHlj{Vh7vW8m7)xmfG#CzdKlTcQP4wG0_H@bVE$D0@Lp@R+=kWYp!KdUdQnU zyb~Y6^>_mB!gE}`fOo4_+^9Nni`tA^)i&IwF2;V9#OGt3iqh5<6iX(98~|rhm0^jY|O=d#%cJ7u^RUq8}U(ND?VoI#K(;k4jEY-Hm<+} z#TlS!dG+*HO<#T4k1@LKR{ysFWW< zQec#7RflL3>#pil*V8hoyU(fL(>|%YFQ~8L-GqYF?_}IaD1;{r8}A`xAz*v~HxaU7 z8K1|^gz6A69%nb~glxek zAz&t}--cekdp3??6Qg?5I5tli3{lx&(NNHa$(s7fE}T)Mps#UqTDMqEDTrwP-D$YVzrMH@lP4u5N(&0!#}Z z*k<7#UZ=tbD=h=7$tUl-P=dv6>+x27gI0aBMt;RAc|Gc2qO5yykfS^_Pvq!G#a`6Y)4h070snq}giZKajU`=WB{uQc`x){ + if (d<0) { + d=d+2*x+3; + x++; + } + else { + d=d+2*(x-y)+5; + x++; + y--; + } + plotpoints(x0,y0,x,y,g); + } + } + + // Paint is the main part of the program + @Override + public void paint(Graphics g) { + int xh, yh, xm, ym, xs, ys, s = 0, m = 10, h = 10, xcenter, ycenter; + String today; + + currentDate = new Date(); + SimpleDateFormat formatter = new SimpleDateFormat("s",Locale.getDefault()); + try { + s = Integer.parseInt(formatter.format(currentDate)); + } catch (NumberFormatException n) { + s = 0; + } + formatter.applyPattern("m"); + try { + m = Integer.parseInt(formatter.format(currentDate)); + } catch (NumberFormatException n) { + m = 10; + } + formatter.applyPattern("h"); + try { + h = Integer.parseInt(formatter.format(currentDate)); + } catch (NumberFormatException n) { + h = 10; + } + formatter.applyPattern("EEE MMM dd HH:mm:ss yyyy"); + today = formatter.format(currentDate); + xcenter=80; + ycenter=55; + + // a= s* pi/2 - pi/2 (to switch 0,0 from 3:00 to 12:00) + // x = r(cos a) + xcenter, y = r(sin a) + ycenter + + xs = (int)(Math.cos(s * 3.14f/30 - 3.14f/2) * 45 + xcenter); + ys = (int)(Math.sin(s * 3.14f/30 - 3.14f/2) * 45 + ycenter); + xm = (int)(Math.cos(m * 3.14f/30 - 3.14f/2) * 40 + xcenter); + ym = (int)(Math.sin(m * 3.14f/30 - 3.14f/2) * 40 + ycenter); + xh = (int)(Math.cos((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 30 + xcenter); + yh = (int)(Math.sin((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 30 + ycenter); + + // Draw the circle and numbers + + g.setFont(clockFaceFont); + g.setColor(handColor); + circle(xcenter,ycenter,50,g); + g.setColor(numberColor); + g.drawString("9",xcenter-45,ycenter+3); + g.drawString("3",xcenter+40,ycenter+3); + g.drawString("12",xcenter-5,ycenter-37); + g.drawString("6",xcenter-3,ycenter+45); + + // Erase if necessary, and redraw + + g.setColor(getBackground()); + if (xs != lastxs || ys != lastys) { + g.drawLine(xcenter, ycenter, lastxs, lastys); + g.drawString(lastdate, 5, 125); + } + if (xm != lastxm || ym != lastym) { + g.drawLine(xcenter, ycenter-1, lastxm, lastym); + g.drawLine(xcenter-1, ycenter, lastxm, lastym); } + if (xh != lastxh || yh != lastyh) { + g.drawLine(xcenter, ycenter-1, lastxh, lastyh); + g.drawLine(xcenter-1, ycenter, lastxh, lastyh); } + g.setColor(numberColor); + g.drawString("", 5, 125); + g.drawString(today, 5, 125); + g.drawLine(xcenter, ycenter, xs, ys); + g.setColor(handColor); + g.drawLine(xcenter, ycenter-1, xm, ym); + g.drawLine(xcenter-1, ycenter, xm, ym); + g.drawLine(xcenter, ycenter-1, xh, yh); + g.drawLine(xcenter-1, ycenter, xh, yh); + lastxs=xs; lastys=ys; + lastxm=xm; lastym=ym; + lastxh=xh; lastyh=yh; + lastdate = today; + currentDate=null; + } + + @Override + public void start() { + timer = new Thread(this); + timer.start(); + } + + @Override + public void stop() { + timer = null; + } + + @Override + public void run() { + Thread me = Thread.currentThread(); + while (timer == me) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + repaint(); + } + } + + @Override + public void update(Graphics g) { + paint(g); + } + + @Override + public String getAppletInfo() { + return "Title: A Clock \nAuthor: Rachel Gollub, 1995 \nAn analog clock."; + } + + @Override + public String[][] getParameterInfo() { + String[][] info = { + {"bgcolor", "hexadecimal RGB number", "The background color. Default is the color of your browser."}, + {"fgcolor1", "hexadecimal RGB number", "The color of the hands and dial. Default is blue."}, + {"fgcolor2", "hexadecimal RGB number", "The color of the seconds hand and numbers. Default is dark gray."} + }; + return info; + } +} diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.html b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.html new file mode 100644 index 0000000..27bc51b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.html @@ -0,0 +1,30 @@ + + + +Untitled Document + + + + +

    + +

    Source Code for Plugin Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp new file mode 100644 index 0000000..a07dda3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp @@ -0,0 +1,34 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + Plugin example + +

    Current time is :

    + + + Plugin tag OBJECT or EMBED not supported by browser. + + +

    +

    + +The above applet is loaded using the Java Plugin from a jsp page using the +plugin tag. + +

    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp.html new file mode 100644 index 0000000..710bda7 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/plugin/plugin.jsp.html @@ -0,0 +1,35 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<title> Plugin example </title>
    +<body bgcolor="white">
    +<h3> Current time is : </h3>
    +<jsp:plugin type="applet" code="Clock2.class" codebase="applet" jreversion="1.2" width="160" height="150" >
    +    <jsp:fallback>
    +        Plugin tag OBJECT or EMBED not supported by browser.
    +    </jsp:fallback>
    +</jsp:plugin>
    +<p>
    +<h4>
    +<font color=red>
    +The above applet is loaded using the Java Plugin from a jsp page using the
    +plugin tag.
    +</font>
    +</h4>
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp new file mode 100644 index 0000000..3ef5743 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp @@ -0,0 +1,25 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + +Error Page For Examples + + +Invalid username and/or password, please try +again. + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp.html new file mode 100644 index 0000000..50ec895 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/error.jsp.html @@ -0,0 +1,26 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<head>
    +<title>Error Page For Examples</title>
    +</head>
    +<body bgcolor="white">
    +Invalid username and/or password, please try
    +<a href='<%= response.encodeURL("index.jsp") %>'>again</a>.
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp new file mode 100644 index 0000000..eacf27a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp @@ -0,0 +1,82 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<% + if (request.getParameter("logoff") != null) { + session.invalidate(); + response.sendRedirect("index.jsp"); + return; + } +%> + + +Protected Page for Examples + + + +You are logged in as remote user +<%= util.HTMLFilter.filter(request.getRemoteUser()) %> +in session <%= session.getId() %>

    + +<% + if (request.getUserPrincipal() != null) { +%> + Your user principal name is + <%= util.HTMLFilter.filter(request.getUserPrincipal().getName()) %> +

    +<% + } else { +%> + No user principal could be identified.

    +<% + } +%> + +<% + String role = request.getParameter("role"); + if (role == null) + role = ""; + if (role.length() > 0) { + if (request.isUserInRole(role)) { +%> + You have been granted role + <%= util.HTMLFilter.filter(role) %>

    +<% + } else { +%> + You have not been granted role + <%= util.HTMLFilter.filter(role) %>

    +<% + } + } +%> + +To check whether your user name has been granted a particular role, +enter it here: +
    + + +
    +

    + +If you have configured this application for form-based authentication, you can +log off by clicking +here. +This should cause you to be returned to the login page after the redirect +that is performed. + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp.html new file mode 100644 index 0000000..cadf810 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/index.jsp.html @@ -0,0 +1,83 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%
    +  if (request.getParameter("logoff") != null) {
    +    session.invalidate();
    +    response.sendRedirect("index.jsp");
    +    return;
    +  }
    +%>
    +<html>
    +<head>
    +<title>Protected Page for Examples</title>
    +</head>
    +<body bgcolor="white">
    +
    +You are logged in as remote user
    +<b><%= util.HTMLFilter.filter(request.getRemoteUser()) %></b>
    +in session <b><%= session.getId() %></b><br><br>
    +
    +<%
    +  if (request.getUserPrincipal() != null) {
    +%>
    +    Your user principal name is
    +    <b><%= util.HTMLFilter.filter(request.getUserPrincipal().getName()) %></b>
    +    <br><br>
    +<%
    +  } else {
    +%>
    +    No user principal could be identified.<br><br>
    +<%
    +  }
    +%>
    +
    +<%
    +  String role = request.getParameter("role");
    +  if (role == null)
    +    role = "";
    +  if (role.length() > 0) {
    +    if (request.isUserInRole(role)) {
    +%>
    +      You have been granted role
    +      <b><%= util.HTMLFilter.filter(role) %></b><br><br>
    +<%
    +    } else {
    +%>
    +      You have <i>not</i> been granted role
    +      <b><%= util.HTMLFilter.filter(role) %></b><br><br>
    +<%
    +    }
    +  }
    +%>
    +
    +To check whether your user name has been granted a particular role,
    +enter it here:
    +<form method="GET" action='<%= response.encodeURL("index.jsp") %>'>
    +<input type="text" name="role" value="<%= util.HTMLFilter.filter(role) %>">
    +<input type="submit" >
    +</form>
    +<br><br>
    +
    +If you have configured this application for form-based authentication, you can
    +log off by clicking
    +<a href='<%= response.encodeURL("index.jsp?logoff=true") %>'>here</a>.
    +This should cause you to be returned to the login page after the redirect
    +that is performed.
    +
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp new file mode 100644 index 0000000..e11a898 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp @@ -0,0 +1,38 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + +Login Page for Examples + +
    + + + + + + + + + + + + + +
    Username:
    Password:
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp.html new file mode 100644 index 0000000..5726e32 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/security/protected/login.jsp.html @@ -0,0 +1,39 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<head>
    +<title>Login Page for Examples</title>
    +<body bgcolor="white">
    +<form method="POST" action='<%= response.encodeURL("j_security_check") %>' >
    +  <table border="0" cellspacing="5">
    +    <tr>
    +      <th align="right">Username:</th>
    +      <td align="left"><input type="text" name="j_username"></td>
    +    </tr>
    +    <tr>
    +      <th align="right">Password:</th>
    +      <td align="left"><input type="password" name="j_password"></td>
    +    </tr>
    +    <tr>
    +      <td align="right"><input type="submit" value="Log In"></td>
    +      <td align="left"><input type="reset"></td>
    +    </tr>
    +  </table>
    +</form>
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/sessions/DummyCart.html b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/DummyCart.html new file mode 100644 index 0000000..d953fa9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/DummyCart.html @@ -0,0 +1,56 @@ + + + + + +sessions.DummyCart Bean Properties + + +

    +sessions.DummyCart Bean Properties +

    +
    +
    +
    public class DummyCart
    extends Object
    + +

    +


    + +

    + + + + + + + + + +
    +Properties Summary
    + +String +DummyCart:items +
    +
    + +Multi +
    +


    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.html b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.html new file mode 100644 index 0000000..834ee0a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.html @@ -0,0 +1,53 @@ + + + + + carts + + + + + +
    +
    +Please enter item to add or remove: +
    +Add Item: + + + + +

    + + + +
    + +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp new file mode 100644 index 0000000..6fba47d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp @@ -0,0 +1,43 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + + +<% + cart.processRequest(); +%> + + + +
    You have the following items in your cart: +
      +<% + String[] items = cart.getItems(); + for (int i=0; i +
    1. <% out.print(util.HTMLFilter.filter(items[i])); %> +<% + } +%> +
    + +
    + +
    +<%@ include file ="carts.html" %> + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp.html new file mode 100644 index 0000000..cb2325f --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/carts.jsp.html @@ -0,0 +1,44 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<jsp:useBean id="cart" scope="session" class="sessions.DummyCart" />
    +
    +<jsp:setProperty name="cart" property="*" />
    +<%
    +    cart.processRequest();
    +%>
    +
    +
    +<FONT size = 5 COLOR="#CC0000">
    +<br> You have the following items in your cart:
    +<ol>
    +<%
    +    String[] items = cart.getItems();
    +    for (int i=0; i<items.length; i++) {
    +%>
    +<li> <% out.print(util.HTMLFilter.filter(items[i])); %>
    +<%
    +    }
    +%>
    +</ol>
    +
    +</FONT>
    +
    +<hr>
    +<%@ include file ="carts.html" %>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/sessions/crt.html b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/crt.html new file mode 100644 index 0000000..11e6eda --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/sessions/crt.html @@ -0,0 +1,34 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Cart Example +

    + +

    Property Sheet for DummyCart +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.html b/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.html new file mode 100644 index 0000000..e20f840 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.html @@ -0,0 +1,30 @@ + + + +Untitled Document + + + + +

    + +

    Source Code for the Simple Tag Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp new file mode 100644 index 0000000..2489146 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp @@ -0,0 +1,38 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + +<%@ taglib uri="http://tomcat.apache.org/example-taglib" prefix="eg"%> + +Radio stations that rock: + +
      + +
    • <%= member %>
    • +
      +
    + + +Did you see me on the stderr window? + + + +Did you see me on the browser window as well? + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp.html new file mode 100644 index 0000000..02693c8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/simpletag/foo.jsp.html @@ -0,0 +1,39 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<body>
    +<%@ taglib uri="http://tomcat.apache.org/example-taglib" prefix="eg"%>
    +
    +Radio stations that rock:
    +
    +<ul>
    +<eg:foo att1="98.5" att2="92.3" att3="107.7">
    +<li><%= member %></li>
    +</eg:foo>
    +</ul>
    +
    +<eg:log>
    +Did you see me on the stderr window?
    +</eg:log>
    +
    +<eg:log toBrowser="true">
    +Did you see me on the browser window as well?
    +</eg:log>
    +
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.html b/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.html new file mode 100644 index 0000000..e48355b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.html @@ -0,0 +1,31 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for Request Parameters Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp new file mode 100644 index 0000000..9bb57a8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp @@ -0,0 +1,56 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + +

    Request Information

    + +JSP Request Method: <%= util.HTMLFilter.filter(request.getMethod()) %> +
    +Request URI: <%= util.HTMLFilter.filter(request.getRequestURI()) %> +
    +Request Protocol: <%= util.HTMLFilter.filter(request.getProtocol()) %> +
    +Servlet path: <%= util.HTMLFilter.filter(request.getServletPath()) %> +
    +Path info: <%= util.HTMLFilter.filter(request.getPathInfo()) %> +
    +Query string: <%= util.HTMLFilter.filter(request.getQueryString()) %> +
    +Content length: <%= request.getContentLength() %> +
    +Content type: <%= util.HTMLFilter.filter(request.getContentType()) %> +
    +Server name: <%= util.HTMLFilter.filter(request.getServerName()) %> +
    +Server port: <%= request.getServerPort() %> +
    +Remote user: <%= util.HTMLFilter.filter(request.getRemoteUser()) %> +
    +Remote address: <%= util.HTMLFilter.filter(request.getRemoteAddr()) %> +
    +Remote host: <%= util.HTMLFilter.filter(request.getRemoteHost()) %> +
    +Authorization scheme: <%= util.HTMLFilter.filter(request.getAuthType()) %> +
    +Locale: <%= request.getLocale() %> +
    +The browser you are using is +<%= util.HTMLFilter.filter(request.getHeader("User-Agent")) %> +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp.html new file mode 100644 index 0000000..00bf89b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/snp/snoop.jsp.html @@ -0,0 +1,57 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +<body bgcolor="white">
    +<h1> Request Information </h1>
    +<font size="4">
    +JSP Request Method: <%= util.HTMLFilter.filter(request.getMethod()) %>
    +<br>
    +Request URI: <%= util.HTMLFilter.filter(request.getRequestURI()) %>
    +<br>
    +Request Protocol: <%= util.HTMLFilter.filter(request.getProtocol()) %>
    +<br>
    +Servlet path: <%= util.HTMLFilter.filter(request.getServletPath()) %>
    +<br>
    +Path info: <%= util.HTMLFilter.filter(request.getPathInfo()) %>
    +<br>
    +Query string: <%= util.HTMLFilter.filter(request.getQueryString()) %>
    +<br>
    +Content length: <%= request.getContentLength() %>
    +<br>
    +Content type: <%= util.HTMLFilter.filter(request.getContentType()) %>
    +<br>
    +Server name: <%= util.HTMLFilter.filter(request.getServerName()) %>
    +<br>
    +Server port: <%= request.getServerPort() %>
    +<br>
    +Remote user: <%= util.HTMLFilter.filter(request.getRemoteUser()) %>
    +<br>
    +Remote address: <%= util.HTMLFilter.filter(request.getRemoteAddr()) %>
    +<br>
    +Remote host: <%= util.HTMLFilter.filter(request.getRemoteHost()) %>
    +<br>
    +Authorization scheme: <%= util.HTMLFilter.filter(request.getAuthType()) %>
    +<br>
    +Locale: <%= request.getLocale() %>
    +<hr>
    +The browser you are using is
    +<%= util.HTMLFilter.filter(request.getHeader("User-Agent")) %>
    +<hr>
    +</font>
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/source.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/source.jsp new file mode 100644 index 0000000..fb75b58 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/source.jsp @@ -0,0 +1,20 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/example-taglib" + prefix="eg" %> + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/source.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/source.jsp.html new file mode 100644 index 0000000..66d5a20 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/source.jsp.html @@ -0,0 +1,21 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@ taglib uri="http://tomcat.apache.org/example-taglib"
    +        prefix="eg" %>
    +
    +<eg:ShowSource jspFile="<%= util.HTMLFilter.filter(request.getQueryString()) %>"/>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.html new file mode 100644 index 0000000..afe90b2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.html @@ -0,0 +1,36 @@ + + + +View Source Code + + + +

    + + + + + +

    + +

    + Source Code for choose.jsp +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp new file mode 100644 index 0000000..745e5f5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp @@ -0,0 +1,54 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + Tag Examples - choose + + +

    Tag Plugin Examples - <c:choose>

    + +
    +
    + Plugin Introductory Notes +
    + Brief Instructions for Writing Plugins +

    +
    + +
    + + <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + # ${index}: + + + One!
    +
    + + Four!
    +
    + + Three!
    +
    + + Huh?
    +
    +
    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp.html new file mode 100644 index 0000000..3f3b7e4 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/choose.jsp.html @@ -0,0 +1,55 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +  <head>
    +    <title>Tag Examples - choose</title>
    +  </head>
    +  <body>
    +    <h1>Tag Plugin Examples - &lt;c:choose></h1>
    +
    +    <hr/>
    +    <br/>
    +    <a href="notes.html">Plugin Introductory Notes</a>
    +    <br/>
    +    <a href="howto.html">Brief Instructions for Writing Plugins</a>
    +    <br/> <br/>
    +    <hr/>
    +
    +    <br/>
    +
    +    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    +
    +    <c:forEach var="index" begin="0" end="4">
    +      # ${index}:
    +      <c:choose>
    +        <c:when test="${index == 1}">
    +          One!<br/>
    +        </c:when>
    +        <c:when test="${index == 4}">
    +          Four!<br/>
    +        </c:when>
    +        <c:when test="${index == 3}">
    +          Three!<br/>
    +        </c:when>
    +        <c:otherwise>
    +          Huh?<br/>
    +        </c:otherwise>
    +      </c:choose>
    +    </c:forEach>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.html new file mode 100644 index 0000000..3d2e608 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.html @@ -0,0 +1,36 @@ + + + +View Source Code + + + +

    + + + + + +

    + +

    + Source Code for foreach.jsp +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp new file mode 100644 index 0000000..81621cc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp @@ -0,0 +1,54 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + Tag Plugin Examples: forEach + + +

    Tag Plugin Examples - <c:forEach>

    + +
    +
    + Plugin Introductory Notes +
    + Brief Instructions for Writing Plugins +

    +
    + +
    + + <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + <%@ page import="java.util.Vector" %> + +

    Iterating over a range

    + + ${item} + + + <% Vector v = new Vector(); + v.add("One"); v.add("Two"); v.add("Three"); v.add("Four"); + + pageContext.setAttribute("vector", v); + %> + +

    Iterating over a Vector

    + + + ${item} + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp.html new file mode 100644 index 0000000..de4eca9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/foreach.jsp.html @@ -0,0 +1,55 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +  <head>
    +    <title>Tag Plugin Examples: forEach</title>
    +  </head>
    +  <body>
    +    <h1>Tag Plugin Examples - &lt;c:forEach></h1>
    +
    +    <hr/>
    +    <br/>
    +    <a href="notes.html">Plugin Introductory Notes</a>
    +    <br/>
    +    <a href="howto.html">Brief Instructions for Writing Plugins</a>
    +    <br/> <br/>
    +    <hr/>
    +
    +    <br/>
    +
    +    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    +    <%@ page import="java.util.Vector" %>
    +
    +    <h3>Iterating over a range</h3>
    +    <c:forEach var="item" begin="1" end="10">
    +        ${item}
    +    </c:forEach>
    +
    +    <% Vector v = new Vector();
    +        v.add("One"); v.add("Two"); v.add("Three"); v.add("Four");
    +
    +        pageContext.setAttribute("vector", v);
    +    %>
    +
    +    <h3>Iterating over a Vector</h3>
    +
    +    <c:forEach items="${vector}" var="item" >
    +        ${item}
    +    </c:forEach>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/howto.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/howto.html new file mode 100644 index 0000000..5f1d223 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/howto.html @@ -0,0 +1,45 @@ + + + + Tag Plugin Implementation + + +

    How to write tag plugins

    +

    + To write a plugin, you'll need to download the source for Tomcat. + There are two steps: +

      +
    1. + Implement the plugin class.

      + This class, which implements + org.apache.jasper.compiler.tagplugin.TagPlugin + instructs Jasper what Java codes to generate in place of the tag + handler calls. + See Javadoc for org.apache.jasper.compiler.tagplugin.TagPlugin + for details. +

    2. + +
    3. + Create the plugin descriptor file WEB-INF/tagPlugins.xml

      + This file + specifies the plugin classes and their corresponding tag handler + classes. +

    4. +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.html new file mode 100644 index 0000000..b04ac59 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.html @@ -0,0 +1,36 @@ + + + +View Source Code + + + +

    + + + + + +

    + +

    + Source Code for if.jsp +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp new file mode 100644 index 0000000..af627bf --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp @@ -0,0 +1,47 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + + + Tag Plugin Examples: if + + +

    Tag Plugin Examples - <c:if>

    + +
    +
    + Plugin Introductory Notes +
    + Brief Instructions for Writing Plugins +

    +
    + +
    + <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +

    Set the test result to a variable

    + + The result of testing for (1==1) is: ${theTruth} + +

    Conditionally execute the body

    + +

    It's true that (2>0)! Working.

    +
    + +

    It's not true that (0>2)! Failed.

    +
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp.html new file mode 100644 index 0000000..ee126c3 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/if.jsp.html @@ -0,0 +1,48 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<html>
    +  <head>
    +    <title>Tag Plugin Examples: if</title>
    +  </head>
    +  <body>
    +    <h1>Tag Plugin Examples - &lt;c:if></h1>
    +
    +    <hr/>
    +    <br/>
    +    <a href="notes.html">Plugin Introductory Notes</a>
    +    <br/>
    +    <a href="howto.html">Brief Instructions for Writing Plugins</a>
    +    <br/> <br/>
    +    <hr/>
    +
    +    <br/>
    +    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    +
    +    <h3>Set the test result to a variable</h3>
    +    <c:if test="${1==1}" var="theTruth" scope="page"/>
    +    The result of testing for (1==1) is: ${theTruth}
    +
    +    <h3>Conditionally execute the body</h3>
    +    <c:if test="${2>0}">
    +        <p>It's true that (2>0)! Working.</p>
    +    </c:if>
    +    <c:if test="${0>2}">
    +        <p>It's not true that (0>2)! Failed.</p>
    +    </c:if>
    +  </body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/notes.html b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/notes.html new file mode 100644 index 0000000..cd326fc --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/tagplugin/notes.html @@ -0,0 +1,41 @@ + + + + Tag Plugin Introduction + + +

    Tag Plugins: Introductory Notes

    +

    + Tomcat provides a framework for implementing tag plugins. The + plugins instruct Jasper, at translation time, to replace tag handler + calls with Java scriptlets. + The framework allows tag library authors to implement plugins for + their tags. +

    +

    + Tomcat is released with plugins for several JSTL tags. Note + that these plugins work with JSTL 1.1 as well as JSTL 1.0, though + the examples uses JSTL 1.1 and JSP 2.0. + These plugins are not complete (for instance, some item types are not + handled in <c:if>). + They do serve as examples to show plugins in action (just + examine the generated Java files), and how they can be implemented. +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.html b/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.html new file mode 100644 index 0000000..0012142 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.html @@ -0,0 +1,31 @@ + + + + +Untitled Document + + + + +

    + +

    Source Code for XML syntax Example +

    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp b/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp new file mode 100644 index 0000000..fdd5f47 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp @@ -0,0 +1,70 @@ + + + + + + + + + String getDateTimeStr(Locale l) { + DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, l); + return df.format(new Date()); + } + + + + + Example JSP in XML format + + + +This is the output of a simple JSP using XML format. +
    + +
    Use a jsp:scriptlet to loop from 1 to 10:
    + +// Note we need to declare CDATA because we don't escape the less than symbol + + + + +
    +]]> + +
    + Use a jsp:expression to write the date and time in the browser's locale: + getDateTimeStr(request.getLocale()) +
    + + + + <p>This sentence is enclosed in a jsp:text element.</p> + + + + +
    diff --git a/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp.html b/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp.html new file mode 100644 index 0000000..1f5f300 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/jsp/xml/xml.jsp.html @@ -0,0 +1,71 @@ +Source Code
    <?xml version="1.0"?>
    +<!--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +-->
    +<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
    +  version="1.2">
    +<jsp:directive.page contentType="text/html"/>
    +<jsp:directive.page import="java.util.Date, java.util.Locale"/>
    +<jsp:directive.page import="java.text.*"/>
    +
    +<jsp:declaration>
    +  String getDateTimeStr(Locale l) {
    +    DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, l);
    +    return df.format(new Date());
    +  }
    +</jsp:declaration>
    +
    +<html>
    +<head>
    +  <title>Example JSP in XML format</title>
    +</head>
    +
    +<body>
    +This is the output of a simple JSP using XML format.
    +<br />
    +
    +<div>Use a jsp:scriptlet to loop from 1 to 10: </div>
    +<jsp:scriptlet>
    +// Note we need to declare CDATA because we don't escape the less than symbol
    +<![CDATA[
    +  for (int i = 1; i<=10; i++) {
    +    out.println(i);
    +    if (i < 10) {
    +      out.println(", ");
    +    }
    +  }
    +]]>
    +</jsp:scriptlet>
    +
    +<!-- Because I omit br's end tag, declare it as CDATA -->
    +<![CDATA[
    +  <br><br>
    +]]>
    +
    +<div align="left">
    +  Use a jsp:expression to write the date and time in the browser's locale:
    +  <jsp:expression>getDateTimeStr(request.getLocale())</jsp:expression>
    +</div>
    +
    +
    +<jsp:text>
    +  &lt;p&gt;This sentence is enclosed in a jsp:text element.&lt;/p&gt;
    +</jsp:text>
    +
    +</body>
    +</html>
    +</jsp:root>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp b/test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp new file mode 100644 index 0000000..a867e37 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp @@ -0,0 +1,32 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page contentType="text/html; charset=UTF-8" %> +<% if (session.getAttribute("nickname") == null) { + response.sendRedirect("login.jsp"); + return; +} +%> + + + + JSP Chat + + + + + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp.html b/test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp.html new file mode 100644 index 0000000..a4b3b47 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/chat/index.jsp.html @@ -0,0 +1,33 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<% if (session.getAttribute("nickname") == null) {
    +    response.sendRedirect("login.jsp");
    +    return;
    +}
    +%>
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
    +<html>
    +<head>
    +   <title>JSP Chat</title>
    +</head>
    +<frameset rows="1*,4*">
    +  <frame name="post" src="post.jsp" scrolling="no" title="Post message">
    +  <frame name="chat" src="chat" scrolling="yes" title="Chat">
    +</frameset>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp b/test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp new file mode 100644 index 0000000..beb3b38 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp @@ -0,0 +1,33 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + +<%@page contentType="text/html; charset=UTF-8" %> + + + JSP Chat + + + + +
    + +Nickname: + +
    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp.html b/test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp.html new file mode 100644 index 0000000..f6186d8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/chat/login.jsp.html @@ -0,0 +1,34 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<html>
    +<head>
    +   <title>JSP Chat</title>
    +</head>
    +
    +<body bgcolor="#FFFFFF">
    +
    +<form method="POST" action='chat' target="_top" name="loginForm">
    +<input type="hidden" name="action" value="login">
    +Nickname: <input type="text" name="nickname">
    +<input type="submit">
    +</form>
    +
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp b/test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp new file mode 100644 index 0000000..f6b38e5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp @@ -0,0 +1,55 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> + +<%@page contentType="text/html; charset=UTF-8" %> + + + JSP Chat + + + + +
    + +Message: + +
    + +
    +<% + String serverName = request.getServerName(); + if ("localhost".equals(serverName)) { + serverName = "127.0.0.1"; + } else if ("127.0.0.1".equals(serverName)) { + serverName = "localhost"; + } + + String chatUrl = request.getScheme() + "://" + serverName + ":" + + request.getServerPort() + request.getContextPath() + + request.getServletPath(); + + // strip "post.jsp" from the address + chatUrl = chatUrl.substring(0, chatUrl.lastIndexOf("/") + 1); +%> +Click to open a new chat window +Note: To avoid hitting the limit on the count of simultaneous +connections to the same host, imposed by the +HTTP specification, +the second chat window should be opened using a different URL, e.g. with +an IP address instead of the host name. + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp.html b/test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp.html new file mode 100644 index 0000000..167cb6a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/chat/post.jsp.html @@ -0,0 +1,56 @@ +Source Code
    <%--
    + Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You 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.
    +--%>
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    +<%@page contentType="text/html; charset=UTF-8" %>
    +<html>
    +<head>
    +   <title>JSP Chat</title>
    +</head>
    +
    +<body bgcolor="#FFFFFF">
    +
    +<form method="POST" action='chat' name="postForm">
    +<input type="hidden" name="action" value="post">
    +Message: <input type="text" name="message">
    +<input type="submit">
    +</form>
    +
    +<br>
    +<%
    +  String serverName = request.getServerName();
    +  if ("localhost".equals(serverName)) {
    +      serverName = "127.0.0.1";
    +  } else if ("127.0.0.1".equals(serverName)) {
    +      serverName = "localhost";
    +  }
    +
    +  String chatUrl = request.getScheme() + "://" + serverName + ":"
    +    + request.getServerPort() + request.getContextPath()
    +    + request.getServletPath();
    +
    +  // strip "post.jsp" from the address
    +  chatUrl = chatUrl.substring(0, chatUrl.lastIndexOf("/") + 1);
    +%>
    +<a target="_blank" href="<%=chatUrl %>">Click to open a new chat window</a>
    +<em>Note</em>: To avoid hitting the limit on the count of simultaneous
    +connections to the same host, imposed by the
    +<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4">HTTP specification</a>,
    +the second chat window should be opened using a different URL, e.g. with
    +an IP address instead of the host name.
    +</body>
    +</html>
    +
    \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/cookies.html b/test.dockerapp/tomcat/webapps/examples/servlets/cookies.html new file mode 100644 index 0000000..bacee44 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/cookies.html @@ -0,0 +1,61 @@ + + + +Untitled Document + + + + +

    +

    Source Code for Cookie Example
    +

    + +
    import java.io.*;
    +import javax.servlet.*;
    +import javax.servlet.http.*;
    +
    +public class CookieExample extends HttpServlet {
    +
    +    public void doGet(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        response.setContentType("text/html");
    +        PrintWriter out = response.getWriter();
    +
    +        // print out cookies
    +
    +        Cookie[] cookies = request.getCookies();
    +        for (int i = 0; i < cookies.length; i++) {
    +            Cookie c = cookies[i];
    +            String name = c.getName();
    +            String value = c.getValue();
    +            out.println(name + " = " + value);
    +        }
    +
    +        // set a cookie
    +
    +        String name = request.getParameter("cookieName");
    +        if (name != null && name.length() > 0) {
    +            String value = request.getParameter("cookieValue");
    +            Cookie c = new Cookie(name, value);
    +            response.addCookie(c);
    +        }
    +    }
    +}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/helloworld.html b/test.dockerapp/tomcat/webapps/examples/servlets/helloworld.html new file mode 100644 index 0000000..c223446 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/helloworld.html @@ -0,0 +1,50 @@ + + + +Untitled Document + + + + +

    +

    Source Code for HelloWorld Example
    +

    + +
    import java.io.*;
    +import javax.servlet.*;
    +import javax.servlet.http.*;
    +
    +public class HelloWorld extends HttpServlet {
    +
    +    public void doGet(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        response.setContentType("text/html");
    +        PrintWriter out = response.getWriter();
    +        out.println("<html>");
    +        out.println("<head>");
    +        out.println("<title>Hello World!</title>");
    +        out.println("</head>");
    +        out.println("<body>");
    +        out.println("<h1>Hello World!</h1>");
    +        out.println("</body>");
    +        out.println("</html>");
    +    }
    +}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/images/code.gif b/test.dockerapp/tomcat/webapps/examples/servlets/images/code.gif new file mode 100644 index 0000000000000000000000000000000000000000..93af2cd130aa61cb2f235cdd6f0e75ab444819ef GIT binary patch literal 292 zcmZ?wbhEHblwgoxIP#z2z<~q*(`NopOZ#sOM8;>*(#{wIk?|P@o$6#>Qz3K*V4S1Pnk5hzS72pDc_ZB|0DiWTyk`LIs7s6iv0@q;(ETk{*X8*p&Sz zS?%Jy|7uNwX5dT_rVVU*FIJccbhvMP#4t}Kw7uYTuBh_VnCTjt97)}qgEke3iU+j# zdTyN*!`HsV>FFn-s95XDrdAynk)$>kVJ;@##Ikl#0e5yDZsrM%j-vc*EJY@UJi>F- w^aL|Jc?Bj;=4WLO5adbda@4El6|}Iev#dyLst@fxxV)*dq0M4 zuU27uS$av`))UvZFOHHZ*ItST2O0$7;7H? zm&+9jg_V_+QmIrfmut0JNgWD>N~y#dv!$ejV3mcCNeF_Fs91zF06g0g%rptkdaf-6 zF_0xVM$i_FQ|#InC0H;@)orLVf()pw6mqsDEh%itRj8`R2I3~Mg(*yIbHb?sbqyn3 zQYZyCsY->?M4l}qr>- z0I$VBAEL|c3!Aa23>>`6zgZI-x?7(TmI_v%;048`BL-aEhiAV!!lj_8tNy{ zuHVlON6V>(=ELvD+RJkuyyRyVcEVSxb@v=^_xJ8_AXukA`|R1H)q9Ptr@mW4Q_jP; zvV-p8YH%TPuI2Q*17~mjF+W7_4*dGfOe`P2(>42bIlAt3wjaL+tnW9`gI6Q#4vn(x+N>Q)$&RbyXeH}5khoAZ zgHYWn8m8H>&V#9A@nKri+6f7CAZX^n(t)JHP^8RL7z)bJ*uqp1CeXrcK^P~G{tuqV z^BsQQ$2pwh@zEn}1p^F%5QJd}Aw&paj0qu>(zUfUmSs7P<9S{Xgle@~tJOqNtk>(3 zB+0U@D2l48nx^TxZWsoa&$A3e34s7$jDj$XWIqfUmW{ZO5C9=SDAKGTH2r`GRm|~r z5L$j98>Zp~kYOR42b6JwQ1b%S^%chx9UoE#D+ZEvK&b8ovKvT_U$;Hc_5{o0Esv@u zV|vtZNi@a@L^X--U`fN84f8w{M0eXUG$N)K%8oDDURAev)u`Ei)$*#g&zml%+l*qc z5u_%u5lz+^!=({{P?YDX?hsigszo##*Hy@JNK{Z=MY4eu6Y@37k1~gfg@L4*NB(TMHD`z5Mi$4{3$K3Fd0=2+ z2&SJ^4mHd1^M91~z5jb@w)hR4@9nxce6>IZv*odP-zSex6`o(pw(oi7X69J;zL6Ew zmMCYwj%&NFbnm5LWxe~Y@k3x5DnB+pXsm90nHrr#zm + + + + + Servlet Examples + + + +

    Servlet +Examples with Code

    +

    This is a collection of examples which demonstrate some of the more +frequently used parts of the Servlet API. Familiarity with the Java(tm) +Programming Language is assumed. +

    These examples will only work when viewed via an http URL. They will +not work if you are viewing these pages via a "file://..." URL. Please +refer to the README file provide with this Tomcat release regarding +how to configure and start the provided web server. +

    Wherever you see a form, enter some data and see how the servlet reacts. +When playing with the Cookie and Session Examples, jump back to the Headers +Example to see exactly what your browser is sending the server. +

    To navigate your way through the examples, the following icons will +help:

    +
      +
    • Execute the example
    • +
    • Look at the source code for the example
    • + +
    • Return to this screen
    • +
    + +

    Tip: To see the cookie interactions with your browser, try turning on +the "notify when setting a cookie" option in your browser preferences. +This will let you see when a session is created and give some feedback +when looking at the cookie demo.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Hello WorldExecuteSource
    Request InfoExecuteSource
    Request HeadersExecuteSource
    Request ParametersExecuteSource
    CookiesExecuteSource
    SessionsExecuteSource
    + +

    Note: The source code for these examples does not contain all of the +source code that is actually in the example, only the important sections +of code. Code not important to understand the example has been removed +for clarity.

    + +

    Other Examples

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Servlet 3.0 Asynchronous processing examples:
    async0 + Execute +
    async1 + Execute +
    async2 + Execute +
    async3 + Execute +
    stockticker + Execute +
    Comet processing example:
    + See the "Advanced IO" chapter in the User Guide for + details. This example only works with the HTTP NIO or HTTP APR/native + connectors as these are the only connectors that support Comet.
    Comet Chat + Execute +
    Servlet 3.1 Non-blocking IO examples
    Byte counter + Execute +
    Number Writer + Execute +
    + + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/nonblocking/bytecounter.html b/test.dockerapp/tomcat/webapps/examples/servlets/nonblocking/bytecounter.html new file mode 100644 index 0000000..55d31a2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/nonblocking/bytecounter.html @@ -0,0 +1,32 @@ + + + + Servlet 3.1 non-blocking IO examples: Byte counter + + +

    Byte counter

    +

    Select a file and/or enter some data using the form below and then submit + it. The server will read the request body using non-blocking IO and then + respond with the total length of the request body in bytes.

    +
    +

    +

    +

    +
    + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/reqheaders.html b/test.dockerapp/tomcat/webapps/examples/servlets/reqheaders.html new file mode 100644 index 0000000..adda30c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/reqheaders.html @@ -0,0 +1,49 @@ + + + +Untitled Document + + + + +

    +

    Source Code for RequestHeader Example
    +

    + +
    import java.io.*;
    +import java.util.*;
    +import javax.servlet.*;
    +import javax.servlet.http.*;
    +
    +public class RequestHeaderExample extends HttpServlet {
    +
    +    public void doGet(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        response.setContentType("text/html");
    +        PrintWriter out = response.getWriter();
    +        Enumeration e = request.getHeaderNames();
    +        while (e.hasMoreElements()) {
    +            String name = (String)e.nextElement();
    +            String value = request.getHeader(name);
    +            out.println(name + " = " + value);
    +        }
    +    }
    +}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/reqinfo.html b/test.dockerapp/tomcat/webapps/examples/servlets/reqinfo.html new file mode 100644 index 0000000..daf239c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/reqinfo.html @@ -0,0 +1,68 @@ + + + +Untitled Document + + + + +

    +

    Source Code for Request Info Example
    +

    + +
    import java.io.*;
    +import javax.servlet.*;
    +import javax.servlet.http.*;
    +
    +public class RequestInfo extends HttpServlet {
    +
    +    public void doGet(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        response.setContentType("text/html");
    +        PrintWriter out = response.getWriter();
    +        out.println("<html>");
    +        out.println("<body>");
    +        out.println("<head>");
    +        out.println("<title>Request Information Example</title>");
    +        out.println("</head>");
    +        out.println("<body>");
    +        out.println("<h3>Request Information Example</h3>");
    +        out.println("Method: " + request.getMethod());
    +        out.println("Request URI: " + request.getRequestURI());
    +        out.println("Protocol: " + request.getProtocol());
    +        out.println("PathInfo: " + request.getPathInfo());
    +        out.println("Remote Address: " + request.getRemoteAddr());
    +        out.println("</body>");
    +        out.println("</html>");
    +    }
    +
    +    /**
    +     * We are going to perform the same operations for POST requests
    +     * as for GET methods, so this method just sends the request to
    +     * the doGet method.
    +     */
    +
    +    public void doPost(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        doGet(request, response);
    +    }
    +}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/reqparams.html b/test.dockerapp/tomcat/webapps/examples/servlets/reqparams.html new file mode 100644 index 0000000..7128e39 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/reqparams.html @@ -0,0 +1,78 @@ + + + +Untitled Document + + + + +

    +

    Source Code for Request Parameter Example
    +

    + +
    import java.io.*;
    +import java.util.*;
    +import javax.servlet.*;
    +import javax.servlet.http.*;
    +
    +public class RequestParamExample extends HttpServlet {
    +
    +    public void doGet(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        response.setContentType("text/html");
    +        PrintWriter out = response.getWriter();
    +        out.println("<html>");
    +        out.println("<head>");
    +        out.println("<title>Request Parameters Example</title>");
    +        out.println("</head>");
    +        out.println("<body>");
    +        out.println("<h3>Request Parameters Example</h3>");
    +        out.println("Parameters in this request:<br>");
    +        if (firstName != null || lastName != null) {
    +            out.println("First Name:");
    +            out.println(" = " + HTMLFilter.filter(firstName) + "<br>");
    +            out.println("Last Name:");
    +            out.println(" = " + HTMLFilter.filter(lastName));
    +        } else {
    +            out.println("No Parameters, Please enter some");
    +        }
    +        out.println("<P>");
    +        out.print("<form action=\"");
    +        out.print("RequestParamExample\" ");
    +        out.println("method=POST>");
    +        out.println("First Name:");
    +        out.println("<input type=text size=20 name=firstname>");
    +        out.println("<br>");
    +        out.println("Last Name:");
    +        out.println("<input type=text size=20 name=lastname>");
    +        out.println("<br>");
    +        out.println("<input type=submit>");
    +        out.println("</form>");
    +        out.println("</body>");
    +        out.println("</html>");
    +    }
    +
    +    public void doPost(HttpServletRequest request, HttpServletResponse res)
    +    throws IOException, ServletException
    +    {
    +        doGet(request, response);
    +    }
    +}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/servlets/sessions.html b/test.dockerapp/tomcat/webapps/examples/servlets/sessions.html new file mode 100644 index 0000000..99816c2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/servlets/sessions.html @@ -0,0 +1,70 @@ + + + +Untitled Document + + + + +

    +

    Source Code for Session Example
    +

    + +
    import java.io.*;
    +import java.util.*;
    +import javax.servlet.*;
    +import javax.servlet.http.*;
    +
    +public class SessionExample extends HttpServlet {
    +
    +    public void doGet(HttpServletRequest request, HttpServletResponse response)
    +    throws IOException, ServletException
    +    {
    +        response.setContentType("text/html");
    +        PrintWriter out = response.getWriter();
    +
    +        HttpSession session = request.getSession(true);
    +
    +        // print session info
    +
    +        Date created = new Date(session.getCreationTime());
    +        Date accessed = new Date(session.getLastAccessedTime());
    +        out.println("ID " + session.getId());
    +        out.println("Created: " + created);
    +        out.println("Last Accessed: " + accessed);
    +
    +        // set session info if needed
    +
    +        String dataName = request.getParameter("dataName");
    +        if (dataName != null && dataName.length() > 0) {
    +            String dataValue = request.getParameter("dataValue");
    +            session.setAttribute(dataName, dataValue);
    +        }
    +
    +        // print session contents
    +
    +        Enumeration e = session.getAttributeNames();
    +        while (e.hasMoreElements()) {
    +            String name = (String)e.nextElement();
    +            String value = session.getAttribute(name).toString();
    +            out.println(name + " = " + value);
    +        }
    +    }
    +}
    + + diff --git a/test.dockerapp/tomcat/webapps/examples/websocket/chat.xhtml b/test.dockerapp/tomcat/webapps/examples/websocket/chat.xhtml new file mode 100644 index 0000000..fca748c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/websocket/chat.xhtml @@ -0,0 +1,136 @@ + + + + + Apache Tomcat WebSocket Examples: Chat + + + + +

    Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!

    +
    +

    + +

    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/websocket/drawboard.xhtml b/test.dockerapp/tomcat/webapps/examples/websocket/drawboard.xhtml new file mode 100644 index 0000000..8c4ef73 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/websocket/drawboard.xhtml @@ -0,0 +1,897 @@ + + + + + Apache Tomcat WebSocket Examples: Drawboard + + + + +
    Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!
    +
    +
    +
    +
    + +

    About Drawboard WebSocket Example

    +
    +

    + This drawboard is a page where you can draw with your mouse or touch input + (using different colors) and everybody else which has the page open will + immediately see what you are drawing.
    + If someone opens the page later, they will get the current room image (so they + can see what was already drawn by other people). +

    +

    + It uses asynchronous sending of messages so that it doesn't need separate threads + for each client to send messages (this needs NIO or APR connector to be used).
    + Each "Room" (where the drawing happens) uses a ReentrantLock to synchronize access + (currently, only a single Room is implemented). +

    +

    + When you open the page, first you will receive a binary websocket message containing + the current room image as PNG image. After that, you will receive string messages + that contain the drawing actions (line from x1,y1 to x2,y2).
    + Note that it currently only uses simple string messages instead of JSON because + I did not want to introduce a dependency on a JSON lib. +

    +

    + It uses synchronization mechanisms to ensure that the final image will look the same + for every user, regardless of what their network latency/speed is – e.g. if two user + draw at the same time on the same place, the server will decide which line was the + first one, and that will be reflected on every client. +

    +
    + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/websocket/echo.xhtml b/test.dockerapp/tomcat/webapps/examples/websocket/echo.xhtml new file mode 100644 index 0000000..89347bb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/websocket/echo.xhtml @@ -0,0 +1,184 @@ + + + + + Apache Tomcat WebSocket Examples: Echo + + + + +

    Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!

    +
    +
    +
    + Connect to service implemented using: +
    + + +
    + + +
    + + +
    + + + +
    +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/websocket/index.xhtml b/test.dockerapp/tomcat/webapps/examples/websocket/index.xhtml new file mode 100644 index 0000000..97ee945 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/websocket/index.xhtml @@ -0,0 +1,32 @@ + + + + + Apache Tomcat WebSocket Examples + + +

    Apache Tomcat WebSocket Examples

    + + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/examples/websocket/snake.xhtml b/test.dockerapp/tomcat/webapps/examples/websocket/snake.xhtml new file mode 100644 index 0000000..b71077c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/examples/websocket/snake.xhtml @@ -0,0 +1,266 @@ + + + + + Apache Tomcat WebSocket Examples: Multiplayer Snake + + + +

    Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!

    +
    + +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/host-manager/META-INF/context.xml b/test.dockerapp/tomcat/webapps/host-manager/META-INF/context.xml new file mode 100644 index 0000000..1f32048 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/META-INF/context.xml @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/401.jsp b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/401.jsp new file mode 100644 index 0000000..047766b --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/401.jsp @@ -0,0 +1,71 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page session="false" trimDirectiveWhitespaces="true" %> + + + + 401 Unauthorized + + + +

    401 Unauthorized

    +

    + You are not authorized to view this page. If you have not changed + any configuration files, please examine the file + conf/tomcat-users.xml in your installation. That + file must contain the credentials to let you use this webapp. +

    +

    + For example, to add the admin-gui role to a user named + tomcat with a password of s3cret, add the following to the + config file listed above. +

    +
    +<role rolename="admin-gui"/>
    +<user username="tomcat" password="s3cret" roles="admin-gui"/>
    +
    +

    + Note that for Tomcat 7 onwards, the roles required to use the host manager + application were changed from the single admin role to the + following two roles. You will need to assign the role(s) required for + the functionality you wish to access. +

    +
      +
    • admin-gui - allows access to the HTML GUI
    • +
    • admin-script - allows access to the text interface
    • +
    +

    + The HTML interface is protected against CSRF but the text interface is not. + To maintain the CSRF protection: +

    +
      +
    • Users with the admin-gui role should not be granted the + admin-script role.
    • +
    • If the text interface is accessed through a browser (e.g. for testing + since this interface is intended for tools not humans) then the browser + must be closed afterwards to terminate the session.
    • +
    + + + diff --git a/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/403.jsp b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/403.jsp new file mode 100644 index 0000000..2c9f797 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/403.jsp @@ -0,0 +1,85 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page session="false" trimDirectiveWhitespaces="true" %> + + + + 403 Access Denied + + + +

    403 Access Denied

    +

    + You are not authorized to view this page. +

    +

    + If you have already configured the Host Manager application to allow access + and you have used your browsers back button, used a saved book-mark or + similar then you may have triggered the cross-site request forgery (CSRF) + protection that has been enabled for the HTML interface of the Host Manager + application. You will need to reset this protection by returning to the + main Host Manager page. + Once you return to this page, you will be able to continue using the Host + Manager application's HTML interface normally. If you continue to see this + access denied message, check that you have the necessary permissions to + access this application. +

    +

    If you have not changed + any configuration files, please examine the file + conf/tomcat-users.xml in your installation. That + file must contain the credentials to let you use this webapp. +

    +

    + For example, to add the admin-gui role to a user named + tomcat with a password of s3cret, add the following to the + config file listed above. +

    +
    +<role rolename="admin-gui"/>
    +<user username="tomcat" password="s3cret" roles="admin-gui"/>
    +
    +

    + Note that for Tomcat 7 onwards, the roles required to use the host manager + application were changed from the single admin role to the + following two roles. You will need to assign the role(s) required for + the functionality you wish to access. +

    +
      +
    • admin-gui - allows access to the HTML GUI
    • +
    • admin-script - allows access to the text interface
    • +
    +

    + The HTML interface is protected against CSRF but the text interface is not. + To maintain the CSRF protection: +

    +
      +
    • Users with the admin-gui role should not be granted the + admin-script role.
    • +
    • If the text interface is accessed through a browser (e.g. for testing + since this interface is intended for tools not humans) then the browser + must be closed afterwards to terminate the session.
    • +
    + + + diff --git a/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/404.jsp b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/404.jsp new file mode 100644 index 0000000..9816df5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/jsp/404.jsp @@ -0,0 +1,62 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page import="org.apache.catalina.util.RequestUtil" session="false" + trimDirectiveWhitespaces="true" %> + + + + 404 Not found + + + +

    404 Not found

    +

    + The page you tried to access + (<%=RequestUtil.filter((String) request.getAttribute( + "javax.servlet.error.request_uri"))%>) + does not exist. +

    +

    + The Host Manager application has been re-structured for Tomcat 7 onwards and + some URLs have changed. All URLs used to access the Manager application + should now start with one of the following options: +

    +
      +
    • <%=request.getContextPath()%>/html for the HTML GUI
    • +
    • <%=request.getContextPath()%>/text for the text interface
    • +
    +

    + Note that the URL for the text interface has changed from + "<%=request.getContextPath()%>" to + "<%=request.getContextPath()%>/text". +

    +

    + You probably need to adjust the URL you are using to access the Host Manager + application. However, there is always a chance you have found a bug in the + Host Manager application. If you are sure you have found a bug, and that the + bug has not already been reported, please report it to the Apache Tomcat + team. +

    + + diff --git a/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/web.xml b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/web.xml new file mode 100644 index 0000000..c2d6f0a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/WEB-INF/web.xml @@ -0,0 +1,143 @@ + + + + + Tomcat Host Manager Application + + A scriptable host management web application for the Tomcat Web Server; + Manager lets you view, create and remove virtual hosts. + + + + HostManager + org.apache.catalina.manager.host.HostManagerServlet + + debug + 2 + + + + HTMLHostManager + org.apache.catalina.manager.host.HTMLHostManagerServlet + + debug + 2 + + + + + SetCharacterEncoding + org.apache.catalina.filters.SetCharacterEncodingFilter + + encoding + UTF-8 + + + + + SetCharacterEncoding + /* + + + + CSRF + org.apache.catalina.filters.CsrfPreventionFilter + + entryPoints + /html,/html/,/html/list,/index.jsp + + + + + CSRF + HTMLHostManager + + + + + HostManager + /text/* + + + HTMLHostManager + /html/* + + + + + + HostManager commands + /text/* + + + + admin-script + + + + + HTMLHostManager commands + /html/* + + + + admin-gui + + + + + + BASIC + Tomcat Host Manager Application + + + + + + The role that is required to log in to the Host Manager Application HTML + interface + + admin-gui + + + + The role that is required to log in to the Host Manager Application text + interface + + admin-script + + + + 401 + /WEB-INF/jsp/401.jsp + + + 403 + /WEB-INF/jsp/403.jsp + + + 404 + /WEB-INF/jsp/404.jsp + + + diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/add.gif b/test.dockerapp/tomcat/webapps/host-manager/images/add.gif new file mode 100644 index 0000000000000000000000000000000000000000..0774d074e5e48291bdacfacb086506e6be117e51 GIT binary patch literal 1037 zcmZ?wbhEHb6k!lyc+SA^9|->a|M&0T|Nno1n4h0tnTz4o;>0&glV!LWO;{KX^ykTP zGrU;!o~1phVTD*cK_!)em>kR#mn&Z^0eO_xlSoe_rhTdU2{GAH%zidEYmsygkrvrz1CG(e()%elNK2f9s9cY)lOA zFHHY+vFYoj2~vCv9}m?1K3M+d$V54A1}%N3>6>p)KJ;Ph^-o+33=fX46z69#)mMIU zX`LuPvyQH3L))$XdH+|R`pLj3#K*_?|NDPF1}|^fSwWhMt)w~)6|3?yj#iYvY3u#U zz+k?5_Z0?4&i}vuGc&jbXzljryOSdOKilYUx!k$z`*f|fsunnK;giFW)5K{fr5eq4b7~gYAGEP z7#KS_xkU;zCM1>#7e(d>$#qP^BWE~tBtO4mJmGb}q literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/asf-logo.svg b/test.dockerapp/tomcat/webapps/host-manager/images/asf-logo.svg new file mode 100644 index 0000000..e24cbe5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/images/asf-logo.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/code.gif b/test.dockerapp/tomcat/webapps/host-manager/images/code.gif new file mode 100644 index 0000000000000000000000000000000000000000..d27307b5c09467c2e45bbfcd1ff74989eb2e7d65 GIT binary patch literal 394 zcmZ?wbhEHb6k!lySjxcg|NsAg|Na>m7<~Bf;lYCk`uh5YhK2_Y90&`0TwMGlHulx| z^XKp1zrTO~{%OFIr0wCGk>*L_#l_fx07^78uf_y0eALxXeY&ZVS$tf_gsW5<=_ z#~&LR{Wx~~@qq*T{{8>o&~U}u`>TV)%Z7#qKR>_t`1lhio=8gm&d$CqCiY|X>Z2Pr zZ1DH@->~lav}tGl|Nm=XU^H>*6ylK%0}z1x!oarPp`pM-N2)dikZ=q-8iKhfFV&ot-Z?#bsK$q(mDRr`$3(c`=?^VUbBf3LBO?F*3FB z2rH&5?cP|btfH!>&Z(iPC8xdDk6A}sSMT=aD<1m#3{1+}>>KXh^JOqF2nv4n;e)*V JgAa}j)&TJ-upR&a literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/design.gif b/test.dockerapp/tomcat/webapps/host-manager/images/design.gif new file mode 100644 index 0000000000000000000000000000000000000000..f5db0a9fc783924486176ce157924fba53df73fc GIT binary patch literal 608 zcmZ?wbhEHb6k!lyIL5&6|NsAgK=A*+y}iAiot?eCt%HMuEs*J8ujLw+y7Ptq{{K!J zf7q}4X0-UF?)+zRlW&T4U*v2)!e6yXwRo0{SJEe-5&!>cxrG=mdLiwZn4h0tkeBaZ zXTN^^`uFeOe|Y!)!-o&&&!6AFfB%LJ8x|~BuzKPA|Ns7#x-xkKyruV1%sHz7ZzCM7sKSh-eh--RQa&hK1ucJ=HF%O;;& z(71m>$AyWdcbfMc+`Vw!lBw%v)-7nyom8CNS*TU6fAIXF^#?X=1X{Rn{hEX8E?l^< zY2Dfj=YX!b$S}x&4#+*AxL{yE+Q87%#Ms=-#MIW++}hp8(Az(WfqCjw7G_pfW;S+? zK29!f9$r3v0YM>Q5mB)&afwAsB$uyTEw!$TO?uDXeKN9r%yRNakI5@2C^8>9BCn*Z zBB!dVrgo-TU7hjpQ4LKkZEYR#ysImZEe>aVg^r Vos(-!G%qcgJt^mrj0gvVH2@9_)ye<> literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/docs.gif b/test.dockerapp/tomcat/webapps/host-manager/images/docs.gif new file mode 100644 index 0000000000000000000000000000000000000000..d64a4a18c405e2c10ab791363f9f7acd16f3d433 GIT binary patch literal 261 zcmZ?wbhEHb6k!lyXklRZ|NsBLfBy^&3_g7L@ZiA%eSLjHL&F0H4xB%K{{H>@`}gm^ zaN)w=|Nrz24bGiAckjXd0|)l~`~Sb8p~273FFrp0;lqa;Hf-?s_kVc*!TptFK^W zYAveoFcA_K5zXln5UZ$U78jG4CN@JuQj&p5NQ}L2!9raIDJdi4wVO8!3NGHP$Y2cs DYrJfE literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/fix.gif b/test.dockerapp/tomcat/webapps/host-manager/images/fix.gif new file mode 100644 index 0000000000000000000000000000000000000000..d59ad642ba46c0bc1af17ebd2485722e92d6c70e GIT binary patch literal 345 zcmZ?wbhEHb6k!lySjxcg|NsAg|NhCz$;r#h*Vot2pFe-Xgb57|4F?V!*sx)Pf`Wp- zzyHC52YafE7nQ{H_?deNa@Yt7|Ns5_|Np=BjScHJZqShyb`oKj>}~Xa{jy+g9z6-E ze;_me7)uCF^D_FsZh9ae>;K=s{^BeQRBRf^&21nd@qhh{Kt8trzduj* zHV)$93F2e56B6$9w|uc@qp`Ti|35%m2ml=hAOQJ=fvwJ=K|nx4s{h22qR1Gdx!wm8 zv|72?TbvF$Sny2pWe}U_A+XHvXu`zQIrE#HnF2E`LX!mA98j7>H; OF){5sba63^6 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/tomcat.gif b/test.dockerapp/tomcat/webapps/host-manager/images/tomcat.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6f863e43e3924a35854c556a9c1b6d125cba GIT binary patch literal 2066 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/host-manager/images/update.gif b/test.dockerapp/tomcat/webapps/host-manager/images/update.gif new file mode 100644 index 0000000000000000000000000000000000000000..31e22abbc7a2e24b20b978e9be9bce91d4d97728 GIT binary patch literal 627 zcmZ?wbhEHb6k!lyIL5&6|NsAgK=A*+y}iAiot?eCt%HMuEs*J8ujLw+y7Ptq{{K!J zf7q}4X0-UF?)+zRlW&T4U*v2)!e6yXwRo0{SJEe-5&!>cxrG=mdLiwZn4h0tkeBaZ zXTN^^`uFeOe|Y!)!-o&&&!6AFfB%LJ8x|~BprD}e|KI zixKbaBa2L3t=6qucmCpq-3N9pT)$}Y+DUZ_>hmV#r_`iKsYvtb2q@R8MedK$FEQlQ z=a5vD+;`!~rt>?OoLxQp!m`Qd7Budkz+leWabaTVo#u#BStWN`r`%g8s3p4R;O>R% zmP}nYvu;6q?xf=E&O#{_89^-(t#bYP8*L_qrri462hSf`e_+E#pd0tCUvqFBkFL=A zvs*7*xUgy6+SLo^E6dAWI0y8^MUY>q3UnBN02CJt>^B-1nwl7!o0*u}x|& +<%@ page session="false" trimDirectiveWhitespaces="true" %> +<% response.sendRedirect(request.getContextPath() + "/html"); %> \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/host-manager/manager.xml b/test.dockerapp/tomcat/webapps/host-manager/manager.xml new file mode 100644 index 0000000..2510acb --- /dev/null +++ b/test.dockerapp/tomcat/webapps/host-manager/manager.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/META-INF/context.xml b/test.dockerapp/tomcat/webapps/manager/META-INF/context.xml new file mode 100644 index 0000000..cddf1d8 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/META-INF/context.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/401.jsp b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/401.jsp new file mode 100644 index 0000000..fcd0280 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/401.jsp @@ -0,0 +1,80 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page session="false" trimDirectiveWhitespaces="true" %> + + + + 401 Unauthorized + + + +

    401 Unauthorized

    +

    + You are not authorized to view this page. If you have not changed + any configuration files, please examine the file + conf/tomcat-users.xml in your installation. That + file must contain the credentials to let you use this webapp. +

    +

    + For example, to add the manager-gui role to a user named + tomcat with a password of s3cret, add the following to the + config file listed above. +

    +
    +<role rolename="manager-gui"/>
    +<user username="tomcat" password="s3cret" roles="manager-gui"/>
    +
    +

    + Note that for Tomcat 7 onwards, the roles required to use the manager + application were changed from the single manager role to the + following four roles. You will need to assign the role(s) required for + the functionality you wish to access. +

    +
      +
    • manager-gui - allows access to the HTML GUI and the status + pages
    • +
    • manager-script - allows access to the text interface and the + status pages
    • +
    • manager-jmx - allows access to the JMX proxy and the status + pages
    • +
    • manager-status - allows access to the status pages only
    • +
    +

    + The HTML interface is protected against CSRF but the text and JMX interfaces + are not. To maintain the CSRF protection: +

    +
      +
    • Users with the manager-gui role should not be granted either + the manager-script or manager-jmx roles.
    • +
    • If the text or jmx interfaces are accessed through a browser (e.g. for + testing since these interfaces are intended for tools not humans) then + the browser must be closed afterwards to terminate the session.
    • +
    +

    + For more information - please see the + Manager App HOW-TO. +

    + + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/403.jsp b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/403.jsp new file mode 100644 index 0000000..b5aed2a --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/403.jsp @@ -0,0 +1,95 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page session="false" trimDirectiveWhitespaces="true" %> + + + + 403 Access Denied + + + +

    403 Access Denied

    +

    + You are not authorized to view this page. +

    +

    + If you have already configured the Manager application to allow access and + you have used your browsers back button, used a saved book-mark or similar + then you may have triggered the cross-site request forgery (CSRF) protection + that has been enabled for the HTML interface of the Manager application. You + will need to reset this protection by returning to the + main Manager page. Once you + return to this page, you will be able to continue using the Manager + application's HTML interface normally. If you continue to see this access + denied message, check that you have the necessary permissions to access this + application. +

    +

    + If you have not changed + any configuration files, please examine the file + conf/tomcat-users.xml in your installation. That + file must contain the credentials to let you use this webapp. +

    +

    + For example, to add the manager-gui role to a user named + tomcat with a password of s3cret, add the following to the + config file listed above. +

    +
    +<role rolename="manager-gui"/>
    +<user username="tomcat" password="s3cret" roles="manager-gui"/>
    +
    +

    + Note that for Tomcat 7 onwards, the roles required to use the manager + application were changed from the single manager role to the + following four roles. You will need to assign the role(s) required for + the functionality you wish to access. +

    +
      +
    • manager-gui - allows access to the HTML GUI and the status + pages
    • +
    • manager-script - allows access to the text interface and the + status pages
    • +
    • manager-jmx - allows access to the JMX proxy and the status + pages
    • +
    • manager-status - allows access to the status pages only
    • +
    +

    + The HTML interface is protected against CSRF but the text and JMX interfaces + are not. To maintain the CSRF protection: +

    +
      +
    • Users with the manager-gui role should not be granted either + the manager-script or manager-jmx roles.
    • +
    • If the text or jmx interfaces are accessed through a browser (e.g. for + testing since these interfaces are intended for tools not humans) then + the browser must be closed afterwards to terminate the session.
    • +
    +

    + For more information - please see the + Manager App HOW-TO. +

    + + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/404.jsp b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/404.jsp new file mode 100644 index 0000000..7e1ef5c --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/404.jsp @@ -0,0 +1,63 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@ page import="org.apache.catalina.util.RequestUtil" session="false" + trimDirectiveWhitespaces="true" %> + + + + 404 Not found + + + +

    404 Not found

    +

    + The page you tried to access + (<%=RequestUtil.filter((String) request.getAttribute( + "javax.servlet.error.request_uri"))%>) + does not exist. +

    +

    + The Manager application has been re-structured for Tomcat 7 onwards and some + of URLs have changed. All URLs used to access the Manager application should + now start with one of the following options: +

    +
      +
    • <%=request.getContextPath()%>/html for the HTML GUI
    • +
    • <%=request.getContextPath()%>/text for the text interface
    • +
    • <%=request.getContextPath()%>/jmxproxy for the JMX proxy
    • +
    • <%=request.getContextPath()%>/status for the status pages
    • +
    +

    + Note that the URL for the text interface has changed from + "<%=request.getContextPath()%>" to + "<%=request.getContextPath()%>/text". +

    +

    + You probably need to adjust the URL you are using to access the Manager + application. However, there is always a chance you have found a bug in the + Manager application. If you are sure you have found a bug, and that the bug + has not already been reported, please report it to the Apache Tomcat team. +

    + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/connectorCiphers.jsp b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/connectorCiphers.jsp new file mode 100644 index 0000000..1f209c2 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/connectorCiphers.jsp @@ -0,0 +1,92 @@ + +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page session="false" contentType="text/html; charset=ISO-8859-1" %> +<%@page import="java.util.Map" %> +<%@page import="java.util.Map.Entry" %> +<%@page import="java.util.List" %> + + + +<% Map> cipherList = (Map>) request.getAttribute("cipherList"); +%> + + + + + + + + + Configured ciphers per Connector + + +

    Configured ciphers per Connector

    + + + + + + + + + + <% + for (Map.Entry> entry : cipherList.entrySet()) { + %> + + + + + <% + } + %> + +
    ConnectorEnabled Ciphers
    <%=entry.getKey()%> + <% + for (String cipher : entry.getValue()) { + %> +

    <%=cipher%>

    + <% + } + %> +
    + +
    +

    + +

    +
    + +<%--div style="display: none;"> +

    + Valid HTML 4.01! + Valid XHTML 1.0! + Valid XHTML 1.1! +

    + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionDetail.jsp b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionDetail.jsp new file mode 100644 index 0000000..1fd5046 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionDetail.jsp @@ -0,0 +1,197 @@ + +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page session="false" contentType="text/html; charset=ISO-8859-1" %> +<%@page import="java.util.Enumeration" %> +<%@page import="javax.servlet.http.HttpSession" %> +<%@page import="org.apache.catalina.Session" %> +<%@page import="org.apache.catalina.manager.JspHelper" %> +<%@page import="org.apache.catalina.util.ContextName" %> + +<%--!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"--%> + + +<% String path = (String) request.getAttribute("path"); + String version = (String) request.getAttribute("version"); + ContextName cn = new ContextName(path, version); + Session currentSession = (Session)request.getAttribute("currentSession"); + String currentSessionId = null; + HttpSession currentHttpSession = null; + if (currentSession != null) { + currentHttpSession = currentSession.getSession(); + currentSessionId = JspHelper.escapeXml(currentSession.getId()); + } else { + currentSessionId = "Session invalidated"; + } + String submitUrl = JspHelper.escapeXml(response.encodeURL( + ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + + "?path=" + path + "&version=" + version)); +%> + + + + + + + + + + Sessions Administration: details for <%= currentSessionId %> + + +<% if (currentHttpSession == null) { %> +

    <%=currentSessionId%>

    +<% } else { %> +

    Details for Session <%= currentSessionId %>

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Session Id<%= currentSessionId %>
    Guessed Locale<%= JspHelper.guessDisplayLocaleFromSession(currentSession) %>
    Guessed User<%= JspHelper.guessDisplayUserFromSession(currentSession) %>
    Creation Time<%= JspHelper.getDisplayCreationTimeForSession(currentSession) %>
    Last Accessed Time<%= JspHelper.getDisplayLastAccessedTimeForSession(currentSession) %>
    Session Max Inactive Interval<%= JspHelper.secondsToTimeString(currentSession.getMaxInactiveInterval()) %>
    Used Time<%= JspHelper.getDisplayUsedTimeForSession(currentSession) %>
    Inactive Time<%= JspHelper.getDisplayInactiveTimeForSession(currentSession) %>
    TTL<%= JspHelper.getDisplayTTLForSession(currentSession) %>
    + +
    +
    + + + <% + if ("Primary".equals(request.getParameter("sessionType"))) { + %> + + <% + } + %> +
    +
    + +
    <%= JspHelper.escapeXml(request.getAttribute("error")) %>
    +
    <%= JspHelper.escapeXml(request.getAttribute("message")) %>
    + + + <% int nAttributes = 0; + Enumeration attributeNamesEnumeration = currentHttpSession.getAttributeNames(); + while (attributeNamesEnumeration.hasMoreElements()) { + attributeNamesEnumeration.nextElement(); + ++nAttributes; + } + %> + + + + + + + + + <%--tfoot> + + + + + + <% attributeNamesEnumeration = currentHttpSession.getAttributeNames(); + while (attributeNamesEnumeration.hasMoreElements()) { + String attributeName = (String) attributeNamesEnumeration.nextElement(); + %> + + + + + + <% } // end while %> + +
    <%= JspHelper.formatNumber(nAttributes) %> attributes
    Remove AttributeAttribute nameAttribute value
    + TODO: set Max Inactive Interval on sessions +
    +
    +
    + + + + <% + if ("Primary".equals(request.getParameter("sessionType"))) { + %> + + + <% + } else { + out.print("Primary sessions only"); + } + %> +
    +
    +
    <%= JspHelper.escapeXml(attributeName) %><% Object attributeValue = currentHttpSession.getAttribute(attributeName); %>"><%= JspHelper.escapeXml(attributeValue) %>
    +<% } // endif%> + +
    +

    + +

    +
    + +<%--div style="display: none;"> +

    + Valid HTML 4.01! + Valid XHTML 1.0! + Valid XHTML 1.1! +

    + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionsList.jsp b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionsList.jsp new file mode 100644 index 0000000..c365d10 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/jsp/sessionsList.jsp @@ -0,0 +1,172 @@ + +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--%> +<%@page session="false" contentType="text/html; charset=ISO-8859-1" %> +<%@page import="java.util.Collection" %> +<%@page import="java.util.Iterator" %> +<%@page import="org.apache.catalina.manager.JspHelper" %> +<%@page import="org.apache.catalina.Session" %> +<%@page import="org.apache.catalina.ha.session.DeltaSession" %> +<%@page import="org.apache.catalina.util.ContextName" %> + + + +<%@page import="org.apache.catalina.manager.DummyProxySession"%> +<% String path = (String) request.getAttribute("path"); + String version = (String) request.getAttribute("version"); + ContextName cn = new ContextName(path, version); + String submitUrl = JspHelper.escapeXml(response.encodeURL( + ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + + "?path=" + path + "&version=" + version)); + Collection activeSessions = (Collection) request.getAttribute("activeSessions"); +%> + + + + + + + + + + Sessions Administration for <%= JspHelper.escapeXml(cn.getDisplayName()) %> + + +

    Sessions Administration for <%= JspHelper.escapeXml(cn.getDisplayName()) %>

    + +

    Tips:

    +
      +
    • Click on a column to sort.
    • +
    • To view a session details and/or remove a session attributes, click on its id.
    • +
    + +
    <%= JspHelper.escapeXml(request.getAttribute("error")) %>
    +
    <%= JspHelper.escapeXml(request.getAttribute("message")) %>
    + +
    +
    Active HttpSessions informations + + "/> + <% String order = (String) request.getAttribute("order"); + if (order == null || "".equals(order)) { + order = "ASC"; + } + %> + + + <%= JspHelper.formatNumber(activeSessions.size()) %> active Sessions
    + + + + + + + + + + + + + + + <% if (activeSessions.size() > 10) { %> + <%-- is the same as --%> + + + + + + + + + + + + + <% } // end if %> + +<% Iterator iter = activeSessions.iterator(); + while (iter.hasNext()) { + Session currentSession = (Session) iter.next(); + String currentSessionId = JspHelper.escapeXml(currentSession.getId()); + String type; + if (currentSession instanceof DeltaSession) { + if (((DeltaSession) currentSession).isPrimarySession()) { + type = "Primary"; + } else { + type = "Backup"; + } + } else if (currentSession instanceof DummyProxySession) { + type = "Proxy"; + } else { + type = "Primary"; + } +%> + + + + + + + + + + + +<% } // end while %> + +
    Session IdTypeGuessed LocaleGuessed User nameCreation TimeLast Accessed TimeUsed TimeInactive TimeTTL
    Session IdTypeGuessed LocaleGuessed User nameCreation TimeLast Accessed TimeUsed TimeInactive TimeTTL
    + <% + if ("Proxy".equals(type)) { + out.print(currentSessionId); + } else { + %> + <%= currentSessionId %> + <% + } + %> + <%= type %><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %><%= JspHelper.guessDisplayUserFromSession(currentSession) %><%= JspHelper.getDisplayCreationTimeForSession(currentSession) %><%= JspHelper.getDisplayLastAccessedTimeForSession(currentSession) %><%= JspHelper.getDisplayUsedTimeForSession(currentSession) %><%= JspHelper.getDisplayInactiveTimeForSession(currentSession) %><%= JspHelper.getDisplayTTLForSession(currentSession) %>
    +

    + +

    +
    +
    + +
    +

    + +

    +
    + +<%--div style="display: none;"> +

    + Valid HTML 4.01! + Valid XHTML 1.0! + Valid XHTML 1.1! +

    + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/WEB-INF/web.xml b/test.dockerapp/tomcat/webapps/manager/WEB-INF/web.xml new file mode 100644 index 0000000..a9c7267 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/WEB-INF/web.xml @@ -0,0 +1,213 @@ + + + + + Tomcat Manager Application + + A scriptable management web application for the Tomcat Web Server; + Manager lets you view, load/unload/etc particular web applications. + + + + Manager + org.apache.catalina.manager.ManagerServlet + + debug + 2 + + + + HTMLManager + org.apache.catalina.manager.HTMLManagerServlet + + debug + 2 + + + + + 52428800 + 52428800 + 0 + + + + Status + org.apache.catalina.manager.StatusManagerServlet + + debug + 0 + + + + + JMXProxy + org.apache.catalina.manager.JMXProxyServlet + + + + + Manager + /text/* + + + Status + /status/* + + + JMXProxy + /jmxproxy/* + + + HTMLManager + /html/* + + + + SetCharacterEncoding + org.apache.catalina.filters.SetCharacterEncodingFilter + + encoding + UTF-8 + + + + + SetCharacterEncoding + /* + + + + CSRF + org.apache.catalina.filters.CsrfPreventionFilter + + entryPoints + /html,/html/,/html/list,/index.jsp + + + + + CSRF + HTMLManager + + + + + + + HTML Manager interface (for humans) + /html/* + + + manager-gui + + + + + Text Manager interface (for scripts) + /text/* + + + manager-script + + + + + JMX Proxy interface + /jmxproxy/* + + + manager-jmx + + + + + Status interface + /status/* + + + manager-gui + manager-script + manager-jmx + manager-status + + + + + + BASIC + Tomcat Manager Application + + + + + + The role that is required to access the HTML Manager pages + + manager-gui + + + + The role that is required to access the text Manager pages + + manager-script + + + + The role that is required to access the HTML JMX Proxy + + manager-jmx + + + + The role that is required to access to the Manager Status pages + + manager-status + + + + 401 + /WEB-INF/jsp/401.jsp + + + 403 + /WEB-INF/jsp/403.jsp + + + 404 + /WEB-INF/jsp/404.jsp + + + + 419430400 + 419430400 + 0 + + + diff --git a/test.dockerapp/tomcat/webapps/manager/images/add.gif b/test.dockerapp/tomcat/webapps/manager/images/add.gif new file mode 100644 index 0000000000000000000000000000000000000000..0774d074e5e48291bdacfacb086506e6be117e51 GIT binary patch literal 1037 zcmZ?wbhEHb6k!lyc+SA^9|->a|M&0T|Nno1n4h0tnTz4o;>0&glV!LWO;{KX^ykTP zGrU;!o~1phVTD*cK_!)em>kR#mn&Z^0eO_xlSoe_rhTdU2{GAH%zidEYmsygkrvrz1CG(e()%elNK2f9s9cY)lOA zFHHY+vFYoj2~vCv9}m?1K3M+d$V54A1}%N3>6>p)KJ;Ph^-o+33=fX46z69#)mMIU zX`LuPvyQH3L))$XdH+|R`pLj3#K*_?|NDPF1}|^fSwWhMt)w~)6|3?yj#iYvY3u#U zz+k?5_Z0?4&i}vuGc&jbXzljryOSdOKilYUx!k$z`*f|fsunnK;giFW)5K{fr5eq4b7~gYAGEP z7#KS_xkU;zCM1>#7e(d>$#qP^BWE~tBtO4mJmGb}q literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/manager/images/asf-logo.svg b/test.dockerapp/tomcat/webapps/manager/images/asf-logo.svg new file mode 100644 index 0000000..e24cbe5 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/images/asf-logo.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/images/code.gif b/test.dockerapp/tomcat/webapps/manager/images/code.gif new file mode 100644 index 0000000000000000000000000000000000000000..d27307b5c09467c2e45bbfcd1ff74989eb2e7d65 GIT binary patch literal 394 zcmZ?wbhEHb6k!lySjxcg|NsAg|Na>m7<~Bf;lYCk`uh5YhK2_Y90&`0TwMGlHulx| z^XKp1zrTO~{%OFIr0wCGk>*L_#l_fx07^78uf_y0eALxXeY&ZVS$tf_gsW5<=_ z#~&LR{Wx~~@qq*T{{8>o&~U}u`>TV)%Z7#qKR>_t`1lhio=8gm&d$CqCiY|X>Z2Pr zZ1DH@->~lav}tGl|Nm=XU^H>*6ylK%0}z1x!oarPp`pM-N2)dikZ=q-8iKhfFV&ot-Z?#bsK$q(mDRr`$3(c`=?^VUbBf3LBO?F*3FB z2rH&5?cP|btfH!>&Z(iPC8xdDk6A}sSMT=aD<1m#3{1+}>>KXh^JOqF2nv4n;e)*V JgAa}j)&TJ-upR&a literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/manager/images/design.gif b/test.dockerapp/tomcat/webapps/manager/images/design.gif new file mode 100644 index 0000000000000000000000000000000000000000..f5db0a9fc783924486176ce157924fba53df73fc GIT binary patch literal 608 zcmZ?wbhEHb6k!lyIL5&6|NsAgK=A*+y}iAiot?eCt%HMuEs*J8ujLw+y7Ptq{{K!J zf7q}4X0-UF?)+zRlW&T4U*v2)!e6yXwRo0{SJEe-5&!>cxrG=mdLiwZn4h0tkeBaZ zXTN^^`uFeOe|Y!)!-o&&&!6AFfB%LJ8x|~BuzKPA|Ns7#x-xkKyruV1%sHz7ZzCM7sKSh-eh--RQa&hK1ucJ=HF%O;;& z(71m>$AyWdcbfMc+`Vw!lBw%v)-7nyom8CNS*TU6fAIXF^#?X=1X{Rn{hEX8E?l^< zY2Dfj=YX!b$S}x&4#+*AxL{yE+Q87%#Ms=-#MIW++}hp8(Az(WfqCjw7G_pfW;S+? zK29!f9$r3v0YM>Q5mB)&afwAsB$uyTEw!$TO?uDXeKN9r%yRNakI5@2C^8>9BCn*Z zBB!dVrgo-TU7hjpQ4LKkZEYR#ysImZEe>aVg^r Vos(-!G%qcgJt^mrj0gvVH2@9_)ye<> literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/manager/images/docs.gif b/test.dockerapp/tomcat/webapps/manager/images/docs.gif new file mode 100644 index 0000000000000000000000000000000000000000..d64a4a18c405e2c10ab791363f9f7acd16f3d433 GIT binary patch literal 261 zcmZ?wbhEHb6k!lyXklRZ|NsBLfBy^&3_g7L@ZiA%eSLjHL&F0H4xB%K{{H>@`}gm^ zaN)w=|Nrz24bGiAckjXd0|)l~`~Sb8p~273FFrp0;lqa;Hf-?s_kVc*!TptFK^W zYAveoFcA_K5zXln5UZ$U78jG4CN@JuQj&p5NQ}L2!9raIDJdi4wVO8!3NGHP$Y2cs DYrJfE literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/manager/images/fix.gif b/test.dockerapp/tomcat/webapps/manager/images/fix.gif new file mode 100644 index 0000000000000000000000000000000000000000..d59ad642ba46c0bc1af17ebd2485722e92d6c70e GIT binary patch literal 345 zcmZ?wbhEHb6k!lySjxcg|NsAg|NhCz$;r#h*Vot2pFe-Xgb57|4F?V!*sx)Pf`Wp- zzyHC52YafE7nQ{H_?deNa@Yt7|Ns5_|Np=BjScHJZqShyb`oKj>}~Xa{jy+g9z6-E ze;_me7)uCF^D_FsZh9ae>;K=s{^BeQRBRf^&21nd@qhh{Kt8trzduj* zHV)$93F2e56B6$9w|uc@qp`Ti|35%m2ml=hAOQJ=fvwJ=K|nx4s{h22qR1Gdx!wm8 zv|72?TbvF$Sny2pWe}U_A+XHvXu`zQIrE#HnF2E`LX!mA98j7>H; OF){5sba63^6 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/manager/images/tomcat.gif b/test.dockerapp/tomcat/webapps/manager/images/tomcat.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6f863e43e3924a35854c556a9c1b6d125cba GIT binary patch literal 2066 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 literal 0 HcmV?d00001 diff --git a/test.dockerapp/tomcat/webapps/manager/images/update.gif b/test.dockerapp/tomcat/webapps/manager/images/update.gif new file mode 100644 index 0000000000000000000000000000000000000000..31e22abbc7a2e24b20b978e9be9bce91d4d97728 GIT binary patch literal 627 zcmZ?wbhEHb6k!lyIL5&6|NsAgK=A*+y}iAiot?eCt%HMuEs*J8ujLw+y7Ptq{{K!J zf7q}4X0-UF?)+zRlW&T4U*v2)!e6yXwRo0{SJEe-5&!>cxrG=mdLiwZn4h0tkeBaZ zXTN^^`uFeOe|Y!)!-o&&&!6AFfB%LJ8x|~BprD}e|KI zixKbaBa2L3t=6qucmCpq-3N9pT)$}Y+DUZ_>hmV#r_`iKsYvtb2q@R8MedK$FEQlQ z=a5vD+;`!~rt>?OoLxQp!m`Qd7Budkz+leWabaTVo#u#BStWN`r`%g8s3p4R;O>R% zmP}nYvu;6q?xf=E&O#{_89^-(t#bYP8*L_qrri462hSf`e_+E#pd0tCUvqFBkFL=A zvs*7*xUgy6+SLo^E6dAWI0y8^MUY>q3UnBN02CJt>^B-1nwl7!o0*u}x|& +<%@ page session="false" trimDirectiveWhitespaces="true" %> +<% response.sendRedirect(request.getContextPath() + "/html"); %> \ No newline at end of file diff --git a/test.dockerapp/tomcat/webapps/manager/status.xsd b/test.dockerapp/tomcat/webapps/manager/status.xsd new file mode 100644 index 0000000..5af979d --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/status.xsd @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.dockerapp/tomcat/webapps/manager/xform.xsl b/test.dockerapp/tomcat/webapps/manager/xform.xsl new file mode 100644 index 0000000..b07fcb9 --- /dev/null +++ b/test.dockerapp/tomcat/webapps/manager/xform.xsl @@ -0,0 +1,125 @@ + + + + + + + + + + + + Tomcat Status + + + +
    Tomcat Status
    + + + + + +
    + + + + Memory Pools
    + +
    +
    + + + + + + + + +
    JVM:free: total: max:

    +
    + + + + + + + + + + +
    Name: Type: Initial: Committed: Maximum: Used:
    +
    + + + Connector --
    + + + + +
    + + + + + + + + +
    threadInfomaxThreads: currentThreadCount: currentThreadsBusy:

    +
    + + + + + + + + + + + +
    requestInfo maxTime: processingTime: requestCount: errorCount: bytesReceived: bytesSent:

    +
    + + + + + + +
    StageTimeB SentB RecvClientVHostRequest

    +
    + + + + + + + + + + ? + + + +

  • Load Balancer HOW-TO

    Table of Contents

    Using the JK 1.2.x native connector

    + +Please refer to the JK 1.2.x documentation. + +

    Using Apache HTTP Server 2.x with mod_proxy

    + +Please refer to the mod_proxy documentation for Apache HTTP Server 2.2. This supports either +HTTP or AJP load balancing. This new version of mod_proxy is also usable with +Apache HTTP Server 2.0, but mod_proxy will have to be compiled separately using the code +from Apache HTTP Server 2.2. + +

    + Comments +

    Notice: This comments section collects your suggestions + on improving documentation for Apache Tomcat.

    + If you have trouble and need help, read + Find Help page + and ask your question on the tomcat-users + mailing list. + Do not ask such questions here. This is not a Q&A section.

    + The Apache Comments System is explained here. + Comments may be removed by our moderators if they are either + implemented or considered invalid/off-topic. +