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("net.sourceforge.jtds:jtds")
|
||||
testImplementation("org.apache.derby:derby")
|
||||
testImplementation("org.apache.httpcomponents:httpasyncclient")
|
||||
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.hsqldb:hsqldb")
|
||||
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 {
|
||||
}
|
||||
|
||||
@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)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@EnabledForJreRange(min = JRE.JAVA_11)
|
||||
@ClassPathExclusions({ "jetty-*.jar", "tomcat-embed*.jar" })
|
||||
@ClassPathOverrides({ "org.slf4j:slf4j-api:1.7.25", "org.eclipse.jetty:jetty-io:10.0.2",
|
||||
"org.eclipse.jetty:jetty-server:10.0.2", "org.eclipse.jetty:jetty-servlet:10.0.2",
|
||||
"org.eclipse.jetty:jetty-util: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",
|
||||
@ClassPathExclusions({ "jetty-*.jar", "tomcat-embed*.jar", "http2-*.jar" })
|
||||
@ClassPathOverrides({ "org.slf4j:slf4j-api:1.7.25", "org.eclipse.jetty:jetty-client:10.0.2",
|
||||
"org.eclipse.jetty:jetty-io:10.0.2", "org.eclipse.jetty:jetty-server:10.0.2",
|
||||
"org.eclipse.jetty:jetty-servlet:10.0.2", "org.eclipse.jetty:jetty-util: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" })
|
||||
@interface TestWithJetty10 {
|
||||
|
||||
|
|
|
@ -41,15 +41,12 @@ import io.netty.handler.codec.http.HttpHeaderNames;
|
|||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
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.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.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -459,35 +456,24 @@ public abstract class AbstractReactiveWebServerFactoryTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed()
|
||||
throws InterruptedException, ExecutionException, IOException {
|
||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Exception {
|
||||
AbstractReactiveWebServerFactory factory = getFactory();
|
||||
Http2 http2 = new Http2();
|
||||
http2.setEnabled(true);
|
||||
factory.setHttp2(http2);
|
||||
this.webServer = factory.getWebServer(new EchoHandler());
|
||||
this.webServer.start();
|
||||
try (CloseableHttpAsyncClient http2Client = HttpAsyncClients.createHttp2Default()) {
|
||||
http2Client.start();
|
||||
SimpleHttpRequest request = SimpleHttpRequests.post("http://localhost:" + this.webServer.getPort());
|
||||
request.setBody("Hello World", ContentType.TEXT_PLAIN);
|
||||
SimpleHttpResponse response = http2Client.execute(request, new FutureCallback<SimpleHttpResponse>() {
|
||||
|
||||
@Override
|
||||
public void failed(Exception ex) {
|
||||
org.eclipse.jetty.client.HttpClient client = new org.eclipse.jetty.client.HttpClient(
|
||||
new HttpClientTransportOverHTTP2(new HTTP2Client()));
|
||||
client.start();
|
||||
try {
|
||||
ContentResponse response = client.POST("http://localhost:" + this.webServer.getPort())
|
||||
.content(new StringContentProvider("Hello World"), "text/plain").send();
|
||||
assertThat(response.getStatus() == HttpStatus.OK.value());
|
||||
assertThat(response.getContentAsString()).isEqualTo("Hello World");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed(SimpleHttpResponse result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
}
|
||||
|
||||
}).get();
|
||||
assertThat(response.getCode() == HttpStatus.OK.value());
|
||||
assertThat(response.getBodyText()).isEqualTo("Hello World");
|
||||
finally {
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,12 +79,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import javax.servlet.http.HttpSession;
|
||||
|
||||
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.client.HttpClient;
|
||||
import org.apache.http.client.entity.InputStreamFactory;
|
||||
|
@ -103,6 +97,9 @@ import org.apache.jasper.EmbeddedServletOptions;
|
|||
import org.apache.jasper.servlet.JspServlet;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
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.Assumptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -1130,35 +1127,22 @@ public abstract class AbstractServletWebServerFactoryTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed()
|
||||
throws InterruptedException, ExecutionException, IOException {
|
||||
protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Exception {
|
||||
AbstractServletWebServerFactory factory = getFactory();
|
||||
Http2 http2 = new Http2();
|
||||
http2.setEnabled(true);
|
||||
factory.setHttp2(http2);
|
||||
this.webServer = factory.getWebServer(exampleServletRegistration());
|
||||
this.webServer.start();
|
||||
try (CloseableHttpAsyncClient http2Client = HttpAsyncClients.createHttp2Default()) {
|
||||
http2Client.start();
|
||||
SimpleHttpRequest request = SimpleHttpRequests
|
||||
.get("http://localhost:" + this.webServer.getPort() + "/hello");
|
||||
SimpleHttpResponse response = http2Client.execute(request, new FutureCallback<SimpleHttpResponse>() {
|
||||
|
||||
@Override
|
||||
public void failed(Exception ex) {
|
||||
org.eclipse.jetty.client.HttpClient client = new org.eclipse.jetty.client.HttpClient(
|
||||
new HttpClientTransportOverHTTP2(new HTTP2Client()));
|
||||
client.start();
|
||||
try {
|
||||
ContentResponse response = client.GET("http://localhost:" + this.webServer.getPort() + "/hello");
|
||||
assertThat(response.getStatus() == HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed(SimpleHttpResponse result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
}
|
||||
|
||||
}).get();
|
||||
assertThat(response.getCode()).isEqualTo(HttpStatus.OK.value());
|
||||
assertThat(response.getBodyText()).isEqualTo("Hello World");
|
||||
finally {
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue