1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.testing.nio;
29
30 import static org.hamcrest.MatcherAssert.assertThat;
31
32 import java.net.InetSocketAddress;
33 import java.util.concurrent.Future;
34
35 import org.apache.hc.core5.http.ContentType;
36 import org.apache.hc.core5.http.HttpHost;
37 import org.apache.hc.core5.http.HttpResponse;
38 import org.apache.hc.core5.http.HttpStatus;
39 import org.apache.hc.core5.http.HttpVersion;
40 import org.apache.hc.core5.http.Message;
41 import org.apache.hc.core5.http.Method;
42 import org.apache.hc.core5.http.URIScheme;
43 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
44 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
45 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
46 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
47 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
48 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
49 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
50 import org.apache.hc.core5.http2.HttpVersionPolicy;
51 import org.apache.hc.core5.reactor.IOReactorConfig;
52 import org.apache.hc.core5.reactor.ListenerEndpoint;
53 import org.apache.hc.core5.testing.nio.extension.H2AsyncRequesterResource;
54 import org.apache.hc.core5.testing.nio.extension.H2AsyncServerResource;
55 import org.apache.hc.core5.util.Timeout;
56 import org.hamcrest.CoreMatchers;
57 import org.junit.jupiter.api.Test;
58 import org.junit.jupiter.api.extension.RegisterExtension;
59
60 public class H2ProtocolNegotiationTest {
61
62 private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
63
64 @RegisterExtension
65 private final H2AsyncServerResource serverResource;
66 @RegisterExtension
67 private final H2AsyncRequesterResource clientResource;
68
69 public H2ProtocolNegotiationTest() {
70 this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
71 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
72 .setIOReactorConfig(
73 IOReactorConfig.custom()
74 .setSoTimeout(TIMEOUT)
75 .build())
76 .register("*", () -> new EchoHandler(2048))
77 );
78 this.clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
79 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
80 .setIOReactorConfig(IOReactorConfig.custom()
81 .setSoTimeout(TIMEOUT)
82 .build())
83 );
84 }
85
86 @Test
87 public void testForceHttp1() throws Exception {
88 final HttpAsyncServer server = serverResource.start();
89 final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0), URIScheme.HTTPS);
90 final ListenerEndpoint listener = future.get();
91 final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
92 final HttpAsyncRequester requester = clientResource.start();
93
94 final HttpHost target = new HttpHost(URIScheme.HTTPS.id, "localhost", address.getPort());
95 final Future<AsyncClientEndpoint> connectFuture = requester.connect(target, TIMEOUT, HttpVersionPolicy.FORCE_HTTP_1, null);
96 final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
97
98 final Future<Message<HttpResponse, String>> resultFuture1 = endpoint.execute(
99 new BasicRequestProducer(Method.POST, target, "/stuff",
100 new StringAsyncEntityProducer("some stuff", ContentType.TEXT_PLAIN)),
101 new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
102 final Message<HttpResponse, String> message1 = resultFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
103 assertThat(message1, CoreMatchers.notNullValue());
104 final HttpResponse response1 = message1.getHead();
105 assertThat(response1.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
106 assertThat(response1.getVersion(), CoreMatchers.equalTo(HttpVersion.HTTP_1_1));
107 }
108
109 @Test
110 public void testForceHttp2() throws Exception {
111 final HttpAsyncServer server = serverResource.start();
112 final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0), URIScheme.HTTPS);
113 final ListenerEndpoint listener = future.get();
114 final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
115 final HttpAsyncRequester requester = clientResource.start();
116
117 final HttpHost target = new HttpHost(URIScheme.HTTPS.id, "localhost", address.getPort());
118 final Future<AsyncClientEndpoint> connectFuture = requester.connect(target, TIMEOUT, HttpVersionPolicy.FORCE_HTTP_2, null);
119 final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
120
121 final Future<Message<HttpResponse, String>> resultFuture1 = endpoint.execute(
122 new BasicRequestProducer(Method.POST, target, "/stuff",
123 new StringAsyncEntityProducer("some stuff", ContentType.TEXT_PLAIN)),
124 new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
125 final Message<HttpResponse, String> message1 = resultFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
126 assertThat(message1, CoreMatchers.notNullValue());
127 final HttpResponse response1 = message1.getHead();
128 assertThat(response1.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
129 assertThat(response1.getVersion(), CoreMatchers.equalTo(HttpVersion.HTTP_2));
130 }
131
132 @Test
133 public void testNegotiateProtocol() throws Exception {
134 final HttpAsyncServer server = serverResource.start();
135 final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0), URIScheme.HTTPS);
136 final ListenerEndpoint listener = future.get();
137 final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
138 final HttpAsyncRequester requester = clientResource.start();
139
140 final HttpHost target = new HttpHost(URIScheme.HTTPS.id, "localhost", address.getPort());
141 final Future<AsyncClientEndpoint> connectFuture = requester.connect(target, TIMEOUT, HttpVersionPolicy.NEGOTIATE, null);
142 final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
143
144 final Future<Message<HttpResponse, String>> resultFuture1 = endpoint.execute(
145 new BasicRequestProducer(Method.POST, target, "/stuff",
146 new StringAsyncEntityProducer("some stuff", ContentType.TEXT_PLAIN)),
147 new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
148 final Message<HttpResponse, String> message1 = resultFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
149 assertThat(message1, CoreMatchers.notNullValue());
150 final HttpResponse response1 = message1.getHead();
151 assertThat(response1.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
152 assertThat(response1.getVersion(), CoreMatchers.equalTo(HttpVersion.HTTP_2));
153 }
154
155 }