+ * Note: This method is not used by Tomcat but is used directly by
+ * third-party code and must not be removed.
+ *
+ * @param request The request object to be upgraded
+ * @param response The response object to be populated with the result of
+ * the upgrade
+ * @param sec The server endpoint to use to process the upgrade request
+ * @param pathParams The path parameters associated with the upgrade request
+ *
+ * @throws ServletException If a configuration error prevents the upgrade
+ * from taking place
+ * @throws IOException If an I/O error occurs during the upgrade process
+ */
public void doUpgrade(HttpServletRequest request,
HttpServletResponse response, ServerEndpointConfig sec,
Map pathParams)
diff -Nru tomcat7-7.0.68/java/org/apache/tomcat/websocket/Transformation.java tomcat7-7.0.69/java/org/apache/tomcat/websocket/Transformation.java
--- tomcat7-7.0.68/java/org/apache/tomcat/websocket/Transformation.java 2014-09-17 06:31:22.000000000 +0000
+++ tomcat7-7.0.69/java/org/apache/tomcat/websocket/Transformation.java 2016-03-18 11:32:53.000000000 +0000
@@ -94,4 +94,9 @@
* may be bigger or smaller than the size of the input list
*/
List sendMessagePart(List messageParts);
+
+ /**
+ * Clean-up any resources that were used by the transformation.
+ */
+ void close();
}
diff -Nru tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsFrameBase.java tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsFrameBase.java
--- tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsFrameBase.java 2015-12-11 12:51:51.000000000 +0000
+++ tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsFrameBase.java 2016-03-18 11:32:53.000000000 +0000
@@ -737,6 +737,11 @@
public boolean validateRsv(int rsv, byte opCode) {
return rsv == 0;
}
+
+ @Override
+ public void close() {
+ // NO-OP for the terminal transformations
+ }
}
diff -Nru tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
--- tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2015-12-11 13:55:37.000000000 +0000
+++ tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2016-03-18 11:32:53.000000000 +0000
@@ -271,7 +271,8 @@
// trigger a session close and depending on timing the client
// session may close before we can read the timeout.
long timeout = getBlockingSendTimeout();
- FutureToSendHandler f2sh = new FutureToSendHandler(wsSession);
+ FutureToSendHandler f2sh =
+ new FutureToSendHandler(wsSession, opCode == Constants.OPCODE_CLOSE);
startMessage(opCode, payload, last, f2sh);
try {
if (timeout == -1) {
@@ -689,6 +690,9 @@
for (EncoderEntry entry : encoderEntries) {
entry.getEncoder().destroy();
}
+ // The transformation handles both input and output. It only needs to be
+ // closed once so it is closed here on the output side.
+ transformation.close();
doClose();
}
diff -Nru tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsSession.java tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsSession.java
--- tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsSession.java 2016-02-02 12:00:49.000000000 +0000
+++ tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsSession.java 2016-02-23 15:00:53.000000000 +0000
@@ -621,7 +621,8 @@
// If the session has already been closed the any registered futures
// will have been processed so the failure result for this future
// needs to be set here.
- if (state == State.OPEN) {
+ if (state == State.OPEN || f2sh.isCloseMessage()) {
+ // WebSocket session is open or this is the close message
futures.put(f2sh, f2sh);
} else if (f2sh.isDone()) {
// NO-OP. The future completed before the session closed so no
diff -Nru tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsWebSocketContainer.java tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
--- tomcat7-7.0.68/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2015-11-27 20:29:40.000000000 +0000
+++ tomcat7-7.0.69/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2016-03-07 19:42:49.000000000 +0000
@@ -243,6 +243,7 @@
proxyPath = URI.create("http" + path.toString().substring(2));
} else if ("wss".equalsIgnoreCase(scheme)) {
proxyPath = URI.create("https" + path.toString().substring(3));
+ secure = true;
} else {
throw new DeploymentException(sm.getString(
"wsWebSocketContainer.pathWrongScheme", scheme));
@@ -284,12 +285,8 @@
} else {
// Must be wss due to scheme validation above
sa = new InetSocketAddress(host, 443);
- secure = true;
}
} else {
- if ("wss".equalsIgnoreCase(scheme)) {
- secure = true;
- }
sa = new InetSocketAddress(host, port);
}
} else {
diff -Nru tomcat7-7.0.68/res/confinstall/tomcat-users_2.xml tomcat7-7.0.69/res/confinstall/tomcat-users_2.xml
--- tomcat7-7.0.68/res/confinstall/tomcat-users_2.xml 2014-01-26 21:56:50.000000000 +0000
+++ tomcat7-7.0.69/res/confinstall/tomcat-users_2.xml 2016-03-08 18:08:16.000000000 +0000
@@ -1,18 +1,23 @@
diff -Nru tomcat7-7.0.68/res/ide-support/eclipse/eclipse.classpath tomcat7-7.0.69/res/ide-support/eclipse/eclipse.classpath
--- tomcat7-7.0.68/res/ide-support/eclipse/eclipse.classpath 2015-11-12 14:26:44.000000000 +0000
+++ tomcat7-7.0.69/res/ide-support/eclipse/eclipse.classpath 2016-03-22 09:25:42.000000000 +0000
@@ -27,5 +27,6 @@
+
diff -Nru tomcat7-7.0.68/res/maven/mvn.properties.default tomcat7-7.0.69/res/maven/mvn.properties.default
--- tomcat7-7.0.68/res/maven/mvn.properties.default 2015-12-07 15:18:38.000000000 +0000
+++ tomcat7-7.0.69/res/maven/mvn.properties.default 2016-02-09 07:25:45.000000000 +0000
@@ -35,7 +35,7 @@
maven.asf.release.repo.repositoryId=apache.releases
# Release version info
-maven.asf.release.deploy.version=7.0.68
+maven.asf.release.deploy.version=7.0.69
#Where do we load the libraries from
tomcat.lib.path=../../output/build/lib
diff -Nru tomcat7-7.0.68/res/rat/rat-excludes.txt tomcat7-7.0.69/res/rat/rat-excludes.txt
--- tomcat7-7.0.68/res/rat/rat-excludes.txt 2012-06-01 18:38:58.000000000 +0000
+++ tomcat7-7.0.69/res/rat/rat-excludes.txt 2016-02-15 21:14:55.000000000 +0000
@@ -24,9 +24,11 @@
- *.manifest JAR manifest files cannot contain license
- package-list files in API documentation (javadoc) are generated
- bug52121-part1, bug52121-part2 files in tests are test data for a hard
- to reproduce testcase and should be used as is.
+ to reproduce testcase and should be used as is.
- other trivial test files, such as textual files containing only "OK' string,
- are also excluded.
+ are also excluded.
+ - *.bmp files image files cannot contain license
+ - *.dia files image files cannot contain license
output/build/webapps/docs/*.html
output/build/webapps/docs/appdev/*.html
@@ -61,3 +63,5 @@
test/org/apache/coyote/http11/filters/bug52121-part2
test/webapp-3.0/bug53257/*.txt
test/webapp-3.0-fragments/WEB-INF/classes/*.txt
+**/*.bmp
+**/*.dia
diff -Nru tomcat7-7.0.68/res/tomcat.nsi tomcat7-7.0.69/res/tomcat.nsi
--- tomcat7-7.0.68/res/tomcat.nsi 2014-08-04 18:43:42.000000000 +0000
+++ tomcat7-7.0.69/res/tomcat.nsi 2016-02-25 20:38:14.000000000 +0000
@@ -1122,6 +1122,12 @@
SetShellVarContext current
RMDir /r "$SMPROGRAMS\Apache Tomcat @VERSION_MAJOR_MINOR@ $TomcatServiceName"
+ ; Before files are removed using recursive deletes, remove any symbolic
+ ; links in the installation directory and the directory structure below it
+ ; to ensure the recursive deletes don't result in any nasty surprises.
+ Push "$INSTDIR"
+ Call un.RemoveSymlinks
+
Delete "$INSTDIR\tomcat.ico"
Delete "$INSTDIR\LICENSE"
Delete "$INSTDIR\NOTICE"
@@ -1160,7 +1166,7 @@
; =================
; uninstall init function
;
-; Read the command line paramater and set up the service name variables so the
+; Read the command line parameter and set up the service name variables so the
; uninstaller knows which service it is working with
; =================
Function un.onInit
@@ -1170,4 +1176,46 @@
StrCpy $TomcatServiceFileName $R1.exe
StrCpy $TomcatServiceManagerFileName $R1w.exe
FunctionEnd
+
+; =================
+; Removes symbolic links from the path found on top of the stack.
+; The path is removed from the stack as a result of calling this function.
+; =================
+Function un.RemoveSymlinks
+ Pop $0
+ ${GetFileAttributes} "$0" "REPARSE_POINT" $3
+ ; DetailPrint "Processing directory [$0] [$3]"
+ FindFirst $1 $2 $0\*.*
+ ; DetailPrint "Search [$1] found [$2]"
+ StrCmp $3 "1" RemoveSymlinks-delete
+RemoveSymlinks-loop:
+ ; DetailPrint "Search [$1] processing [$0\$2]"
+ StrCmp $2 "" RemoveSymlinks-exit
+ StrCmp $2 "." RemoveSymlinks-skip
+ StrCmp $2 ".." RemoveSymlinks-skip
+ IfFileExists $0\$2\*.* RemoveSymlinks-directory
+RemoveSymlinks-skip:
+ ; DetailPrint "Search [$1] ignoring file [$0\$2]"
+ FindNext $1 $2
+ StrCmp $2 "" RemoveSymlinks-exit
+ goto RemoveSymlinks-loop
+RemoveSymlinks-directory:
+ ; DetailPrint "Search [$1] found directory [$0\$2]"
+ Push $0
+ Push $1
+ Push $0\$2
+ Call un.RemoveSymlinks
+ Pop $1
+ Pop $0
+ ; DetailPrint "Search [$1] restored for [$0]"
+ FindNext $1 $2
+ goto RemoveSymlinks-loop
+RemoveSymlinks-delete:
+ ; DetailPrint "Deleting symlink [$0]"
+ SetFileAttributes "$0" "NORMAL"
+ System::Call "kernel32::RemoveDirectoryW(w `$0`) i.n"
+RemoveSymlinks-exit:
+ ; DetailPrint "Search [$1] closed"
+ FindClose $1
+FunctionEnd
;eof
diff -Nru tomcat7-7.0.68/test/org/apache/catalina/connector/TestResponse.java tomcat7-7.0.69/test/org/apache/catalina/connector/TestResponse.java
--- tomcat7-7.0.68/test/org/apache/catalina/connector/TestResponse.java 2015-11-30 15:35:05.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/catalina/connector/TestResponse.java 2016-03-16 18:03:52.000000000 +0000
@@ -38,6 +38,7 @@
import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.unittest.TesterContext;
import org.apache.tomcat.unittest.TesterRequest;
import org.apache.tomcat.util.buf.ByteChunk;
@@ -574,6 +575,45 @@
public void testEncodeRedirectURL16() throws Exception {
doTestEncodeURL("./..#/../..", "./..;jsessionid=1234#/../..");
} @Test
+ public void testSendRedirect01() throws Exception {
+ doTestSendRedirect("../foo", "../foo");
+ }
+
+
+ @Test
+ public void testSendRedirect02() throws Exception {
+ doTestSendRedirect("../foo bar", "../foo bar");
+ }
+
+
+ @Test
+ public void testSendRedirect03() throws Exception {
+ doTestSendRedirect("../foo%20bar", "../foo%20bar");
+ }
+
+
+ private void doTestSendRedirect(String input, String expectedLocation) throws Exception {
+ // Set-up.
+ // Note: Not sufficient for testing relative -> absolute
+ Connector connector = new Connector();
+ org.apache.coyote.Response cResponse = new org.apache.coyote.Response();
+ Response response = new Response();
+ response.setConnector(connector);
+ response.setCoyoteResponse(cResponse);
+ Request request = new Request();
+ org.apache.coyote.Request cRequest = new org.apache.coyote.Request();
+ request.setCoyoteRequest(cRequest);
+ Context context = new TesterContext();
+ request.setContext(context);
+ response.setRequest(request);
+ // Do test
+ response.sendRedirect(input);
+ String location = response.getHeader("Location");
+ Assert.assertEquals(expectedLocation, location);
+ }
+
+
+ @Test
public void testBug53469a() throws Exception {
Request req = new TesterRequest();
Response resp = new Response();
diff -Nru tomcat7-7.0.68/test/org/apache/catalina/connector/TestSendFile.java tomcat7-7.0.69/test/org/apache/catalina/connector/TestSendFile.java
--- tomcat7-7.0.68/test/org/apache/catalina/connector/TestSendFile.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/catalina/connector/TestSendFile.java 2016-02-19 22:53:50.000000000 +0000
@@ -0,0 +1,166 @@
+/*
+ * 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 org.apache.catalina.connector;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+public class TestSendFile extends TomcatBaseTest{
+
+ public static final int ITERATIONS = 10;
+ public static final int EXPECTED_CONTENT_LENGTH = 100000;
+
+ @Test
+ public void testSendFile() throws Exception {
+
+ Tomcat tomcat = getTomcatInstance();
+
+ Context root = tomcat.addContext("", TEMP_DIR);
+
+ File[] files = new File[ITERATIONS];
+ for (int i=0; i> respHeaders = new HashMap>();
+ for (int i=0; i 0) {
+ int bytes = Math.min(size, defSize);
+ char[] b = new char[bytes];
+ Arrays.fill(b, 'X');
+ w.write(b);
+ size = size - bytes;
+ }
+ w.flush();
+ } finally {
+ if (w != null) {
+ w.close();
+ }
+ if (fw != null) {
+ fw.close();
+ }
+ }
+ System.out.println("Created file:" + f.getAbsolutePath() + " with " + f.length()
+ + " bytes.");
+ return f;
+
+ }
+
+
+ private static class WritingServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private final File f;
+
+ public WritingServlet(File f) {
+ this.f = f;
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ resp.setContentType("'application/octet-stream");
+ resp.setCharacterEncoding("ISO-8859-1");
+ resp.setContentLength((int) f.length());
+ if (Boolean.TRUE.equals(req.getAttribute(Globals.SENDFILE_SUPPORTED_ATTR))) {
+ req.setAttribute(Globals.SENDFILE_FILENAME_ATTR, f.getAbsolutePath());
+ req.setAttribute(Globals.SENDFILE_FILE_START_ATTR, new Long(0));
+ req.setAttribute(Globals.SENDFILE_FILE_END_ATTR, new Long(f.length()));
+ } else {
+ byte[] c = new byte[8192];
+ BufferedInputStream in = null;
+ try {
+ in = new BufferedInputStream(new FileInputStream(f));
+ int len = 0;
+ int written = 0;
+ long start = System.currentTimeMillis();
+ do {
+ len = in.read(c);
+ if (len>0) {
+ resp.getOutputStream().write(c,0,len);
+ written += len;
+ }
+ } while (len > 0);
+ System.out.println("Server Wrote "+written + " bytes in "+(System.currentTimeMillis()-start)+" ms.");
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+ }
+ }
+
+}
diff -Nru tomcat7-7.0.68/test/org/apache/catalina/core/TestAsyncContextImpl.java tomcat7-7.0.69/test/org/apache/catalina/core/TestAsyncContextImpl.java
--- tomcat7-7.0.68/test/org/apache/catalina/core/TestAsyncContextImpl.java 2016-01-04 18:23:42.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/catalina/core/TestAsyncContextImpl.java 2016-04-07 18:25:19.000000000 +0000
@@ -51,12 +51,16 @@
import org.junit.Test;
import org.apache.catalina.Context;
+import org.apache.catalina.Loader;
import org.apache.catalina.Wrapper;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.ErrorPage;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.catalina.valves.TesterAccessLogValve;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.easymock.EasyMock;
public class TestAsyncContextImpl extends TomcatBaseTest {
@@ -1165,6 +1169,7 @@
@Test
public void testErrorHandling() throws Exception {
+ resetTracker();
// Setup Tomcat instance
Tomcat tomcat = getTomcatInstance();
@@ -2212,4 +2217,58 @@
}
}
+
+
+ @Test
+ public void testAsyncListenerSupplyRequestResponse() {
+ final ServletRequest servletRequest = EasyMock.createMock(ServletRequest.class);
+ final ServletResponse servletResponse = EasyMock.createMock(ServletResponse.class);
+ final AsyncListener listener = new AsyncListener() {
+
+ @Override
+ public void onTimeout(AsyncEvent event) throws IOException {
+ checkRequestResponse(event);
+ }
+
+ @Override
+ public void onStartAsync(AsyncEvent event) throws IOException {
+ checkRequestResponse(event);
+ }
+
+ @Override
+ public void onError(AsyncEvent event) throws IOException {
+ checkRequestResponse(event);
+ }
+
+ @Override
+ public void onComplete(AsyncEvent event) throws IOException {
+ checkRequestResponse(event);
+ }
+
+ private void checkRequestResponse(AsyncEvent event) {
+ assertEquals(servletRequest, event.getSuppliedRequest());
+ assertEquals(servletResponse, event.getSuppliedResponse());
+ }
+ };
+ final Context context = EasyMock.createMock(Context.class);
+ final Loader loader = EasyMock.createMock(Loader.class);
+ final Response response = new Response();
+ final Request request = new Request();
+ request.setCoyoteRequest(new org.apache.coyote.Request());
+ request.setContext(context);
+ final AsyncContextImpl ac = new AsyncContextImpl(request);
+ EasyMock.expect(context.getApplicationEventListeners()).andReturn(null);
+ EasyMock.expect(context.getLoader()).andReturn(loader);
+ EasyMock.expect(loader.getClassLoader()).andReturn(null);
+
+ EasyMock.replay(context, loader);
+
+ ac.addListener(listener, servletRequest, servletResponse);
+ ac.setStarted(context, request, response, true);
+ ac.addListener(listener, servletRequest, servletResponse);
+ ac.setErrorState(new Exception(), true);
+ ac.fireOnComplete();
+
+ EasyMock.verify(context, loader);
+ }
}
diff -Nru tomcat7-7.0.68/test/org/apache/catalina/session/TesterStore.java tomcat7-7.0.69/test/org/apache/catalina/session/TesterStore.java
--- tomcat7-7.0.68/test/org/apache/catalina/session/TesterStore.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/catalina/session/TesterStore.java 2016-04-06 20:24:19.000000000 +0000
@@ -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.
+ */
+package org.apache.catalina.session;
+
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.Store;
+
+class TesterStore implements Store {
+
+ private Manager manager;
+ private Map sessions = new HashMap();
+ private List savedIds = new ArrayList();
+
+ List getSavedIds() {
+ return savedIds;
+ }
+
+ @Override
+ public Manager getManager() {
+ return this.manager;
+ }
+
+ @Override
+ public void setManager(Manager manager) {
+ this.manager = manager;
+ }
+
+ @Override
+ public int getSize() throws IOException {
+ return savedIds.size();
+ }
+
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ }
+
+ @Override
+ public String[] keys() throws IOException {
+ return new ArrayList(sessions.keySet()).toArray(new String[] {});
+ }
+
+ @Override
+ public Session load(String id) throws ClassNotFoundException,
+ IOException {
+ return sessions.get(id);
+ }
+
+ @Override
+ public void remove(String id) throws IOException {
+ sessions.remove(id);
+ }
+
+ @Override
+ public void clear() throws IOException {
+ }
+
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ }
+
+ @Override
+ public void save(Session session) throws IOException {
+ sessions.put(session.getId(), session);
+ savedIds.add(session.getId());
+ }
+
+ @Override
+ public String getInfo() {
+ return null;
+ }
+}
+
diff -Nru tomcat7-7.0.68/test/org/apache/catalina/session/TestPersistentManagerIntegration.java tomcat7-7.0.69/test/org/apache/catalina/session/TestPersistentManagerIntegration.java
--- tomcat7-7.0.68/test/org/apache/catalina/session/TestPersistentManagerIntegration.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/catalina/session/TestPersistentManagerIntegration.java 2016-04-06 20:24:19.000000000 +0000
@@ -0,0 +1,241 @@
+/*
+ * 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 org.apache.catalina.session;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+
+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 org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.Session;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.catalina.valves.PersistentValve;
+
+public class TestPersistentManagerIntegration extends TomcatBaseTest {
+
+ private final String ACTIVITY_CHECK = "org.apache.catalina.session.StandardSession.ACTIVITY_CHECK";
+
+ private String oldActivityCheck;
+
+ /**
+ * As documented in config/manager.html, the "ACTIVITY_CHECK" property must
+ * be set to "true" for PersistentManager to function correctly.
+ */
+ @Before
+ public void setActivityCheck() {
+ oldActivityCheck = System.setProperty(ACTIVITY_CHECK, "true");
+ }
+
+ @After
+ public void resetActivityCheck() {
+ if (oldActivityCheck != null) {
+ System.setProperty(ACTIVITY_CHECK, oldActivityCheck);
+ } else {
+ System.clearProperty(ACTIVITY_CHECK);
+ }
+ }
+
+ /**
+ * Wait enough for the system clock to update its value. On some systems
+ * (e.g. old Windows) the clock granularity is tens of milliseconds.
+ */
+ private void waitForClockUpdate() throws InterruptedException {
+ long startTime = System.currentTimeMillis();
+ int waitTime = 1;
+ do {
+ Thread.sleep(waitTime);
+ waitTime *= 10;
+ } while (System.currentTimeMillis() == startTime);
+ }
+
+ /**
+ * Wait while session access counter has a positive value.
+ */
+ private void waitWhileSessionIsActive(StandardSession session)
+ throws InterruptedException {
+ long maxWaitTime = System.currentTimeMillis() + 60000;
+ AtomicInteger accessCount = session.accessCount;
+ while (accessCount.get() > 0) {
+ // Wait until o.a.c.connector.Request.recycle() completes,
+ // as it updates lastAccessedTime.
+ Assert.assertTrue(System.currentTimeMillis() < maxWaitTime);
+ Thread.sleep(200);
+ }
+ }
+
+ @Test
+ public void noSessionCreate_57637() throws IOException, LifecycleException {
+
+ // Setup Tomcat instance
+ Tomcat tomcat = getTomcatInstance();
+
+ // No file system docBase required
+ StandardContext ctx = (StandardContext) tomcat.addContext("", null);
+ ctx.setDistributable(true);
+
+ Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
+ ctx.addServletMapping("/dummy", "DummyServlet");
+
+ PersistentManager manager = new PersistentManager();
+ TesterStore store = new TesterStore();
+
+ manager.setStore(store);
+ manager.setMaxIdleBackup(0);
+ ctx.setManager(manager);
+ ctx.addValve(new PersistentValve());
+ tomcat.start();
+ Assert.assertEquals(manager.getActiveSessions(), 0);
+ Assert.assertTrue("No sessions managed", manager.getSessionIdsFull().isEmpty());
+ Assert.assertEquals(
+ "NO_SESSION",
+ getUrl(
+ "http://localhost:" + getPort()
+ + "/dummy?no_create_session=true").toString());
+ Assert.assertEquals(manager.getActiveSessions(), 0);
+ Assert.assertTrue("No sessions where created", manager.getSessionIdsFull().isEmpty());
+ }
+
+ @Test
+ public void testCreateSessionAndPassivate() throws IOException, LifecycleException, ClassNotFoundException {
+
+ // Setup Tomcat instance
+ Tomcat tomcat = getTomcatInstance();
+
+ // No file system docBase required
+ StandardContext ctx = (StandardContext) tomcat.addContext("", null);
+ ctx.setDistributable(true);
+
+ Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
+ ctx.addServletMapping("/dummy", "DummyServlet");
+
+ PersistentManager manager = new PersistentManager();
+ TesterStore store = new TesterStore();
+
+ manager.setStore(store);
+ manager.setMaxIdleBackup(0);
+ ctx.setManager(manager);
+ ctx.addValve(new PersistentValve());
+ tomcat.start();
+ Assert.assertEquals("No active sessions", manager.getActiveSessions(), 0);
+ Assert.assertTrue("No sessions managed", manager.getSessionIdsFull().isEmpty());
+ String sessionId = getUrl(
+ "http://localhost:" + getPort()
+ + "/dummy?no_create_session=false").toString();
+ Assert.assertNotNull("Session is stored", store.load(sessionId));
+ Assert.assertEquals("All sessions are passivated", manager.getActiveSessions(), 0);
+ Assert.assertTrue("One session was created", !manager.getSessionIdsFull().isEmpty());
+ }
+
+ @Test
+ public void backsUpOnce_56698() throws IOException, LifecycleException,
+ InterruptedException {
+
+ // Setup Tomcat instance
+ Tomcat tomcat = getTomcatInstance();
+
+ // No file system docBase required
+ Context ctx = tomcat.addContext("", null);
+ ctx.setDistributable(true);
+
+ Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
+ ctx.addServletMapping("/dummy", "DummyServlet");
+
+ PersistentManager manager = new PersistentManager();
+ TesterStore store = new TesterStore();
+
+ manager.setStore(store);
+ manager.setMaxIdleBackup(0);
+ ctx.setManager(manager);
+ tomcat.start();
+ String sessionId = getUrl("http://localhost:" + getPort() + "/dummy")
+ .toString();
+
+ // Note: PersistenceManager.findSession() silently updates
+ // session.lastAccessedTime, so call it only once before other work.
+ Session session = manager.findSession(sessionId);
+
+ // Wait until request processing ends, as Request.recycle() updates
+ // session.lastAccessedTime via session.endAccess().
+ waitWhileSessionIsActive((StandardSession) session);
+
+ long lastAccessedTime = session.getLastAccessedTimeInternal();
+
+ // Session should be idle at least for 0 second (maxIdleBackup)
+ // to be eligible for persistence, thus no need to wait.
+
+ // Waiting a bit, to catch changes in last accessed time of a session
+ waitForClockUpdate();
+
+ manager.processPersistenceChecks();
+ Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds());
+ Assert.assertEquals(lastAccessedTime, session.getLastAccessedTimeInternal());
+
+ // session was not accessed, so no save will be performed
+ waitForClockUpdate();
+ manager.processPersistenceChecks();
+ Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds());
+ Assert.assertEquals(lastAccessedTime, session.getLastAccessedTimeInternal());
+
+ // access session
+ session.access();
+ session.endAccess();
+
+ // session was accessed, so it will be saved once again
+ manager.processPersistenceChecks();
+ Assert.assertEquals(Arrays.asList(sessionId, sessionId),
+ store.getSavedIds());
+
+ // session was not accessed, so once again no save will happen
+ manager.processPersistenceChecks();
+ Assert.assertEquals(Arrays.asList(sessionId, sessionId),
+ store.getSavedIds());
+ }
+
+ private static class DummyServlet extends HttpServlet {
+
+ private static final long serialVersionUID = -3696433049266123995L;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ boolean createSession = !Boolean.parseBoolean(req
+ .getParameter("no_create_session"));
+ HttpSession session = req.getSession(createSession);
+ if (session == null) {
+ resp.getWriter().print("NO_SESSION");
+ } else {
+ String id = session.getId();
+ resp.getWriter().print(id);
+ }
+ }
+
+ }
+}
diff -Nru tomcat7-7.0.68/test/org/apache/catalina/session/TestPersistentManager.java tomcat7-7.0.69/test/org/apache/catalina/session/TestPersistentManager.java
--- tomcat7-7.0.68/test/org/apache/catalina/session/TestPersistentManager.java 2016-01-26 23:40:33.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/catalina/session/TestPersistentManager.java 2016-04-06 20:27:42.000000000 +0000
@@ -16,298 +16,44 @@
*/
package org.apache.catalina.session;
-import java.beans.PropertyChangeListener;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-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 org.junit.After;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.Manager;
-import org.apache.catalina.Session;
-import org.apache.catalina.Store;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.startup.Tomcat;
-import org.apache.catalina.startup.TomcatBaseTest;
-import org.apache.catalina.valves.PersistentValve;
-
-public class TestPersistentManager extends TomcatBaseTest {
-
- private final String ACTIVITY_CHECK = "org.apache.catalina.session.StandardSession.ACTIVITY_CHECK";
-
- private String oldActivityCheck;
-
- /**
- * As documented in config/manager.html, the "ACTIVITY_CHECK" property must
- * be set to "true" for PersistentManager to function correctly.
- */
- @Before
- public void setActivityCheck() {
- oldActivityCheck = System.setProperty(ACTIVITY_CHECK, "true");
- }
-
- @After
- public void resetActivityCheck() {
- if (oldActivityCheck != null) {
- System.setProperty(ACTIVITY_CHECK, oldActivityCheck);
- } else {
- System.clearProperty(ACTIVITY_CHECK);
- }
- }
+import org.apache.catalina.Host;
+import org.apache.tomcat.unittest.TesterContext;
+import org.apache.tomcat.unittest.TesterHost;
- /**
- * Wait enough for the system clock to update its value. On some systems
- * (e.g. old Windows) the clock granularity is tens of milliseconds.
- */
- private void waitForClockUpdate() throws InterruptedException {
- long startTime = System.currentTimeMillis();
- int waitTime = 1;
- do {
- Thread.sleep(waitTime);
- waitTime *= 10;
- } while (System.currentTimeMillis() == startTime);
- }
-
- /**
- * Wait while session access counter has a positive value.
- */
- private void waitWhileSessionIsActive(StandardSession session)
- throws InterruptedException {
- long maxWaitTime = System.currentTimeMillis() + 60000;
- AtomicInteger accessCount = session.accessCount;
- while (accessCount.get() > 0) {
- // Wait until o.a.c.connector.Request.recycle() completes,
- // as it updates lastAccessedTime.
- Assert.assertTrue(System.currentTimeMillis() < maxWaitTime);
- Thread.sleep(200);
- }
- }
+public class TestPersistentManager {
@Test
- public void noSessionCreate_57637() throws IOException, LifecycleException {
-
- // Setup Tomcat instance
- Tomcat tomcat = getTomcatInstance();
-
- File appDir = new File("test/webapp-3.0-fragments-empty-absolute-ordering");
- StandardContext ctx = (StandardContext) tomcat.addContext("", appDir.getAbsolutePath());
- ctx.setDistributable(true);
-
- Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
- ctx.addServletMapping("/dummy", "DummyServlet");
-
+ public void testMinIdleSwap() throws Exception {
PersistentManager manager = new PersistentManager();
- DummyStore store = new DummyStore();
+ manager.setStore(new TesterStore());
- manager.setStore(store);
- manager.setMaxIdleBackup(0);
- ctx.setManager(manager);
- ctx.addValve(new PersistentValve());
- tomcat.start();
- Assert.assertEquals(manager.getActiveSessions(), 0);
- Assert.assertTrue("No sessions managed", manager.getSessionIdsFull().isEmpty());
- Assert.assertEquals(
- "NO_SESSION",
- getUrl(
- "http://localhost:" + getPort()
- + "/dummy?no_create_session=true").toString());
- Assert.assertEquals(manager.getActiveSessions(), 0);
- Assert.assertTrue("No sessions where created", manager.getSessionIdsFull().isEmpty());
- }
-
- @Test
- public void testCreateSessionAndPassivate() throws IOException, LifecycleException, ClassNotFoundException {
-
- // Setup Tomcat instance
- Tomcat tomcat = getTomcatInstance();
-
- File appDir = new File("test/webapp-3.0-fragments-empty-absolute-ordering");
- StandardContext ctx = (StandardContext) tomcat.addContext("", appDir.getAbsolutePath());
- ctx.setDistributable(true);
+ Host host = new TesterHost();
+ Context context = new TesterContext();
+ context.setParent(host);
- Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
- ctx.addServletMapping("/dummy", "DummyServlet");
+ manager.setContainer(context);
- PersistentManager manager = new PersistentManager();
- DummyStore store = new DummyStore();
-
- manager.setStore(store);
- manager.setMaxIdleBackup(0);
- ctx.setManager(manager);
- ctx.addValve(new PersistentValve());
- tomcat.start();
- Assert.assertEquals("No active sessions", manager.getActiveSessions(), 0);
- Assert.assertTrue("No sessions managed", manager.getSessionIdsFull().isEmpty());
- String sessionId = getUrl(
- "http://localhost:" + getPort()
- + "/dummy?no_create_session=false").toString();
- Assert.assertNotNull("Session is stored", store.load(sessionId));
- Assert.assertEquals("All sessions are passivated", manager.getActiveSessions(), 0);
- Assert.assertTrue("One session was created", !manager.getSessionIdsFull().isEmpty());
- }
-
- @Test
- public void backsUpOnce_56698() throws IOException, LifecycleException,
- InterruptedException {
+ manager.setMaxActiveSessions(2);
+ manager.setMinIdleSwap(0);
- // Setup Tomcat instance
- Tomcat tomcat = getTomcatInstance();
- // No file system docBase required
- Context ctx = tomcat.addContext("", null);
- ctx.setDistributable(true);
+ manager.start();
- Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
- ctx.addServletMapping("/dummy", "DummyServlet");
+ // Create the maximum number of sessions
+ manager.createSession(null);
+ manager.createSession(null);
- PersistentManager manager = new PersistentManager();
- DummyStore store = new DummyStore();
-
- manager.setStore(store);
- manager.setMaxIdleBackup(0);
- ctx.setManager(manager);
- tomcat.start();
- String sessionId = getUrl("http://localhost:" + getPort() + "/dummy")
- .toString();
-
- // Note: PersistenceManager.findSession() silently updates
- // session.lastAccessedTime, so call it only once before other work.
- Session session = manager.findSession(sessionId);
-
- // Wait until request processing ends, as Request.recycle() updates
- // session.lastAccessedTime via session.endAccess().
- waitWhileSessionIsActive((StandardSession) session);
-
- long lastAccessedTime = session.getLastAccessedTimeInternal();
-
- // Session should be idle at least for 0 second (maxIdleBackup)
- // to be eligible for persistence, thus no need to wait.
-
- // Waiting a bit, to catch changes in last accessed time of a session
- waitForClockUpdate();
-
- manager.processPersistenceChecks();
- Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds());
- Assert.assertEquals(lastAccessedTime, session.getLastAccessedTimeInternal());
-
- // session was not accessed, so no save will be performed
- waitForClockUpdate();
- manager.processPersistenceChecks();
- Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds());
- Assert.assertEquals(lastAccessedTime, session.getLastAccessedTimeInternal());
-
- // access session
- session.access();
- session.endAccess();
-
- // session was accessed, so it will be saved once again
- manager.processPersistenceChecks();
- Assert.assertEquals(Arrays.asList(sessionId, sessionId),
- store.getSavedIds());
-
- // session was not accessed, so once again no save will happen
+ // Given the minIdleSwap settings, this should swap one out to get below
+ // the limit
manager.processPersistenceChecks();
- Assert.assertEquals(Arrays.asList(sessionId, sessionId),
- store.getSavedIds());
- }
-
- private static class DummyServlet extends HttpServlet {
-
- private static final long serialVersionUID = -3696433049266123995L;
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- boolean createSession = !Boolean.parseBoolean(req
- .getParameter("no_create_session"));
- HttpSession session = req.getSession(createSession);
- if (session == null) {
- resp.getWriter().print("NO_SESSION");
- } else {
- String id = session.getId();
- resp.getWriter().print(id);
- }
- }
-
- }
-
- private static class DummyStore implements Store {
+ Assert.assertEquals(1, manager.getActiveSessions());
+ Assert.assertEquals(2, manager.getActiveSessionsFull());
- private Manager manager;
- private Map sessions = new HashMap();
- private List savedIds = new ArrayList();
-
- List getSavedIds() {
- return savedIds;
- }
-
- @Override
- public Manager getManager() {
- return this.manager;
- }
-
- @Override
- public void setManager(Manager manager) {
- this.manager = manager;
- }
-
- @Override
- public int getSize() throws IOException {
- return 0;
- }
-
- @Override
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- }
-
- @Override
- public String[] keys() throws IOException {
- return new ArrayList(sessions.keySet()).toArray(new String[] {});
- }
-
- @Override
- public Session load(String id) throws ClassNotFoundException,
- IOException {
- return sessions.get(id);
- }
-
- @Override
- public void remove(String id) throws IOException {
- sessions.remove(id);
- }
-
- @Override
- public void clear() throws IOException {
- }
-
- @Override
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- }
-
- @Override
- public void save(Session session) throws IOException {
- sessions.put(session.getId(), session);
- savedIds.add(session.getId());
- }
-
- @Override
- public String getInfo() {
- return null;
- }
+ manager.createSession(null);
+ Assert.assertEquals(2, manager.getActiveSessions());
+ Assert.assertEquals(3, manager.getActiveSessionsFull());
}
}
diff -Nru tomcat7-7.0.68/test/org/apache/tomcat/unittest/TesterContext.java tomcat7-7.0.69/test/org/apache/tomcat/unittest/TesterContext.java
--- tomcat7-7.0.68/test/org/apache/tomcat/unittest/TesterContext.java 2015-12-01 13:07:02.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/tomcat/unittest/TesterContext.java 2016-04-06 20:24:19.000000000 +0000
@@ -148,24 +148,26 @@
// NO-OP
}
+ private String name = "/test";
@Override
public String getName() {
- return "/test";
+ return name;
}
@Override
public void setName(String name) {
- // NO-OP
+ this.name = name;
}
+ private Container parent = null;
@Override
public Container getParent() {
- return null;
+ return parent;
}
@Override
public void setParent(Container container) {
- // NO-OP
+ this.parent = container;
}
@Override
diff -Nru tomcat7-7.0.68/test/org/apache/tomcat/unittest/TesterHost.java tomcat7-7.0.69/test/org/apache/tomcat/unittest/TesterHost.java
--- tomcat7-7.0.68/test/org/apache/tomcat/unittest/TesterHost.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/tomcat/unittest/TesterHost.java 2016-04-06 20:24:19.000000000 +0000
@@ -0,0 +1,391 @@
+/*
+ * 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 org.apache.tomcat.unittest;
+
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.regex.Pattern;
+
+import javax.management.ObjectName;
+import javax.naming.directory.DirContext;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.AccessLog;
+import org.apache.catalina.Cluster;
+import org.apache.catalina.Container;
+import org.apache.catalina.ContainerListener;
+import org.apache.catalina.Host;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.Loader;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Pipeline;
+import org.apache.catalina.Realm;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.juli.logging.Log;
+
+public class TesterHost implements Host {
+
+ @Override
+ public Log getLogger() {
+ return null;
+ }
+
+ @Override
+ public ObjectName getObjectName() {
+ return null;
+ }
+
+ @Override
+ public Pipeline getPipeline() {
+ return null;
+ }
+
+ @Override
+ public Cluster getCluster() {
+ return null;
+ }
+
+ @Override
+ public void setCluster(Cluster cluster) {
+ // NO-OP
+ }
+
+ @Override
+ public int getBackgroundProcessorDelay() {
+ return 0;
+ }
+
+ @Override
+ public void setBackgroundProcessorDelay(int delay) {
+ // NO-OP
+ }
+
+ private String name = "TestHost";
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public Container getParent() {
+ return null;
+ }
+
+ @Override
+ public void setParent(Container container) {
+ // NO-OP
+ }
+
+ @Override
+ public ClassLoader getParentClassLoader() {
+ return null;
+ }
+
+ @Override
+ public void setParentClassLoader(ClassLoader parent) {
+ // NO-OP
+ }
+
+ @Override
+ public Realm getRealm() {
+ return null;
+ }
+
+ @Override
+ public void setRealm(Realm realm) {
+ // NO-OP
+ }
+
+ @Override
+ public void backgroundProcess() {
+ // NO-OP
+ }
+
+ @Override
+ public void addChild(Container child) {
+ // NO-OP
+ }
+
+ @Override
+ public void addContainerListener(ContainerListener listener) {
+ // NO-OP
+ }
+
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ // NO-OP
+ }
+
+ @Override
+ public Container findChild(String name) {
+ return null;
+ }
+
+ @Override
+ public Container[] findChildren() {
+ return null;
+ }
+
+ @Override
+ public ContainerListener[] findContainerListeners() {
+ return null;
+ }
+
+ @Override
+ public void removeChild(Container child) {
+ // NO-OP
+ }
+
+ @Override
+ public void removeContainerListener(ContainerListener listener) {
+ // NO-OP
+ }
+
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ // NO-OP
+ }
+
+ @Override
+ public void fireContainerEvent(String type, Object data) {
+ // NO-OP
+ }
+
+ @Override
+ public void logAccess(Request request, Response response, long time, boolean useDefault) {
+ // NO-OP
+ }
+
+ @Override
+ public AccessLog getAccessLog() {
+ return null;
+ }
+
+ @Override
+ public int getStartStopThreads() {
+ return 0;
+ }
+
+ @Override
+ public void setStartStopThreads(int startStopThreads) {
+ // NO-OP
+ }
+
+ @Override
+ public void addLifecycleListener(LifecycleListener listener) {
+ // NO-OP
+ }
+
+ @Override
+ public LifecycleListener[] findLifecycleListeners() {
+ return null;
+ }
+
+ @Override
+ public void removeLifecycleListener(LifecycleListener listener) {
+ // NO-OP
+ }
+
+ @Override
+ public void init() throws LifecycleException {
+ // NO-OP
+ }
+
+ @Override
+ public void start() throws LifecycleException {
+ // NO-OP
+ }
+
+ @Override
+ public void stop() throws LifecycleException {
+ // NO-OP
+ }
+
+ @Override
+ public void destroy() throws LifecycleException {
+ // NO-OP
+ }
+
+ @Override
+ public LifecycleState getState() {
+ return null;
+ }
+
+ @Override
+ public String getStateName() {
+ return null;
+ }
+
+ @Override
+ public String getXmlBase() {
+ return null;
+ }
+
+ @Override
+ public void setXmlBase(String xmlBase) {
+ // NO-OP
+ }
+
+ @Override
+ public String getAppBase() {
+ return null;
+ }
+
+ @Override
+ public void setAppBase(String appBase) {
+ // NO-OP
+ }
+
+ @Override
+ public boolean getAutoDeploy() {
+ return false;
+ }
+
+ @Override
+ public void setAutoDeploy(boolean autoDeploy) {
+ // NO-OP
+ }
+
+ @Override
+ public String getConfigClass() {
+ return null;
+ }
+
+ @Override
+ public void setConfigClass(String configClass) {
+ // NO-OP
+ }
+
+ @Override
+ public boolean getDeployOnStartup() {
+ return false;
+ }
+
+ @Override
+ public void setDeployOnStartup(boolean deployOnStartup) {
+ // NO-OP
+ }
+
+ @Override
+ public String getDeployIgnore() {
+ return null;
+ }
+
+ @Override
+ public Pattern getDeployIgnorePattern() {
+ return null;
+ }
+
+ @Override
+ public void setDeployIgnore(String deployIgnore) {
+ // NO-OP
+ }
+
+ @Override
+ public ExecutorService getStartStopExecutor() {
+ return null;
+ }
+
+ @Override
+ public boolean getCreateDirs() {
+ return false;
+ }
+
+ @Override
+ public void setCreateDirs(boolean createDirs) {
+ // NO-OP
+ }
+
+ @Override
+ public boolean getUndeployOldVersions() {
+ return false;
+ }
+
+ @Override
+ public void setUndeployOldVersions(boolean undeployOldVersions) {
+ // NO-OP
+ }
+
+ @Override
+ public void addAlias(String alias) {
+ // NO-OP
+ }
+
+ @Override
+ public String[] findAliases() {
+ return null;
+ }
+
+ @Override
+ public void removeAlias(String alias) {
+ // NO-OP
+ }
+
+ @Override
+ public String getInfo() {
+ return null;
+ }
+
+ @Override
+ public Loader getLoader() {
+ return null;
+ }
+
+ @Override
+ public void setLoader(Loader loader) {
+ // NO-OP
+ }
+
+ @Override
+ public Manager getManager() {
+ return null;
+ }
+
+ @Override
+ public void setManager(Manager manager) {
+ // NO-OP
+ }
+
+ @Override
+ public Object getMappingObject() {
+ return null;
+ }
+
+ @Override
+ public DirContext getResources() {
+ return null;
+ }
+
+ @Override
+ public void setResources(DirContext resources) {
+ // NO-OP
+ }
+
+ @Override
+ public void invoke(Request request, Response response) throws IOException, ServletException {
+ // NO-OP
+ }
+}
diff -Nru tomcat7-7.0.68/test/org/apache/tomcat/util/buf/TestUriUtil.java tomcat7-7.0.69/test/org/apache/tomcat/util/buf/TestUriUtil.java
--- tomcat7-7.0.68/test/org/apache/tomcat/util/buf/TestUriUtil.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/tomcat/util/buf/TestUriUtil.java 2016-03-01 23:04:09.000000000 +0000
@@ -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 org.apache.tomcat.util.buf;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestUriUtil {
+
+ @Test
+ public void testBuildJarUrl01() throws MalformedURLException {
+ File jarFile = new File("/patha/pathb!/pathc");
+ String result = UriUtil.buildJarUrl(jarFile).toString();
+
+ int index = result.indexOf("!/");
+ Assert.assertEquals(result, result.length() - 2, index);
+ }
+
+
+ @Test
+ public void testBuildJarUrl02() throws MalformedURLException {
+ File jarFile = new File("/patha/pathb*/pathc");
+ String result = UriUtil.buildJarUrl(jarFile).toString();
+
+ int index = result.indexOf("!/");
+ Assert.assertEquals(result, result.length() - 2, index);
+
+ index = result.indexOf("*/");
+ Assert.assertEquals(result, -1, index);
+ }
+
+
+ @Test
+ public void testBuildJarUrl03() throws MalformedURLException {
+ File jarFile = new File("/patha/pathb^/pathc");
+ String result = UriUtil.buildJarUrl(jarFile).toString();
+
+ int index = result.indexOf("!/");
+ Assert.assertEquals(result, result.length() - 2, index);
+
+ index = result.indexOf("^/");
+ Assert.assertEquals(result, -1, index);
+ }
+
+
+ // @Test /* Uncomment to test performance for different implementations. */
+ public void performanceTestBuildJarUrl() throws MalformedURLException {
+ File jarFile = new File("/patha/pathb^/pathc");
+
+ URL url = null;
+
+ int count = 1000000;
+
+ // Warm up
+ for (int i = 0; i < count / 10; i++) {
+ url = UriUtil.buildJarUrl(jarFile);
+ }
+
+ // Test
+ long start = System.nanoTime();
+ for (int i = 0; i < count / 10; i++) {
+ url = UriUtil.buildJarUrl(jarFile);
+ }
+ long duration = System.nanoTime() - start;
+
+ System.out.println("[" + count + "] iterations took [" +
+ duration + "] ns for [" + url + "]");
+ }
+}
diff -Nru tomcat7-7.0.68/test/org/apache/tomcat/websocket/server/TestCloseBug58264.java tomcat7-7.0.69/test/org/apache/tomcat/websocket/server/TestCloseBug58264.java
--- tomcat7-7.0.68/test/org/apache/tomcat/websocket/server/TestCloseBug58264.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat7-7.0.69/test/org/apache/tomcat/websocket/server/TestCloseBug58264.java 2016-02-23 15:00:53.000000000 +0000
@@ -0,0 +1,134 @@
+/*
+ * 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 org.apache.tomcat.websocket.server;
+
+import java.net.URI;
+
+import javax.servlet.ServletContextEvent;
+import javax.websocket.ClientEndpoint;
+import javax.websocket.CloseReason;
+import javax.websocket.ContainerProvider;
+import javax.websocket.DeploymentException;
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+import javax.websocket.server.ServerContainer;
+import javax.websocket.server.ServerEndpointConfig;
+
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+
+public class TestCloseBug58264 extends TomcatBaseTest {
+
+ @Test
+ public void testOnErrorNotCalledWhenClosingConnection() throws Throwable {
+ Tomcat tomcat = getTomcatInstance();
+ // No file system docBase required
+ Context ctx = tomcat.addContext("", null);
+ ctx.addApplicationListener(Bug58624ServerConfig.class.getName());
+ Tomcat.addServlet(ctx, "default", new DefaultServlet());
+ ctx.addServletMapping("/", "default");
+
+ WebSocketContainer wsContainer = ContainerProvider.getWebSocketContainer();
+
+ tomcat.start();
+
+ Bug58624ClientEndpoint client = new Bug58624ClientEndpoint();
+ URI uri = new URI("ws://localhost:" + getPort() + Bug58624ServerConfig.PATH);
+
+ Session session = wsContainer.connectToServer(client, uri);
+ session.close();
+
+ if (client.getError() != null) {
+ throw client.getError();
+ }
+ }
+
+ @ClientEndpoint
+ public class Bug58624ClientEndpoint {
+
+ private volatile Throwable t;
+
+
+ @OnError
+ public void onError(Throwable t) {
+ this.t = t;
+ }
+
+
+ public Throwable getError() {
+ return this.t;
+ }
+ }
+
+ public static class Bug58624ServerConfig extends WsContextListener {
+
+ public static String PATH = "/bug58624";
+
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ super.contextInitialized(sce);
+
+ ServerContainer sc = (ServerContainer) sce.getServletContext().getAttribute(
+ Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
+
+ ServerEndpointConfig sec = ServerEndpointConfig.Builder.create(
+ Bug58624ServerEndpoint.class, PATH).build();
+
+ try {
+ sc.addEndpoint(sec);
+ } catch (DeploymentException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static class Bug58624ServerEndpoint {
+
+ @OnOpen
+ public void onOpen() {
+ System.out.println("Session opened");
+ }
+
+
+ @OnMessage
+ public void onMessage(@SuppressWarnings("unused") Session session, String message) {
+ System.out.println("Received message " + message);
+ }
+
+
+ @OnError
+ public void onError(Throwable t) {
+ System.out.println("HERE");
+ t.printStackTrace();
+ }
+
+
+ @OnClose
+ public void onClose(CloseReason cr) {
+ System.out.println("Session closed: " + cr);
+ }
+ }
+}
diff -Nru tomcat7-7.0.68/webapps/docs/building.xml tomcat7-7.0.69/webapps/docs/building.xml
--- tomcat7-7.0.68/webapps/docs/building.xml 2015-08-18 17:49:57.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/building.xml 2016-02-23 22:23:52.000000000 +0000
@@ -119,12 +119,9 @@
- By default the build is configured to download dependencies into directory
- /usr/share/java. On a typical Linux or MacOX system, an ordinary
- user will not have access to write to this directory, and, even if you do,
- it is likely not appropriate for you to write there. On Windows this usually
- corresponds to the C:\usr\share\java directory, unless Cygwin is
- used.
+ 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.
diff -Nru tomcat7-7.0.68/webapps/docs/changelog.xml tomcat7-7.0.69/webapps/docs/changelog.xml
--- tomcat7-7.0.68/webapps/docs/changelog.xml 2016-02-04 11:59:55.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/changelog.xml 2016-04-11 07:27:16.000000000 +0000
@@ -57,7 +57,253 @@
They eventually become mixed with the numbered issues. (I.e., numbered
issues do not "pop up" wrt. others).
-->
-
+
+
+
+
+ Fix the type of InstanceManager attribute of mbean
+ definition of StandardContext. (kfujino)
+
+
+ 58351: Make the server build date and server version number
+ accessible via JMX. Patch provided by Huxing Zhang. (markt)
+
+
+ 59001: Correctly handle the case when Tomcat is installed on
+ a path where one of the segments ends in an exclamation mark. (markt)
+
+
+ Expand the fix for 59001 to cover the special sequences used
+ in Tomcat's custom jar:war: URLs. (markt)
+
+
+ 59043: Avoid warning while expiring sessions associated with
+ a single sign on if HttpServletRequest.logout() is used.
+ (markt)
+
+
+ 59054: Ensure that using the
+ CrawlerSessionManagerValve in a distributed environment
+ does not trigger an error when the Valve registers itself in the
+ session. (markt)
+
+
+ Log a warning message if a user tries to configure the default session
+ timeout via the deprecated (and ignored)
+ Manager.setMaxInactiveInterval() method. (markt)
+
+
+ Correct a regression introduced in 7.0.68 where the deprecated
+ Manager.getMaxInactiveInterval() method returned the
+ current default session timeout in minutes rather than seconds. (markt)
+
+
+ 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)
+
+
+ 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)
+
+
+ 59123: Close NamingEnumeration objects used by
+ the JNDIRealm once they are no longer required.
+ (fschumacher/markt)
+
+
+ 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)
+
+
+ 59145: Don't log an invalid warning when a user logs out of
+ a session associated with SSO. (markt)
+
+
+ 59151: Fix a regression in the fix for 56917 that
+ added additional (and arguably unnecessary) validation to the provided
+ redirect location. (markt)
+
+
+ 59206: Ensure NPE will not be thrown by
+ o.a.tomcat.util.file.ConfigFileLoader when
+ catalina.base is not specified. (violetagg)
+
+
+ 59213: Async dispatches should be based off a wrapped request.
+ (remm)
+
+
+ 59217: Remove duplication in the recycling of the path in
+ o.a.tomcat.util.http.ServerCookie. Patch is provided by
+ Kyohei Nakamura. (violetagg)
+
+
+ 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)
+
+
+ Clarify the log message that specifying both urlPatterns and value
+ attributes in WebServlet and WebFilter annotations is not allowed.
+ (violetagg)
+
+
+ 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)
+
+
+ 59247: Preload ResourceEntry as a workaround for security
+ manager issues on some JVMs. (kkolinko/remm)
+
+
+ 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)
+
+
+
+
+
+
+ 58646: Correct a problem with sendfile that resulted in a
+ Processor being added to the cache twice leading to broken responses.
+ (markt)
+
+
+ 59015: Fix potential cause of endless APR Poller loop during
+ shutdown if the Poller experiences an error during the shutdown process.
+ (markt)
+
+
+ Limit the default TLS ciphers for JSSE (BIO, NIO) and OpenSSL (APR) to
+ those currently considered secure. (markt)
+
+
+ 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. (markt)
+
+
+
+
+
+
+ 59014: Ensure that a WebSocket close message can be sent
+ after a close message has been received. (markt)
+
+
+ Correctly handle compression of partial messages when the final message
+ fragment has a zero length payload. (markt)
+
+
+ Extend the WebSocket programmatic echo endpoint provided in the examples
+ to handle binary messages and also partial messages. This aligns the
+ code with Tomcat 8 and makes it easier to run the Autobahn testsuite
+ against the WebSocket implementation. (markt)
+
+
+ 59119: Correct read logic for WebSocket client when using
+ secure connections. (markt)
+
+
+ 59134: Correct client connect logic for secure connections
+ made through a proxy. (markt)
+
+
+ 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)
+
+
+
+
+
+
+ Correct the description of the
+ ServletRequest.getServerPort() in Proxy How-To.
+ Issue reported via comments.apache.org. (violetagg)
+
+
+ Fix a potential indefinite wait in the Comet Chat servlet in the
+ examples web application. (markt)
+
+
+ 59229: Fix error in HTTP docs and make clear the the HTTP NIO
+ connector uses non-blocking I/O to read the HTTP request headers.
+ (markt)
+
+
+ Update in the documentation the link to the maven repository where
+ Tomcat snapshot artifacts are deployed. (markt/violetagg)
+
+
+ Clarify in the documentation that calls to
+ ServletContext.log(String, Throwable) or
+ GenericServlet.log(String, Throwable) are logged at the
+ SEVERE level. (violetagg)
+
+
+
+
+
+
+ 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)
+
+
+ Avoid NPE when a proxy node failed to retrieve a backup entry. (kfujino)
+
+
+ Add log of when received an unexpected messages. (kfujino)
+
+
+ Add the flag indicating that member is a localMember. (kfujino)
+
+
+
+
+
+
+ 58283: Change the default download location for libraries
+ during the build process from /usr/share/java to
+ ${user.home}/tomcat-build-libs. Patch provided by
+ Ahmed Hosni. (markt)
+
+
+ 59031: When using the Windows uninstaller, do not remove the
+ contents of any directories that have been symlinked into the Tomcat
+ directory structure. (markt)
+
+
+ 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)
+
+
+ 59211: Add hamcrest to Eclipse classpath. Patch is provided
+ by Huxing Zhang. (violetagg)
+
+
+ 59280: Update the NSIS Installer used to build the
+ Windows Installers to version 2.51. (kkolinko)
+
+
+
+
+
@@ -169,7 +415,7 @@
Extend the feature available in the cluster session manager
implementations that enables session attribute replication to be
- filtered bases on attribute name to all session manager implementations.
+ 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
diff -Nru tomcat7-7.0.68/webapps/docs/config/ajp.xml tomcat7-7.0.69/webapps/docs/config/ajp.xml
--- tomcat7-7.0.68/webapps/docs/config/ajp.xml 2016-01-27 11:42:26.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/config/ajp.xml 2016-03-30 10:58:45.000000000 +0000
@@ -180,7 +180,7 @@
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 based connector will be used.
+ found, the Java BIO 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
diff -Nru tomcat7-7.0.68/webapps/docs/config/cluster-manager.xml tomcat7-7.0.69/webapps/docs/config/cluster-manager.xml
--- tomcat7-7.0.68/webapps/docs/config/cluster-manager.xml 2016-01-27 13:13:20.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/config/cluster-manager.xml 2016-03-10 07:00:08.000000000 +0000
@@ -84,6 +84,8 @@
this value to true. Default value is false.
+
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,
diff -Nru tomcat7-7.0.68/webapps/docs/config/http.xml tomcat7-7.0.69/webapps/docs/config/http.xml
--- tomcat7-7.0.68/webapps/docs/config/http.xml 2015-11-11 09:55:51.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/config/http.xml 2016-03-31 15:52:41.000000000 +0000
@@ -987,12 +987,12 @@
The comma separated list of encryption ciphers to support for HTTPS
connections. If specified, only the ciphers that are listed and supported
by the SSL implementation will be used. By default, the default ciphers
- for the JVM will be used. Note that this usually means that the weak
- export grade ciphers will be included in the list of available ciphers.
- 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.
+ for the JVM will be used less those considered to be insecure. Note that
+ with older JVMs this will result in a very limited set of ciphers being
+ available by default. 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.
@@ -1259,9 +1259,8 @@
Ciphers which may be used for communicating with clients. The default
- is "ALL", with other acceptable values being a list of ciphers, with ":"
- used as the delimiter (see OpenSSL documentation for the list of ciphers
- supported).
+ is "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA". See the OpenSSL
+ documentation for details of the cipher configuration options.
@@ -1329,9 +1328,9 @@
Tomcat Version 3.x onwards 6.x onwards 5.5.x onwards
Support Polling NO YES YES
Polling Size N/A maxConnections maxConnections
- Read HTTP Request Blocking Blocking Blocking
- Read HTTP Body Blocking Blocking Blocking
- Write HTTP Response Blocking Blocking Blocking
+ Read Request Headers Blocking Non Blocking Blocking
+ Read Request Body Blocking Blocking Blocking
+ Write Response Blocking Blocking Blocking
Wait for next Request Blocking Non Blocking Non Blocking
SSL Support Java SSL Java SSL OpenSSL
SSL Handshake Blocking Non blocking Blocking
diff -Nru tomcat7-7.0.68/webapps/docs/config/manager.xml tomcat7-7.0.69/webapps/docs/config/manager.xml
--- tomcat7-7.0.68/webapps/docs/config/manager.xml 2016-01-27 13:13:20.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/config/manager.xml 2016-04-06 20:27:42.000000000 +0000
@@ -254,21 +254,21 @@
-
The time interval (in seconds) since the last access to a session
- before it should be persisted to the session store, and
- passivated out of the server's memory, or -1 to disable
- this feature. 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.
+
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.
-
The time interval (in seconds) since the last access to a session
- before it will be eligible to be persisted to the session store, and
- passivated out of the server's memory, or -1 for this
- swapping to be available at any time. If specified, this value should
- be less than that specified by maxIdleSwap. By default,
- this value is set to -1.
+
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.
diff -Nru tomcat7-7.0.68/webapps/docs/logging.xml tomcat7-7.0.69/webapps/docs/logging.xml
--- tomcat7-7.0.68/webapps/docs/logging.xml 2015-08-11 19:37:04.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/logging.xml 2016-04-06 10:40:30.000000000 +0000
@@ -139,7 +139,7 @@
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 ERROR level.
+ are logged at the SEVERE level.
diff -Nru tomcat7-7.0.68/webapps/docs/maven-jars.xml tomcat7-7.0.69/webapps/docs/maven-jars.xml
--- tomcat7-7.0.68/webapps/docs/maven-jars.xml 2011-11-10 04:15:34.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/maven-jars.xml 2016-04-04 18:35:34.000000000 +0000
@@ -36,8 +36,8 @@
Tomcat snapshots are located in the
- Apache Snapshot Repository.
- The official URL is
+ Apache Snapshot Repository.
+ The official URL is
Snapshots are done periodically, not on a regular basis, but when changes happen and the Tomcat team deems a new snapshot might
useful.
diff -Nru tomcat7-7.0.68/webapps/docs/proxy-howto.xml tomcat7-7.0.69/webapps/docs/proxy-howto.xml
--- tomcat7-7.0.68/webapps/docs/proxy-howto.xml 2014-01-26 22:13:11.000000000 +0000
+++ tomcat7-7.0.69/webapps/docs/proxy-howto.xml 2016-03-09 08:31:26.000000000 +0000
@@ -44,7 +44,7 @@
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 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.