Reputation: 984
The following test with Wiremock throws an exception when sending an HTTP POST request to a Wiremock server.
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
public class ClientTest {
private static final int PORT = 27970;
@Test
public void myTest() throws IOException, InterruptedException {
WireMockServer server = new WireMockServer(WireMockConfiguration.options().port(PORT).notifier(new ConsoleNotifier(true)));
server.start();
WireMock mock = WireMock.create().host("localhost").port(PORT).build();
WireMock.configureFor(mock);
WireMock.stubFor(
post(urlEqualTo("/foo"))
.willReturn(aResponse()
.withStatus(201)
.withBody("bar")));
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:" + PORT + "/foo"))
// .version(HttpClient.Version.HTTP_1_1)
// .POST(HttpRequest.BodyPublishers.ofString("stuff"))
.POST(HttpRequest.BodyPublishers.ofInputStream(() -> new ByteArrayInputStream("stuff".getBytes(StandardCharsets.UTF_8))))
.build();
// Here there be Exceptions
HttpResponse<String> httpResponse = HttpClient.newHttpClient().send(httpRequest, HttpResponse.BodyHandlers.ofString());
assert httpResponse.body().equals("bar");
}
}
The following exceptions occurs:
java.io.IOException: Received RST_STREAM: Stream cancelled
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:586)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123)
at ContentStoreConnectorImplTest.myTest(ContentStoreConnectorImplTest.java:44)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.io.IOException: Received RST_STREAM: Stream cancelled
at java.net.http/jdk.internal.net.http.Stream.handleReset(Stream.java:534)
at java.net.http/jdk.internal.net.http.Stream.incoming_reset(Stream.java:505)
at java.net.http/jdk.internal.net.http.Stream.otherFrame(Stream.java:452)
at java.net.http/jdk.internal.net.http.Stream.incoming(Stream.java:445)
at java.net.http/jdk.internal.net.http.Http2Connection.processFrame(Http2Connection.java:812)
at java.net.http/jdk.internal.net.http.frame.FramesDecoder.decode(FramesDecoder.java:155)
at java.net.http/jdk.internal.net.http.Http2Connection$FramesController.processReceivedData(Http2Connection.java:232)
at java.net.http/jdk.internal.net.http.Http2Connection.asyncReceive(Http2Connection.java:674)
at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.processQueue(Http2Connection.java:1310)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:205)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:230)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
If either HTTP/1.1 or a String BodyPublisher or a GET request is used everything works, see commented lines.
After some debugging we found no solution or obvious problem. We are also not sure if this is a Wiremock problem or a problem with the Java-HTTP-Client.
When we dump the request, the body looks a bit strange though with some additional lines:
POST /foo HTTP/1.1
Connection: Upgrade, HTTP2-Settings
Host: localhost:2727
HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA
Transfer-encoding: chunked
Upgrade: h2c
User-Agent: Java-http-client/17.0.6
5
stuff
0
These lines disappear when using the String-Publisher. They do not disappear when using HTTP/1.1 but then it works regardless.
The dependencies as pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>wiremockhttp2</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
<version>3.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Upvotes: 4
Views: 1400
Reputation: 27103
We ran into this issue today on java 21. Upgrading the jdk from Oracle 21.0.2 to Temurin 21.0.6 fixed it for us.
Upvotes: 0