This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit af28c93c987a0e8be77bc8ab8214dd82e4be73ab Author: opencode <[email protected]> AuthorDate: Mon Oct 12 23:25:27 2026 +0200 Use the hexadecimal request ID format from recycle() for new requests The request ID of a new coyote Request was initialised with a decimal representation while recycle() generated the identifier for every subsequent request on a recycled instance in hexadecimal. The request ID is exposed to web applications through the standard Servlet getRequestId() API, so the first request served by a given request instance had a decimal ID while all later requests on the same instance had hexadecimal IDs, giving an unstable ID format that varied per worker thread. Switch the initialiser to the hexadecimal format. That format is the intended one. The switch to base 16 for the identifiers introduced with the Servlet connection and request ID API covered the value generated on recycle as well as the connection ID, but missed the field initialiser. No server-side component parses the request ID and the Servlet specification defines no format for it, so only applications that pattern-match the ID are affected, and they now observe a single consistent format. Add a regression test that advances the shared identifier generator to a value where the hexadecimal and decimal representations differ and then verifies that the initial ID of a new request continues the hexadecimal sequence. --- java/org/apache/coyote/Request.java | 3 ++- test/org/apache/coyote/TestRequest.java | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/java/org/apache/coyote/Request.java b/java/org/apache/coyote/Request.java index 3b4054ff4a..a09e0000fc 100644 --- a/java/org/apache/coyote/Request.java +++ b/java/org/apache/coyote/Request.java @@ -102,7 +102,8 @@ public final class Request { private final MessageBytes queryMB = MessageBytes.newInstance(); private final MessageBytes protoMB = MessageBytes.newInstance(); - private volatile String requestId = Long.toString(requestIdGenerator.getAndIncrement()); + // The hexadecimal format here matches the identifiers generated in recycle() + private volatile String requestId = Long.toHexString(requestIdGenerator.getAndIncrement()); // remote address/host private final MessageBytes remoteAddrMB = MessageBytes.newInstance(); diff --git a/test/org/apache/coyote/TestRequest.java b/test/org/apache/coyote/TestRequest.java index f3b915e0d5..7be14c088f 100644 --- a/test/org/apache/coyote/TestRequest.java +++ b/test/org/apache/coyote/TestRequest.java @@ -19,6 +19,7 @@ package org.apache.coyote; import java.io.IOException; import java.nio.ByteBuffer; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -153,6 +154,24 @@ public class TestRequest { } + @Test + public void testRequestIdFormatConsistency() { + // Recycle the request until the generated identifier has a value for + // which the hexadecimal and decimal representations differ + String recycledId; + do { + request.markStartTime(); + request.recycle(); + recycledId = request.getRequestId(); + } while (recycledId.length() == 1 && Long.parseLong(recycledId, 16) < 10); + + // The initial identifier of a new request must use the same + // hexadecimal representation as the identifiers generated on recycle + Request newRequest = new Request(); + Assert.assertEquals(Long.toHexString(Long.parseLong(recycledId, 16) + 1), newRequest.getRequestId()); + } + + private void configureMockForOneAcknowledgementWrite(SocketWrapperBase<?> socketWrapper) throws IOException { EasyMock.reset(socketWrapper); socketWrapper.write(true, Constants.ACK_BYTES, 0, Constants.ACK_BYTES.length); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
