From e86dc10ed661277ec4a77eec954fc3d601546867 Mon Sep 17 00:00:00 2001 From: Flavia Rainone Date: Sun, 23 Apr 2023 00:56:20 -0300 Subject: [PATCH 1/2] Investigate failure on Windows Signed-off-by: Flavia Rainone --- .github/workflows/ci.yml | 4 +-- .../protocol/http/HttpResponseConduit.java | 22 +++++++++++++- .../LotsOfHeadersResponseTestCase.java | 29 ++++++++++++------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7fc3250d2..03fc1dbc10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [windows-latest] module: [core] jdk: [17, 21] openjdk_impl: [ temurin ] @@ -121,7 +121,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - module: [core, servlet, websockets-jsr] + module: [core] #, servlet, websockets-jsr] proxy: ['-Pproxy', ''] jdk: [17] steps: diff --git a/core/src/main/java/io/undertow/server/protocol/http/HttpResponseConduit.java b/core/src/main/java/io/undertow/server/protocol/http/HttpResponseConduit.java index f8fdfe916c..c63fdfc7b7 100644 --- a/core/src/main/java/io/undertow/server/protocol/http/HttpResponseConduit.java +++ b/core/src/main/java/io/undertow/server/protocol/http/HttpResponseConduit.java @@ -18,6 +18,7 @@ package io.undertow.server.protocol.http; +import io.undertow.UndertowLogger; import io.undertow.UndertowMessages; import io.undertow.connector.ByteBufferPool; import io.undertow.connector.PooledByteBuffer; @@ -133,7 +134,7 @@ private int processWrite(int state, final Object userData, int pos, int length) try { assert state != STATE_BODY; if (state == STATE_BUF_FLUSH) { - buffer = pooledBuffer.getBuffer(); + buffer = getOrAllocateBuffer();//pooledBuffer.getBuffer(); do { long res = 0; ByteBuffer[] data; @@ -162,6 +163,7 @@ private int processWrite(int state, final Object userData, int pos, int length) } while (buffer.hasRemaining()); return STATE_BODY; } else if (state != STATE_START) { + buffer = getOrAllocateBuffer(); return processStatefulWrite(state, userData, pos, length); } // make sure that headers are written only once. if @@ -234,6 +236,7 @@ private int processWrite(int state, final Object userData, int pos, int length) this.charIndex = 0; this.state = STATE_HDR_NAME; buffer.flip(); + UndertowLogger.ROOT_LOGGER.info("WRITING " + header); return processStatefulWrite(STATE_HDR_NAME, userData, pos, length); } header.appendTo(buffer); @@ -249,6 +252,7 @@ private int processWrite(int state, final Object userData, int pos, int length) this.charIndex = 0; this.state = STATE_HDR_VAL; buffer.flip(); + UndertowLogger.ROOT_LOGGER.info("WRITING2 " + header); return processStatefulWrite(STATE_HDR_VAL, userData, pos, length); } writeString(buffer, string); @@ -325,6 +329,17 @@ public void freeContinueResponse() { } } + private ByteBuffer getOrAllocateBuffer() { + // allocate pooled buffer + if (pooledBuffer == null) { + pooledBuffer = pool.allocate(); + } + // set the state after successfully allocating... so in case something goes bad + // we don't have a dangling flag that won't be cleared at the finally block + this.state |= POOLED_BUFFER_IN_USE; + return pooledBuffer.getBuffer(); + } + private static void writeString(ByteBuffer buffer, String string) { int length = string.length(); for (int charIndex = 0; charIndex < length; charIndex++) { @@ -344,6 +359,10 @@ private static void writeString(ByteBuffer buffer, String string) { */ private int processStatefulWrite(int state, final Object userData, int pos, int len) throws IOException { ByteBuffer buffer = pooledBuffer.getBuffer(); + // set the state after successfully allocating... so in case something goes bad + // we don't have a dangling flag that won't be cleared at the finally block + this.state |= POOLED_BUFFER_IN_USE; + long fiCookie = this.fiCookie; int valueIdx = this.valueIdx; int charIndex = this.charIndex; @@ -367,6 +386,7 @@ private int processStatefulWrite(int state, final Object userData, int pos, int switch (state) { case STATE_HDR_NAME: { final HttpString headerName = headerValues.getHeaderName(); + //UndertowLogger.ROOT_LOGGER.info("PROCESSING " + headerName); length = headerName.length(); while (charIndex < length) { if (buffer.hasRemaining()) { diff --git a/core/src/test/java/io/undertow/server/handlers/LotsOfHeadersResponseTestCase.java b/core/src/test/java/io/undertow/server/handlers/LotsOfHeadersResponseTestCase.java index 1d7d3d3b12..64f8426b2b 100644 --- a/core/src/test/java/io/undertow/server/handlers/LotsOfHeadersResponseTestCase.java +++ b/core/src/test/java/io/undertow/server/handlers/LotsOfHeadersResponseTestCase.java @@ -18,12 +18,12 @@ package io.undertow.server.handlers; +import io.undertow.UndertowLogger; import io.undertow.protocols.http2.Http2Channel; -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; import io.undertow.testutils.AjpIgnore; import io.undertow.testutils.DefaultServer; import io.undertow.testutils.TestHttpClient; +import io.undertow.util.HeaderValues; import io.undertow.util.HttpString; import io.undertow.util.StatusCodes; import org.apache.http.Header; @@ -36,6 +36,7 @@ import org.junit.runner.RunWith; import java.io.IOException; +import java.util.Iterator; /** * @author Stuart Douglas @@ -55,20 +56,20 @@ public static void setup() { Assume.assumeNotNull(System.getProperty(Http2Channel.HTTP2_MAX_HEADER_SIZE_PROPERTY)); final BlockingHandler blockingHandler = new BlockingHandler(); DefaultServer.setRootHandler(blockingHandler); - blockingHandler.setRootHandler(new HttpHandler() { - @Override - public void handleRequest(final HttpServerExchange exchange) { - for (int i = 0; i < COUNT; ++i) { - exchange.getResponseHeaders().put(HttpString.tryFromString(HEADER + i), MESSAGE + i); - } + blockingHandler.setRootHandler(exchange -> { + for (int i = 0; i < COUNT; ++i) { + exchange.getResponseHeaders().put(HttpString.tryFromString(HEADER + i), MESSAGE + i); + } + for (Iterator it = exchange.getResponseHeaders().iterator(); it.hasNext(); ) { + HeaderValues headerValues = it.next(); + UndertowLogger.ROOT_LOGGER.info("HEADER AT SERVER SIDE: " + headerValues.getHeaderName() + ": " + headerValues.getFirst()); } }); } @Test public void testLotsOfHeadersInResponse() throws IOException { - // FIXME UNDERTOW-2279 - Assume.assumeFalse(System.getProperty("os.name").startsWith("Windows")); + Assert.assertTrue(System.getProperty("os.name").startsWith("Windows")); TestHttpClient client = new TestHttpClient(); try { HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/path"); @@ -77,6 +78,14 @@ public void testLotsOfHeadersInResponse() throws IOException { for (int i = 0; i < COUNT; ++i) { Header[] header = result.getHeaders(HEADER + i); if (header.length == 0) { + UndertowLogger.ROOT_LOGGER.info("HEADERS AT CLIENT SIDE, THERE IS A TOTAL OF HEADERS: " + result.getAllHeaders().length); + for (Header listedHeader: result.getAllHeaders()) { + + UndertowLogger.ROOT_LOGGER.info("HEADER: " + listedHeader.getName() + ": " + listedHeader.getValue()); + } + if (result.getAllHeaders().length == 0) { + UndertowLogger.ROOT_LOGGER.info("No header found"); + } Assert.fail("Header " + HEADER + i + " not found"); } Assert.assertEquals(MESSAGE + i, header[0].getValue()); From f8b44ba400e26a9bdd23fb0b3f1ea7ee1a42b04d Mon Sep 17 00:00:00 2001 From: Flavia Rainone Date: Sat, 18 Oct 2025 12:45:30 -0300 Subject: [PATCH 2/2] WIP: try only Windows Signed-off-by: Flavia Rainone --- .github/workflows/ci.yml | 52 ---------------------------------------- 1 file changed, 52 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03fc1dbc10..6763eab30a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,55 +113,3 @@ jobs: path: | **/surefire*-reports/*.txt **/*.dump* - test-matrix-ipv6: - name: JDK ${{ matrix.jdk }} - ipv6 - ${{ matrix.module }} ${{ matrix.proxy && '- proxy' || '' }} - ${{ matrix.os }} - runs-on: ${{ matrix.os }} - needs: build-all - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - module: [core] #, servlet, websockets-jsr] - proxy: ['-Pproxy', ''] - jdk: [17] - steps: - - name: Update hosts - linux - if: matrix.os == 'ubuntu-latest' - run: | - sudo bash -c "echo '127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4' > /etc/hosts" - sudo bash -c "echo '::1 localhost localhost.localdomain localhost6 localhost6.localdomain6' >> /etc/hosts" - sudo sysctl -w fs.file-max=2097152 - - uses: n1hility/cancel-previous-runs@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - name: Host information - run: | - hostname || true - - uses: actions/checkout@v4 - - name: Download Maven Repo - uses: actions/download-artifact@v4 - with: - name: maven-repo - path: . - - name: Extract Maven Repo - shell: bash - run: tar -xzf maven-repo.tgz -C ~ - - name: Set up JDK ${{ matrix.java }} - uses: joschi/setup-jdk@v2 - with: - java-version: ${{ matrix.jdk }} - - name: Generate settings.xml for Maven Builds - uses: whelk-io/maven-settings-xml-action@v21 - with: - repositories: '[{ "id": "jboss", "name": "JBoss", "url": "https://repository.jboss.org/nexus/content/groups/public" }]' - - name: Print Version - run: mvn -v - - name: Run Tests - run: mvn -U -B -fae test ${{ matrix.proxy && '-Pproxy' || '' }} '-DfailIfNoTests=false' -pl ${{ matrix.module }} -Dtest.ipv6=true - - uses: actions/upload-artifact@v4 - if: failure() - with: - name: surefire-reports-${{ matrix.jdk }}-ipv6-${{ matrix.module }}${{ matrix.proxy }}-${{ matrix.os }} - path: | - **/surefire*-reports/*.txt - **/*.dump*