Attempt to stabilise web server tests that use h2c
Apache HttpClient 5.1 doesn't cope with Jetty 10 sending SETTINGS_ENABLE_CONNECT_PROTOCOL in the settings frame. It also appears to be unstable when using Undertow, resulting in a failure and "UT005032: Listener not making progress on framed channel, closing channel to prevent infinite loop" being logged on the server-side. Local experimentation suggests that Jetty's HTTP/2 client is more robust and that it does not trigger the problem with Undertow. It also fixes the problem with SETTINGS_ENABLE_CONNECT_PROTOCOL when testing against Jetty 10 so this commit updates the tests to use Jetty's client. Closes gh-26040
This commit is contained in:
parent
17a13de855
commit
5873dddc1c
|
@ -98,8 +98,10 @@ dependencies {
|
||||||
testImplementation("mysql:mysql-connector-java")
|
testImplementation("mysql:mysql-connector-java")
|
||||||
testImplementation("net.sourceforge.jtds:jtds")
|
testImplementation("net.sourceforge.jtds:jtds")
|
||||||
testImplementation("org.apache.derby:derby")
|
testImplementation("org.apache.derby:derby")
|
||||||
testImplementation("org.apache.httpcomponents:httpasyncclient")
|
|
||||||
testImplementation("org.awaitility:awaitility")
|
testImplementation("org.awaitility:awaitility")
|
||||||
|
testImplementation("org.eclipse.jetty:jetty-client")
|
||||||
|
testImplementation("org.eclipse.jetty.http2:http2-client")
|
||||||
|
testImplementation("org.eclipse.jetty.http2:http2-http-client-transport")
|
||||||
testImplementation("org.firebirdsql.jdbc:jaybird-jdk18")
|
testImplementation("org.firebirdsql.jdbc:jaybird-jdk18")
|
||||||
testImplementation("org.hsqldb:hsqldb")
|
testImplementation("org.hsqldb:hsqldb")
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
|
|
|
@ -43,11 +43,4 @@ class Jetty10ReactiveWebServerFactoryTests extends JettyReactiveWebServerFactory
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Override
|
|
||||||
@Disabled("https://github.com/eclipse/jetty.project/issues/6164")
|
|
||||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,4 @@ public class Jetty10ServletWebServerFactoryTests extends JettyServletWebServerFa
|
||||||
protected void jettyConfigurations() throws Exception {
|
protected void jettyConfigurations() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Override
|
|
||||||
@Disabled("https://github.com/eclipse/jetty.project/issues/6164")
|
|
||||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,12 @@ import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@EnabledForJreRange(min = JRE.JAVA_11)
|
@EnabledForJreRange(min = JRE.JAVA_11)
|
||||||
@ClassPathExclusions({ "jetty-*.jar", "tomcat-embed*.jar" })
|
@ClassPathExclusions({ "jetty-*.jar", "tomcat-embed*.jar", "http2-*.jar" })
|
||||||
@ClassPathOverrides({ "org.slf4j:slf4j-api:1.7.25", "org.eclipse.jetty:jetty-io:10.0.2",
|
@ClassPathOverrides({ "org.slf4j:slf4j-api:1.7.25", "org.eclipse.jetty:jetty-client:10.0.2",
|
||||||
"org.eclipse.jetty:jetty-server:10.0.2", "org.eclipse.jetty:jetty-servlet:10.0.2",
|
"org.eclipse.jetty:jetty-io:10.0.2", "org.eclipse.jetty:jetty-server:10.0.2",
|
||||||
"org.eclipse.jetty:jetty-util:10.0.2", "org.eclipse.jetty:jetty-webapp:10.0.2",
|
"org.eclipse.jetty:jetty-servlet:10.0.2", "org.eclipse.jetty:jetty-util:10.0.2",
|
||||||
"org.eclipse.jetty.http2:http2-common:10.0.2", "org.eclipse.jetty.http2:http2-hpack:10.0.2",
|
"org.eclipse.jetty:jetty-webapp:10.0.2", "org.eclipse.jetty.http2:http2-common:10.0.2",
|
||||||
|
"org.eclipse.jetty.http2:http2-hpack:10.0.2", "org.eclipse.jetty.http2:http2-http-client-transport:10.0.2",
|
||||||
"org.eclipse.jetty.http2:http2-server:10.0.2", "org.mortbay.jasper:apache-jsp:8.5.40" })
|
"org.eclipse.jetty.http2:http2-server:10.0.2", "org.mortbay.jasper:apache-jsp:8.5.40" })
|
||||||
@interface TestWithJetty10 {
|
@interface TestWithJetty10 {
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,12 @@ import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
import io.netty.handler.codec.http.HttpResponse;
|
import io.netty.handler.codec.http.HttpResponse;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
|
||||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||||
import org.awaitility.Awaitility;
|
import org.awaitility.Awaitility;
|
||||||
|
import org.eclipse.jetty.client.api.ContentResponse;
|
||||||
|
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||||
|
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||||
|
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
@ -459,35 +456,24 @@ public abstract class AbstractReactiveWebServerFactoryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed()
|
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Exception {
|
||||||
throws InterruptedException, ExecutionException, IOException {
|
|
||||||
AbstractReactiveWebServerFactory factory = getFactory();
|
AbstractReactiveWebServerFactory factory = getFactory();
|
||||||
Http2 http2 = new Http2();
|
Http2 http2 = new Http2();
|
||||||
http2.setEnabled(true);
|
http2.setEnabled(true);
|
||||||
factory.setHttp2(http2);
|
factory.setHttp2(http2);
|
||||||
this.webServer = factory.getWebServer(new EchoHandler());
|
this.webServer = factory.getWebServer(new EchoHandler());
|
||||||
this.webServer.start();
|
this.webServer.start();
|
||||||
try (CloseableHttpAsyncClient http2Client = HttpAsyncClients.createHttp2Default()) {
|
org.eclipse.jetty.client.HttpClient client = new org.eclipse.jetty.client.HttpClient(
|
||||||
http2Client.start();
|
new HttpClientTransportOverHTTP2(new HTTP2Client()));
|
||||||
SimpleHttpRequest request = SimpleHttpRequests.post("http://localhost:" + this.webServer.getPort());
|
client.start();
|
||||||
request.setBody("Hello World", ContentType.TEXT_PLAIN);
|
try {
|
||||||
SimpleHttpResponse response = http2Client.execute(request, new FutureCallback<SimpleHttpResponse>() {
|
ContentResponse response = client.POST("http://localhost:" + this.webServer.getPort())
|
||||||
|
.content(new StringContentProvider("Hello World"), "text/plain").send();
|
||||||
@Override
|
assertThat(response.getStatus() == HttpStatus.OK.value());
|
||||||
public void failed(Exception ex) {
|
assertThat(response.getContentAsString()).isEqualTo("Hello World");
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
@Override
|
client.stop();
|
||||||
public void completed(SimpleHttpResponse result) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelled() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}).get();
|
|
||||||
assertThat(response.getCode() == HttpStatus.OK.value());
|
|
||||||
assertThat(response.getBodyText()).isEqualTo("Hello World");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,12 +79,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
|
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.entity.InputStreamFactory;
|
import org.apache.http.client.entity.InputStreamFactory;
|
||||||
|
@ -103,6 +97,9 @@ import org.apache.jasper.EmbeddedServletOptions;
|
||||||
import org.apache.jasper.servlet.JspServlet;
|
import org.apache.jasper.servlet.JspServlet;
|
||||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||||
import org.awaitility.Awaitility;
|
import org.awaitility.Awaitility;
|
||||||
|
import org.eclipse.jetty.client.api.ContentResponse;
|
||||||
|
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||||
|
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Assumptions;
|
import org.junit.jupiter.api.Assumptions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -1130,35 +1127,22 @@ public abstract class AbstractServletWebServerFactoryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed()
|
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Exception {
|
||||||
throws InterruptedException, ExecutionException, IOException {
|
|
||||||
AbstractServletWebServerFactory factory = getFactory();
|
AbstractServletWebServerFactory factory = getFactory();
|
||||||
Http2 http2 = new Http2();
|
Http2 http2 = new Http2();
|
||||||
http2.setEnabled(true);
|
http2.setEnabled(true);
|
||||||
factory.setHttp2(http2);
|
factory.setHttp2(http2);
|
||||||
this.webServer = factory.getWebServer(exampleServletRegistration());
|
this.webServer = factory.getWebServer(exampleServletRegistration());
|
||||||
this.webServer.start();
|
this.webServer.start();
|
||||||
try (CloseableHttpAsyncClient http2Client = HttpAsyncClients.createHttp2Default()) {
|
org.eclipse.jetty.client.HttpClient client = new org.eclipse.jetty.client.HttpClient(
|
||||||
http2Client.start();
|
new HttpClientTransportOverHTTP2(new HTTP2Client()));
|
||||||
SimpleHttpRequest request = SimpleHttpRequests
|
client.start();
|
||||||
.get("http://localhost:" + this.webServer.getPort() + "/hello");
|
try {
|
||||||
SimpleHttpResponse response = http2Client.execute(request, new FutureCallback<SimpleHttpResponse>() {
|
ContentResponse response = client.GET("http://localhost:" + this.webServer.getPort() + "/hello");
|
||||||
|
assertThat(response.getStatus() == HttpStatus.OK.value());
|
||||||
@Override
|
}
|
||||||
public void failed(Exception ex) {
|
finally {
|
||||||
}
|
client.stop();
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed(SimpleHttpResponse result) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelled() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}).get();
|
|
||||||
assertThat(response.getCode()).isEqualTo(HttpStatus.OK.value());
|
|
||||||
assertThat(response.getBodyText()).isEqualTo("Hello World");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue