This is an automated email from the ASF dual-hosted git repository. dsoumis pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 0b864af9aa2f780562f1bd79b7eee31280db8d3d Author: Dimitris Soumis <[email protected]> AuthorDate: Thu Feb 19 19:07:07 2026 +0200 Add TestSessionWithProxy --- .../apache/catalina/startup/TomcatBaseTest.java | 6 +- .../integration/httpd/TestSessionWithProxy.java | 117 +++++++++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/test/org/apache/catalina/startup/TomcatBaseTest.java b/test/org/apache/catalina/startup/TomcatBaseTest.java index 21f744647a..eb1e320a86 100644 --- a/test/org/apache/catalina/startup/TomcatBaseTest.java +++ b/test/org/apache/catalina/startup/TomcatBaseTest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; +import java.io.Serial; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URI; @@ -466,6 +467,7 @@ public abstract class TomcatBaseTest extends LoggingBaseTest { */ public static final class SnoopServlet extends HttpServlet { + @Serial private static final long serialVersionUID = 1L; @Override @@ -481,7 +483,7 @@ public abstract class TomcatBaseTest extends LoggingBaseTest { response.setCharacterEncoding("UTF-8"); ServletContext ctx = this.getServletContext(); - HttpSession session = request.getSession(false); + HttpSession session = request.getSession("true".equals(request.getParameter("createSession"))); PrintWriter out = response.getWriter(); out.println("CONTEXT-NAME: " + ctx.getServletContextName()); @@ -558,7 +560,7 @@ public abstract class TomcatBaseTest extends LoggingBaseTest { e.hasMoreElements();) { name = e.nextElement(); value = new StringBuilder(); - String values[] = request.getParameterValues(name); + String[] values = request.getParameterValues(name); int m = values.length; for (int j = 0; j < m; j++) { value.append(values[j]); diff --git a/test/org/apache/tomcat/integration/httpd/TestSessionWithProxy.java b/test/org/apache/tomcat/integration/httpd/TestSessionWithProxy.java new file mode 100644 index 0000000000..a021b741a2 --- /dev/null +++ b/test/org/apache/tomcat/integration/httpd/TestSessionWithProxy.java @@ -0,0 +1,117 @@ +/* + * 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.integration.httpd; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jakarta.servlet.http.HttpServletResponse; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.Valve; +import org.apache.catalina.valves.RemoteIpValve; +import org.apache.tomcat.util.buf.ByteChunk; +import org.apache.tomcat.util.net.TesterSupport; + +public class TestSessionWithProxy extends HttpdIntegrationBaseTest { + private static final String HTTPD_CONFIG = """ + LoadModule proxy_module modules/mod_proxy.so + LoadModule proxy_http_module modules/mod_proxy_http.so + LoadModule headers_module modules/mod_headers.so + LoadModule ssl_module modules/mod_ssl.so + SSLSessionCache none + ProxyPass /endpoint http://localhost:%{TOMCAT_PORT}/%{SERVLET_NAME} + ProxyPassReverse /endpoint http://localhost:%{TOMCAT_PORT}/%{SERVLET_NAME} + Listen %{HTTPD_SSL_PORT} https + <VirtualHost *:%{HTTPD_SSL_PORT}> + ServerName localhost:%{HTTPD_SSL_PORT} + SSLEngine on + SSLCertificateFile "%{SSL_CERT_FILE}" + SSLCertificateKeyFile "%{SSL_KEY_FILE}" + ProxyPass /endpoint http://localhost:%{TOMCAT_PORT}/%{SERVLET_NAME} + ProxyPassReverse /endpoint http://localhost:%{TOMCAT_PORT}/%{SERVLET_NAME} + RequestHeader set X-Forwarded-Proto https + </VirtualHost> + """; + + @Override + protected List<Valve> getValveConfig() { + List<Valve> valves = new ArrayList<>(); + + RemoteIpValve remoteIpValve = new RemoteIpValve(); + valves.add(remoteIpValve); + + return valves; + } + + @Override + protected String getHttpdConfig() { + return HTTPD_CONFIG; + } + + /** + * Verify that a session created through httpd can be retrieved + * on a subsequent request using the session cookie. + */ + @Test + public void testSessionCookieSetAndRetrieved() throws Exception { + // Create a session + ByteChunk res = new ByteChunk(); + Map<String, List<String>> resHead = new HashMap<>(); + int rc = getUrl("http://localhost:" + getHttpdPort() + "/endpoint?createSession=true", res, null, resHead); + Assert.assertEquals(HttpServletResponse.SC_OK, rc); + + RequestDescriptor requestDesc = SnoopResult.parse(res.toString()); + Assert.assertNotNull(requestDesc.getRequestInfo()); + String sessionId = requestDesc.getRequestInfo("SESSION-ID"); + Assert.assertNotNull(sessionId); + Assert.assertEquals("true", requestDesc.getRequestInfo("SESSION-IS-NEW")); + + String setCookie = resHead.get("Set-Cookie").getFirst(); + Assert.assertTrue(setCookie.contains("JSESSIONID")); + + // Send the session cookie back + Map<String, List<String>> reqHead = new HashMap<>(); + reqHead.put("Cookie", List.of("JSESSIONID=" + sessionId)); + rc = getUrl("http://localhost:" + getHttpdPort() + "/endpoint", res, reqHead, null); + Assert.assertEquals(HttpServletResponse.SC_OK, rc); + + requestDesc = SnoopResult.parse(res.toString()); + Assert.assertNotNull(requestDesc.getRequestInfo()); + Assert.assertEquals(sessionId, requestDesc.getRequestInfo("SESSION-ID")); + Assert.assertEquals("false", requestDesc.getRequestInfo("SESSION-IS-NEW")); + } + + /** + * Verify that when SSL is used at httpd, but not Tomcat, and RemoteIpValve + * sets the scheme to https, session cookies have the Secure flag. + */ + @Test + public void testSecureCookieWithSslTermination() throws Exception { + TesterSupport.configureClientSsl(); + ByteChunk res = new ByteChunk(); + Map<String, List<String>> resHead = new HashMap<>(); + getUrl("https://localhost:" + getHttpdSslPort() + "/endpoint?createSession=true", res, null, resHead); + Assert.assertTrue("Session cookie should have Secure flag", resHead.get("Set-Cookie").getFirst().contains("Secure")); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
