[Git][java-team/httpcomponents-core5][upstream] New upstream version 5.4.4
Emmanuel Bourg (@ebourg)
gitlab at salsa.debian.org
Fri Sep 25 19:39:46 BST 2026
Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / httpcomponents-core5
Commits:
d3056127 by Emmanuel Bourg at 2026-09-25T19:17:32+02:00
New upstream version 5.4.4
- - - - -
22 changed files:
- RELEASE_NOTES.txt
- httpcore5-h2/pom.xml
- httpcore5-reactive/pom.xml
- httpcore5-testing/pom.xml
- + httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/Http1BufferSizeBenchmark.java
- httpcore5/pom.xml
- httpcore5/src/main/java/org/apache/hc/core5/http/HttpException.java
- httpcore5/src/main/java/org/apache/hc/core5/http/config/Http1Config.java
- httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractBinAsyncEntityProducer.java
- httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractCharAsyncEntityProducer.java
- httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/DigestingEntityProducer.java
- httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/FileEntityProducer.java
- httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/PathEntityProducer.java
- httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
- httpcore5/src/test/java/org/apache/hc/core5/http/TestHttpExceptions.java
- httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestAbstractBinAsyncEntityProducer.java
- httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestDigestingEntityProducer.java
- httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestFileAsyncEntityProducer.java
- httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestPathAsyncEntityProducer.java
- httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestStringAsyncEntityProducer.java
- httpcore5/src/test/java/org/apache/hc/core5/net/TestURIBuilder.java
- pom.xml
Changes:
=====================================
RELEASE_NOTES.txt
=====================================
@@ -1,3 +1,26 @@
+Release 5.4.4
+------------------
+
+This maintenance release optimizes HTTP/1.1 message buffer configuration and corrects
+the handling of asynchronous entity producer state resets after interrupted writes.
+
+
+Change Log
+-------------------
+
+* HTTPCORE-800: Fixed hexadecimal encoding of control characters in HttpException messages.
+ Contributed by Arturo Bernal <abernal at apache.org>
+
+* HTTPCORE-799: Corrected the handling of asynchronous entity producer state resets after interrupted writes.
+ Contributed by Matthias Kurz <m.kurz at irregular.at>
+
+* Fixed URIBuilder encoding policy documentation and null reset behavior.
+ Contributed by Praful Gupta <prafulgupta6 at gmail.com>
+
+* Increased the default HTTP/1.1 buffer size to 32 KiB.
+ Contributed by Arturo Bernal <abernal at apache.org>
+
+
Release 5.4.3
------------------
@@ -16,7 +39,7 @@ Change Log
Contributed by Ryan Schmitt <rschmitt at apache.org>
* Use max line length of 8192 and max header count of 100 for incoming HTTP/1 messages
- by default.
+ by default. Override with Http1Config.Builder.setMaxLineLength(int) and setMaxHeaderCount(int).
Contributed by Oleg Kalnichevski <olegk at apache.org>
* Enforce configured HPACK header list size limit upon initialization of HTTP/2
=====================================
httpcore5-h2/pom.xml
=====================================
@@ -28,7 +28,7 @@
<parent>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-parent</artifactId>
- <version>5.4.3</version>
+ <version>5.4.4</version>
</parent>
<artifactId>httpcore5-h2</artifactId>
<name>Apache HttpComponents Core HTTP/2</name>
=====================================
httpcore5-reactive/pom.xml
=====================================
@@ -27,7 +27,7 @@
<parent>
<artifactId>httpcore5-parent</artifactId>
<groupId>org.apache.httpcomponents.core5</groupId>
- <version>5.4.3</version>
+ <version>5.4.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
=====================================
httpcore5-testing/pom.xml
=====================================
@@ -28,7 +28,7 @@
<parent>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-parent</artifactId>
- <version>5.4.3</version>
+ <version>5.4.4</version>
</parent>
<artifactId>httpcore5-testing</artifactId>
<name>Apache HttpComponents Core Integration Tests</name>
=====================================
httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/Http1BufferSizeBenchmark.java
=====================================
@@ -0,0 +1,161 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.benchmark;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.config.Http1Config;
+import org.apache.hc.core5.http.impl.bootstrap.AsyncRequesterBootstrap;
+import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
+import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
+import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
+import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
+import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
+import org.apache.hc.core5.http.nio.support.BasicResponseProducer;
+import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.testing.nio.Http1TestServer;
+import org.apache.hc.core5.util.Timeout;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * End-to-end HTTP/1.1 throughput of a large-body GET over loopback, as a function of the
+ * {@link Http1Config} session buffer size. Both the requester and the server are configured with
+ * the same buffer size, so this isolates the effect of the buffer default on large messages.
+ */
+ at BenchmarkMode(Mode.Throughput)
+ at OutputTimeUnit(TimeUnit.SECONDS)
+ at Warmup(iterations = 3, time = 2, timeUnit = TimeUnit.SECONDS)
+ at Measurement(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS)
+// A fixed, generous heap keeps GC out of the measurement: at ~6 K x 1 MB/s the transient garbage
+// otherwise triggers frequent collections whose pauses dominate the run-to-run variance.
+ at Fork(value = 1, jvmArgs = {"-Xms4g", "-Xmx4g"})
+// Client and server run in the same JVM, so keep concurrency at or below the available cores to
+// avoid oversubscription noise; override with JMH -t on larger machines.
+ at Threads(8)
+ at State(Scope.Benchmark)
+public class Http1BufferSizeBenchmark {
+
+ @Param({"8192", "16384", "32768", "65536"})
+ public int bufferSize;
+
+ @Param({"1048576"})
+ public int bodySize;
+
+ private static final Timeout TIMEOUT = Timeout.ofSeconds(60);
+
+ private Http1TestServer server;
+ private HttpAsyncRequester requester;
+ private HttpHost target;
+
+ @Setup(Level.Trial)
+ public void setUp() throws Exception {
+ final Http1Config h1Config = Http1Config.custom().setBufferSize(bufferSize).build();
+ final byte[] body = new byte[bodySize];
+
+ server = new Http1TestServer();
+ server.configure(h1Config);
+ server.register("*", () -> new BasicServerExchangeHandler<>(new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {
+
+ @Override
+ public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(
+ final HttpRequest request, final EntityDetails entityDetails, final HttpContext context) {
+ return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
+ }
+
+ @Override
+ public void handle(
+ final Message<HttpRequest, Void> message, final ResponseTrigger responseTrigger,
+ final HttpContext context) throws HttpException, java.io.IOException {
+ responseTrigger.submitResponse(
+ new BasicResponseProducer(HttpStatus.SC_OK,
+ AsyncEntityProducers.create(body, ContentType.APPLICATION_OCTET_STREAM)),
+ context);
+ }
+ }));
+ final InetSocketAddress address = server.start();
+
+ requester = AsyncRequesterBootstrap.bootstrap()
+ .setIOReactorConfig(IOReactorConfig.custom().setSoTimeout(TIMEOUT).build())
+ .setHttp1Config(h1Config)
+ .setMaxTotal(300)
+ .setDefaultMaxPerRoute(300)
+ .create();
+ requester.start();
+ target = new HttpHost("http", "localhost", address.getPort());
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ if (requester != null) {
+ requester.close(CloseMode.GRACEFUL);
+ }
+ if (server != null) {
+ server.close();
+ }
+ }
+
+ @Benchmark
+ public long getLargeBody() throws Exception {
+ final Future<Message<HttpResponse, Void>> future = requester.execute(
+ new BasicRequestProducer(Method.GET, target, "/"),
+ new BasicResponseConsumer<>(new DiscardingEntityConsumer<Void>()),
+ TIMEOUT, null);
+ final Message<HttpResponse, Void> message = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
+ return message.getHead().getCode();
+ }
+
+}
=====================================
httpcore5/pom.xml
=====================================
@@ -28,7 +28,7 @@
<parent>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-parent</artifactId>
- <version>5.4.3</version>
+ <version>5.4.4</version>
</parent>
<artifactId>httpcore5</artifactId>
<name>Apache HttpComponents Core HTTP/1.1</name>
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/HttpException.java
=====================================
@@ -60,7 +60,7 @@ public class HttpException extends Exception {
final char ch = chars[i];
if (ch < FIRST_VALID_CHAR) {
builder.append("[0x");
- final String hexString = Integer.toHexString(i);
+ final String hexString = Integer.toHexString(ch);
if (hexString.length() == 1) {
builder.append("0");
}
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/config/Http1Config.java
=====================================
@@ -141,7 +141,9 @@ public class Http1Config {
}
private static final int INIT_WINDOW_SIZE = 65535;
- private static final int INIT_BUF_SIZE = 8192;
+ // Larger session buffers cut the number of read/write events on large messages; the gain
+ // levels off past 32 KB while per-connection footprint keeps growing, so 32 KB is the default.
+ private static final int INIT_BUF_SIZE = 32 * 1024;
private static final Timeout INIT_WAIT_FOR_CONTINUE = Timeout.ofSeconds(3);
private static final int INIT_BUF_CHUNK = -1;
private static final int INIT_MAX_HEADER_COUNT = 100;
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractBinAsyncEntityProducer.java
=====================================
@@ -223,6 +223,7 @@ public abstract class AbstractBinAsyncEntityProducer implements AsyncEntityProdu
@Override
public void releaseResources() {
state = State.ACTIVE;
+ byteBuffer.clear();
}
}
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractCharAsyncEntityProducer.java
=====================================
@@ -245,6 +245,7 @@ public abstract class AbstractCharAsyncEntityProducer implements AsyncEntityProd
@Override
public void releaseResources() {
state = State.ACTIVE;
+ bytebuf.clear();
charsetEncoder.reset();
}
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/DigestingEntityProducer.java
=====================================
@@ -155,6 +155,7 @@ public class DigestingEntityProducer implements AsyncEntityProducer {
@Override
public void releaseResources() {
+ digester.reset();
wrapped.releaseResources();
}
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/FileEntityProducer.java
=====================================
@@ -155,6 +155,7 @@ public final class FileEntityProducer implements AsyncEntityProducer {
@Override
public void releaseResources() {
eof = false;
+ byteBuffer.clear();
Closer.closeQuietly(accessFileRef.getAndSet(null));
}
=====================================
httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/PathEntityProducer.java
=====================================
@@ -161,6 +161,7 @@ public final class PathEntityProducer implements AsyncEntityProducer {
@Override
public void releaseResources() {
eof = false;
+ byteBuffer.clear();
Closer.closeQuietly(channelRef.getAndSet(null));
}
=====================================
httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
=====================================
@@ -207,7 +207,7 @@ public class URIBuilder {
* Sets the encoding policy for this {@link URIBuilder}.
* The encoding policy determines how URI components (e.g., query, fragment) are
* percent-encoded when building the URI string. If not set, the default policy
- * is {@link EncodingPolicy#RFC_3986}.
+ * is {@link EncodingPolicy#ALL_RESERVED}.
*
* @param encodingPolicy the encoding policy to apply, or {@code null} to reset
* to the default ({@link EncodingPolicy#ALL_RESERVED})
@@ -215,7 +215,7 @@ public class URIBuilder {
* @since 5.4
*/
public URIBuilder setEncodingPolicy(final EncodingPolicy encodingPolicy) {
- this.encodingPolicy = encodingPolicy;
+ this.encodingPolicy = encodingPolicy != null ? encodingPolicy : EncodingPolicy.ALL_RESERVED;
return this;
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/http/TestHttpExceptions.java
=====================================
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.Test;
*/
class TestHttpExceptions {
- private static final String CLEAN_MESSAGE = "[0x00]Hello[0x06][0x07][0x08][0x09][0x0a][0x0b][0x0c][0x0d][0x0e][0x0f]World";
+ private static final String CLEAN_MESSAGE = "[0x01]Hello[0x01][0x02][0x03][0x04][0x05][0x06][0x07][0x08][0x09][0x00]World";
private static final String nonPrintableMessage = String.valueOf(
new char[] { 1, 'H', 'e', 'l', 'l', 'o', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'W', 'o', 'r', 'l', 'd' });
@@ -86,4 +86,18 @@ class TestHttpExceptions {
Assertions.assertEquals(CLEAN_MESSAGE, new UnsupportedHttpVersionException(nonPrintableMessage).getMessage());
}
+
+ @Test
+ void testControlCharacterEscaping() {
+ final HttpException exception = new HttpException("0123456789abcdef\nsuffix");
+
+ Assertions.assertEquals("0123456789abcdef[0x0a]suffix", exception.getMessage());
+ }
+
+ @Test
+ void testControlCharacterEncodingIndependentOfPosition() {
+ Assertions.assertEquals("a[0x0a]b", new HttpException("a\nb").getMessage());
+ Assertions.assertEquals("0123456789abcdef[0x0a]b", new HttpException("0123456789abcdef\nb").getMessage());
+ }
+
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestAbstractBinAsyncEntityProducer.java
=====================================
@@ -82,6 +82,48 @@ class TestAbstractBinAsyncEntityProducer {
}
+ static private class RepeatableByteAsyncEntityProducer extends AbstractBinAsyncEntityProducer {
+
+ private final ByteBuffer content;
+
+ public RepeatableByteAsyncEntityProducer(
+ final int fragmentSizeHint,
+ final ContentType contentType,
+ final byte[] content) {
+ super(fragmentSizeHint, contentType);
+ this.content = ByteBuffer.wrap(content);
+ }
+
+ @Override
+ public boolean isRepeatable() {
+ return true;
+ }
+
+ @Override
+ protected int availableData() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ protected void produceData(final StreamChannel<ByteBuffer> channel) throws IOException {
+ channel.write(content);
+ if (!content.hasRemaining()) {
+ channel.endStream();
+ }
+ }
+
+ @Override
+ public void failed(final Exception cause) {
+ }
+
+ @Override
+ public void releaseResources() {
+ content.clear();
+ super.releaseResources();
+ }
+
+ }
+
@Test
void testProduceDataNoBuffering() throws Exception {
@@ -184,4 +226,22 @@ class TestAbstractBinAsyncEntityProducer {
}
+ @Test
+ void testProduceDataRepeatableAfterPartialWrite() throws Exception {
+ final AsyncEntityProducer producer = new RepeatableByteAsyncEntityProducer(
+ 6, ContentType.TEXT_PLAIN, "abcdef".getBytes(StandardCharsets.US_ASCII));
+
+ final WritableByteChannelMock partialByteChannel = new WritableByteChannelMock(1024, 3);
+ producer.produce(new BasicDataStreamChannel(partialByteChannel));
+ Assertions.assertEquals("abc", partialByteChannel.dump(StandardCharsets.US_ASCII));
+ producer.releaseResources();
+
+ final WritableByteChannelMock byteChannel = new WritableByteChannelMock(1024);
+ final DataStreamChannel streamChannel = new BasicDataStreamChannel(byteChannel);
+ producer.produce(streamChannel);
+
+ Assertions.assertFalse(byteChannel.isOpen());
+ Assertions.assertEquals("abcdef", byteChannel.dump(StandardCharsets.US_ASCII));
+ }
+
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestDigestingEntityProducer.java
=====================================
@@ -34,6 +34,7 @@ import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.WritableByteChannelMock;
import org.apache.hc.core5.http.nio.BasicDataStreamChannel;
+import org.apache.hc.core5.util.TextUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -62,4 +63,29 @@ class TestDigestingEntityProducer {
Assertions.assertEquals("827ccb0eea8a706c4c34a16891f84e7b", trailers.get(1).getValue());
}
+ @Test
+ void testProduceDataRepeatableAfterPartialWrite() throws Exception {
+ final DigestingEntityProducer producer = new DigestingEntityProducer("MD5",
+ new StringAsyncEntityProducer("abcdef", 6, 6, ContentType.TEXT_PLAIN));
+
+ final WritableByteChannelMock partialByteChannel = new WritableByteChannelMock(1024, 3);
+ producer.produce(new BasicDataStreamChannel(partialByteChannel));
+ Assertions.assertEquals("abc", partialByteChannel.dump(StandardCharsets.US_ASCII));
+ producer.releaseResources();
+
+ final WritableByteChannelMock byteChannel = new WritableByteChannelMock(1024);
+ final BasicDataStreamChannel dataStreamChannel = new BasicDataStreamChannel(byteChannel);
+ while (byteChannel.isOpen()) {
+ producer.produce(dataStreamChannel);
+ }
+
+ Assertions.assertEquals("abcdef", byteChannel.dump(StandardCharsets.US_ASCII));
+ Assertions.assertEquals("e80b5017098950fc58aad83c8c14978e", TextUtils.toHexString(producer.getDigest()));
+
+ final List<Header> trailers = dataStreamChannel.getTrailers();
+ Assertions.assertNotNull(trailers);
+ Assertions.assertEquals("digest", trailers.get(1).getName());
+ Assertions.assertEquals("e80b5017098950fc58aad83c8c14978e", trailers.get(1).getValue());
+ }
+
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestFileAsyncEntityProducer.java
=====================================
@@ -104,4 +104,22 @@ class TestFileAsyncEntityProducer {
}
}
+ @Test
+ void testTextContentRepeatableAfterPartialWrite() throws Exception {
+ final AsyncEntityProducer producer = new FileEntityProducer(tempFile, ContentType.TEXT_PLAIN);
+
+ final WritableByteChannelMock partialByteChannel = new WritableByteChannelMock(1024, 3);
+ producer.produce(new BasicDataStreamChannel(partialByteChannel));
+ Assertions.assertEquals("abc", partialByteChannel.dump(StandardCharsets.US_ASCII));
+ producer.releaseResources();
+
+ final WritableByteChannelMock byteChannel = new WritableByteChannelMock(1024);
+ final DataStreamChannel streamChannel = new BasicDataStreamChannel(byteChannel);
+ producer.produce(streamChannel);
+ producer.produce(streamChannel);
+
+ Assertions.assertFalse(byteChannel.isOpen());
+ Assertions.assertEquals("abcdef", byteChannel.dump(StandardCharsets.US_ASCII));
+ }
+
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestPathAsyncEntityProducer.java
=====================================
@@ -109,4 +109,23 @@ class TestPathAsyncEntityProducer {
}
}
+ @Test
+ void testTextContentRepeatableAfterPartialWrite() throws Exception {
+ final Path tempPath = tempFile.toPath();
+ final AsyncEntityProducer producer = new PathEntityProducer(tempPath, ContentType.TEXT_PLAIN, StandardOpenOption.READ);
+
+ final WritableByteChannelMock partialByteChannel = new WritableByteChannelMock(1024, 3);
+ producer.produce(new BasicDataStreamChannel(partialByteChannel));
+ Assertions.assertEquals("abc", partialByteChannel.dump(StandardCharsets.US_ASCII));
+ producer.releaseResources();
+
+ final WritableByteChannelMock byteChannel = new WritableByteChannelMock(1024);
+ final DataStreamChannel streamChannel = new BasicDataStreamChannel(byteChannel);
+ producer.produce(streamChannel);
+ producer.produce(streamChannel);
+
+ Assertions.assertFalse(byteChannel.isOpen());
+ Assertions.assertEquals("abcdef", byteChannel.dump(StandardCharsets.US_ASCII));
+ }
+
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/http/nio/entity/TestStringAsyncEntityProducer.java
=====================================
@@ -80,4 +80,23 @@ class TestStringAsyncEntityProducer {
}
}
+ @Test
+ void testTextContentRepeatableAfterPartialWrite() throws Exception {
+ final AsyncEntityProducer producer = new StringAsyncEntityProducer(
+ "abcdef", 6, 6, ContentType.TEXT_PLAIN);
+
+ final WritableByteChannelMock partialByteChannel = new WritableByteChannelMock(1024, 3);
+ producer.produce(new BasicDataStreamChannel(partialByteChannel));
+ Assertions.assertEquals("abc", partialByteChannel.dump(StandardCharsets.US_ASCII));
+ producer.releaseResources();
+
+ final WritableByteChannelMock byteChannel = new WritableByteChannelMock(1024);
+ final DataStreamChannel streamChannel = new BasicDataStreamChannel(byteChannel);
+ producer.produce(streamChannel);
+ producer.produce(streamChannel);
+
+ Assertions.assertFalse(byteChannel.isOpen());
+ Assertions.assertEquals("abcdef", byteChannel.dump(StandardCharsets.US_ASCII));
+ }
+
}
=====================================
httpcore5/src/test/java/org/apache/hc/core5/net/TestURIBuilder.java
=====================================
@@ -998,6 +998,39 @@ class TestURIBuilder {
Assertions.assertEquals("hello world", params.get(0).getValue());
}
+ @Test
+ void testDefaultEncodingPolicy() throws Exception {
+ final URIBuilder builder = new URIBuilder()
+ .setScheme("http")
+ .setHost("example.com")
+ .setPath("/a:b")
+ .addParameter("key", "a/b")
+ .setFragment("a/b");
+ final URI expected = new URI("http://example.com/a%3Ab?key=a%2Fb#a%2Fb");
+
+ Assertions.assertEquals(expected, builder.build());
+ builder.setEncodingPolicy(URIBuilder.EncodingPolicy.ALL_RESERVED);
+ Assertions.assertEquals(expected, builder.build());
+ builder.setEncodingPolicy(null);
+ Assertions.assertEquals(expected, builder.build());
+ }
+
+ @Test
+ void testResetEncodingPolicy() throws Exception {
+ final URIBuilder builder = new URIBuilder()
+ .setScheme("http")
+ .setUserInfo("user!")
+ .setHost("example.com")
+ .setPath("/a:b")
+ .setCustomQuery("a/b")
+ .setFragment("a/b")
+ .setEncodingPolicy(URIBuilder.EncodingPolicy.RFC_3986);
+
+ Assertions.assertEquals(new URI("http://user!@example.com/a:b?a/b#a/b"), builder.build());
+ Assertions.assertSame(builder, builder.setEncodingPolicy(null));
+ Assertions.assertEquals(new URI("http://user%21@example.com/a%3Ab?a%2Fb#a%2Fb"), builder.build());
+ }
+
@Test
void testCustomQueryEncoding() throws Exception {
final String query = "query param:!@/?\"";
=====================================
pom.xml
=====================================
@@ -33,7 +33,7 @@
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-parent</artifactId>
<name>Apache HttpComponents Core</name>
- <version>5.4.3</version>
+ <version>5.4.4</version>
<description>Apache HttpComponents Core is a library of components for building HTTP enabled services</description>
<url>https://hc.apache.org/httpcomponents-core-5.4.x/${project.version}/</url>
<inceptionYear>2005</inceptionYear>
@@ -48,7 +48,7 @@
<connection>scm:git:https://gitbox.apache.org/repos/asf/httpcomponents-core.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/httpcomponents-core.git</developerConnection>
<url>https://github.com/apache/httpcomponents-core/tree/${project.scm.tag}</url>
- <tag>5.4.3</tag>
+ <tag>5.4.4</tag>
</scm>
<distributionManagement>
View it on GitLab: https://salsa.debian.org/java-team/httpcomponents-core5/-/commit/d3056127325e0ff0d7835c722e2ff84dc395ffc9
--
View it on GitLab: https://salsa.debian.org/java-team/httpcomponents-core5/-/commit/d3056127325e0ff0d7835c722e2ff84dc395ffc9
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20260925/c8b53e2e/attachment.htm>
More information about the pkg-java-commits
mailing list