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.io.IOException;
33 import java.net.InetSocketAddress;
34 import java.util.concurrent.Future;
35
36 import org.apache.hc.core5.function.Supplier;
37 import org.apache.hc.core5.http.ContentType;
38 import org.apache.hc.core5.http.Header;
39 import org.apache.hc.core5.http.HttpException;
40 import org.apache.hc.core5.http.HttpHost;
41 import org.apache.hc.core5.http.HttpRequest;
42 import org.apache.hc.core5.http.HttpResponse;
43 import org.apache.hc.core5.http.HttpStatus;
44 import org.apache.hc.core5.http.Message;
45 import org.apache.hc.core5.http.Method;
46 import org.apache.hc.core5.http.URIScheme;
47 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
48 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
49 import org.apache.hc.core5.http.impl.routing.RequestRouter;
50 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
51 import org.apache.hc.core5.http.nio.AsyncFilterChain;
52 import org.apache.hc.core5.http.nio.AsyncPushProducer;
53 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
54 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
55 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
56 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
57 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
58 import org.apache.hc.core5.http2.HttpVersionPolicy;
59 import org.apache.hc.core5.reactor.IOReactorConfig;
60 import org.apache.hc.core5.reactor.ListenerEndpoint;
61 import org.apache.hc.core5.testing.nio.extension.H2AsyncRequesterResource;
62 import org.apache.hc.core5.testing.nio.extension.H2AsyncServerResource;
63 import org.apache.hc.core5.util.Timeout;
64 import org.hamcrest.CoreMatchers;
65 import org.junit.jupiter.api.Test;
66 import org.junit.jupiter.api.extension.RegisterExtension;
67
68 public abstract class H2ServerBootstrapFiltersTest {
69
70 private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
71
72 @RegisterExtension
73 private final H2AsyncServerResource serverResource = new H2AsyncServerResource((bootstrap) -> bootstrap
74 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
75 .setIOReactorConfig(
76 IOReactorConfig.custom()
77 .setSoTimeout(TIMEOUT)
78 .build())
79 .setRequestRouter(RequestRouter.<Supplier<AsyncServerExchangeHandler>>builder()
80 .addRoute(RequestRouter.LOCAL_AUTHORITY, "*", () -> new EchoHandler(2048))
81 .resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
82 .build())
83 .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
84 chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
85
86 @Override
87 public void sendInformation(
88 final HttpResponse response) throws HttpException, IOException {
89 responseTrigger.sendInformation(response);
90 }
91
92 @Override
93 public void submitResponse(
94 final HttpResponse response,
95 final AsyncEntityProducer entityProducer) throws HttpException, IOException {
96 response.setHeader("X-Test-Filter", "active");
97 responseTrigger.submitResponse(response, entityProducer);
98 }
99
100 @Override
101 public void pushPromise(
102 final HttpRequest promise,
103 final AsyncPushProducer responseProducer) throws HttpException, IOException {
104 responseTrigger.pushPromise(promise, responseProducer);
105 }
106
107 })));
108
109 @RegisterExtension
110 private final H2AsyncRequesterResource clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
111 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
112 .setIOReactorConfig(IOReactorConfig.custom()
113 .setSoTimeout(TIMEOUT)
114 .build()));
115
116 @Test
117 public void testSequentialRequests() throws Exception {
118 final HttpAsyncServer server = serverResource.start();
119
120 final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0), URIScheme.HTTP);
121 final ListenerEndpoint listener = future.get();
122 final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
123 final HttpAsyncRequester requester = clientResource.start();
124
125 final HttpHost target = new HttpHost("http", "localhost", address.getPort());
126 final Future<Message<HttpResponse, String>> resultFuture = requester.execute(
127 new BasicRequestProducer(Method.POST, target, "/stuff",
128 new StringAsyncEntityProducer("some stuff", ContentType.TEXT_PLAIN)),
129 new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), TIMEOUT, null);
130 final Message<HttpResponse, String> message = resultFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
131 assertThat(message, CoreMatchers.notNullValue());
132 final HttpResponse response = message.getHead();
133 assertThat(response.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
134 final Header testFilterHeader = response.getHeader("X-Test-Filter");
135 assertThat(testFilterHeader, CoreMatchers.notNullValue());
136 }
137
138 }