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 java.io.IOException;
31 import java.net.InetSocketAddress;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.concurrent.Future;
35
36 import javax.net.ssl.SSLContext;
37
38 import org.apache.hc.core5.function.Decorator;
39 import org.apache.hc.core5.function.Supplier;
40 import org.apache.hc.core5.http.config.CharCodingConfig;
41 import org.apache.hc.core5.http.config.Http1Config;
42 import org.apache.hc.core5.http.impl.HttpProcessors;
43 import org.apache.hc.core5.http.impl.routing.RequestRouter;
44 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
45 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
46 import org.apache.hc.core5.http.nio.support.BasicAsyncServerExpectationDecorator;
47 import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
48 import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
49 import org.apache.hc.core5.http.protocol.HttpProcessor;
50 import org.apache.hc.core5.http.protocol.UriPatternType;
51 import org.apache.hc.core5.http2.HttpVersionPolicy;
52 import org.apache.hc.core5.http2.config.H2Config;
53 import org.apache.hc.core5.http2.impl.H2Processors;
54 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
55 import org.apache.hc.core5.reactor.IOReactorConfig;
56 import org.apache.hc.core5.reactor.IOReactorStatus;
57 import org.apache.hc.core5.reactor.ListenerEndpoint;
58 import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
59 import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
60 import org.apache.hc.core5.util.Args;
61 import org.apache.hc.core5.util.Asserts;
62
63 public class H2TestServer extends AsyncServer {
64
65 private final SSLContext sslContext;
66 private final SSLSessionInitializer sslSessionInitializer;
67 private final SSLSessionVerifier sslSessionVerifier;
68 private final List<RequestRouter.Entry<Supplier<AsyncServerExchangeHandler>>> routeEntries;
69
70 public H2TestServer(
71 final IOReactorConfig ioReactorConfig,
72 final SSLContext sslContext,
73 final SSLSessionInitializer sslSessionInitializer,
74 final SSLSessionVerifier sslSessionVerifier) throws IOException {
75 super(ioReactorConfig);
76 this.sslContext = sslContext;
77 this.sslSessionInitializer = sslSessionInitializer;
78 this.sslSessionVerifier = sslSessionVerifier;
79 this.routeEntries = new ArrayList<>();
80 }
81
82 public H2TestServer() throws IOException {
83 this(IOReactorConfig.DEFAULT, null, null, null);
84 }
85
86 public void register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
87 Args.notNull(uriPattern, "URI pattern");
88 Args.notNull(supplier, "Exchange handler supplier");
89 Asserts.check(getStatus() == IOReactorStatus.INACTIVE, "Server has already been started");
90 routeEntries.add(new RequestRouter.Entry<>(uriPattern, supplier));
91 }
92
93 public <T> void register(
94 final String uriPattern,
95 final AsyncServerRequestHandler<T> requestHandler) {
96 register(uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
97 }
98
99 public void start(final IOEventHandlerFactory handlerFactory) throws IOException {
100 execute(handlerFactory);
101 }
102
103 public InetSocketAddress start(
104 final HttpProcessor httpProcessor,
105 final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
106 final H2Config h2Config) throws Exception {
107 start(new InternalServerProtocolNegotiationStarter(
108 httpProcessor != null ? httpProcessor : H2Processors.server(),
109 new DefaultAsyncResponseExchangeHandlerFactory(
110 RequestRouter.create(RequestRouter.LOCAL_AUTHORITY, UriPatternType.URI_PATTERN, routeEntries, RequestRouter.LOCAL_AUTHORITY_RESOLVER, null),
111 exchangeHandlerDecorator != null ? exchangeHandlerDecorator : BasicAsyncServerExpectationDecorator::new),
112 HttpVersionPolicy.FORCE_HTTP_2,
113 h2Config,
114 Http1Config.DEFAULT,
115 CharCodingConfig.DEFAULT,
116 sslContext,
117 sslSessionInitializer,
118 sslSessionVerifier));
119 final Future<ListenerEndpoint> future = listen(new InetSocketAddress(0));
120 final ListenerEndpoint listener = future.get();
121 return (InetSocketAddress) listener.getAddress();
122 }
123
124 public InetSocketAddress start(
125 final HttpProcessor httpProcessor,
126 final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
127 final Http1Config http1Config) throws Exception {
128 start(new InternalServerProtocolNegotiationStarter(
129 httpProcessor != null ? httpProcessor : HttpProcessors.server(),
130 new DefaultAsyncResponseExchangeHandlerFactory(
131 RequestRouter.create(RequestRouter.LOCAL_AUTHORITY, UriPatternType.URI_PATTERN, routeEntries, RequestRouter.LOCAL_AUTHORITY_RESOLVER, null),
132 exchangeHandlerDecorator != null ? exchangeHandlerDecorator : BasicAsyncServerExpectationDecorator::new),
133 HttpVersionPolicy.FORCE_HTTP_1,
134 H2Config.DEFAULT,
135 http1Config,
136 CharCodingConfig.DEFAULT,
137 sslContext,
138 sslSessionInitializer,
139 sslSessionVerifier));
140 final Future<ListenerEndpoint> future = listen(new InetSocketAddress(0));
141 final ListenerEndpoint listener = future.get();
142 return (InetSocketAddress) listener.getAddress();
143 }
144
145 public InetSocketAddress start(final H2Config h2Config) throws Exception {
146 return start(null, null, h2Config);
147 }
148
149 public InetSocketAddress start(final Http1Config http1Config) throws Exception {
150 return start(null, null, http1Config);
151 }
152
153 public InetSocketAddress start() throws Exception {
154 return start(H2Config.DEFAULT);
155 }
156
157 }