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 package org.apache.hc.client5.http.examples;
28
29 import java.nio.ByteBuffer;
30 import java.nio.CharBuffer;
31 import java.util.concurrent.Future;
32
33 import org.apache.hc.client5.http.async.methods.AbstractBinPushConsumer;
34 import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
35 import org.apache.hc.client5.http.config.TlsConfig;
36 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
37 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
38 import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
39 import org.apache.hc.core5.function.Supplier;
40 import org.apache.hc.core5.http.ContentType;
41 import org.apache.hc.core5.http.HttpRequest;
42 import org.apache.hc.core5.http.HttpResponse;
43 import org.apache.hc.core5.http.impl.routing.RequestRouter;
44 import org.apache.hc.core5.http.message.BasicHttpRequest;
45 import org.apache.hc.core5.http.message.StatusLine;
46 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
47 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
48 import org.apache.hc.core5.http.support.BasicRequestBuilder;
49 import org.apache.hc.core5.http2.HttpVersionPolicy;
50 import org.apache.hc.core5.http2.config.H2Config;
51 import org.apache.hc.core5.io.CloseMode;
52
53
54
55
56 public class AsyncClientH2ServerPush {
57
58 public static void main(final String[] args) throws Exception {
59
60 final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
61 .setH2Config(H2Config.custom()
62 .setPushEnabled(true)
63 .build())
64 .setConnectionManager(PoolingAsyncClientConnectionManagerBuilder.create()
65 .setDefaultTlsConfig(TlsConfig.custom()
66 .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
67 .build())
68 .build())
69 .build();
70
71 client.start();
72
73 final RequestRouter<Supplier<AsyncPushConsumer>> pushRequestRouter = RequestRouter.<Supplier<AsyncPushConsumer>>builder()
74
75 .resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
76
77 .addRoute(RequestRouter.LOCAL_AUTHORITY, "*", () -> new AbstractBinPushConsumer() {
78
79 @Override
80 protected void start(
81 final HttpRequest promise,
82 final HttpResponse response,
83 final ContentType contentType) {
84 System.out.println(promise.getPath() + " (push)->" + new StatusLine(response));
85 }
86
87 @Override
88 protected int capacityIncrement() {
89 return Integer.MAX_VALUE;
90 }
91
92 @Override
93 protected void data(final ByteBuffer data, final boolean endOfStream) {
94 }
95
96 @Override
97 protected void completed() {
98 }
99
100 @Override
101 public void failed(final Exception cause) {
102 System.out.println("(push)->" + cause);
103 }
104
105 @Override
106 public void releaseResources() {
107 }
108
109 })
110 .build();
111
112 final BasicHttpRequest request = BasicRequestBuilder.get("https://nghttp2.org/httpbin/").build();
113
114 System.out.println("Executing request " + request);
115 final Future<Void> future = client.execute(
116 new BasicRequestProducer(request, null),
117 new AbstractCharResponseConsumer<Void>() {
118
119 @Override
120 protected void start(
121 final HttpResponse response,
122 final ContentType contentType) {
123 System.out.println(request + "->" + new StatusLine(response));
124 }
125
126 @Override
127 protected int capacityIncrement() {
128 return Integer.MAX_VALUE;
129 }
130
131 @Override
132 protected void data(final CharBuffer data, final boolean endOfStream) {
133 }
134
135 @Override
136 protected Void buildResult() {
137 return null;
138 }
139
140 @Override
141 public void failed(final Exception cause) {
142 System.out.println(request + "->" + cause);
143 }
144
145 @Override
146 public void releaseResources() {
147 }
148
149 },
150 HttpAsyncClients.pushRouter(pushRequestRouter),
151 null,
152 null);
153 future.get();
154
155 System.out.println("Shutting down");
156 client.close(CloseMode.GRACEFUL);
157 }
158
159 }