in httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java [440:541]
public HttpAsyncServer create() {
final String actualCanonicalHostName = canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName();
final HttpRequestMapper<Supplier<AsyncServerExchangeHandler>> requestRouterCopy;
if (lookupRegistry != null && requestRouter == null) {
final org.apache.hc.core5.http.protocol.RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> handlerRegistry = new org.apache.hc.core5.http.protocol.RequestHandlerRegistry<>(
actualCanonicalHostName,
() -> lookupRegistry != null ? lookupRegistry : new org.apache.hc.core5.http.protocol.UriPatternMatcher<>());
for (final RequestRouter.Entry<Supplier<AsyncServerExchangeHandler>> entry: routeEntries) {
handlerRegistry.register(entry.uriAuthority != null ? entry.uriAuthority.getHostName() : null, entry.route.pattern, entry.route.handler);
}
requestRouterCopy = handlerRegistry;
} else {
if (routeEntries.isEmpty()) {
requestRouterCopy = requestRouter;
} else {
requestRouterCopy = RequestRouter.create(
new URIAuthority(actualCanonicalHostName),
UriPatternType.URI_PATTERN,
routeEntries,
RequestRouter.IGNORE_PORT_AUTHORITY_RESOLVER,
requestRouter);
}
}
final HandlerFactory<AsyncServerExchangeHandler> handlerFactory;
if (!filters.isEmpty()) {
final NamedElementChain<AsyncFilterHandler> filterChainDefinition = new NamedElementChain<>();
filterChainDefinition.addLast(
new TerminalAsyncServerFilter(new DefaultAsyncResponseExchangeHandlerFactory(requestRouterCopy)),
StandardFilter.MAIN_HANDLER.name());
filterChainDefinition.addFirst(
new AsyncServerExpectationFilter(),
StandardFilter.EXPECT_CONTINUE.name());
for (final FilterEntry<AsyncFilterHandler> entry: filters) {
switch (entry.position) {
case AFTER:
filterChainDefinition.addAfter(entry.existing, entry.filterHandler, entry.name);
break;
case BEFORE:
filterChainDefinition.addBefore(entry.existing, entry.filterHandler, entry.name);
break;
case REPLACE:
filterChainDefinition.replace(entry.existing, entry.filterHandler);
break;
case FIRST:
filterChainDefinition.addFirst(entry.filterHandler, entry.name);
break;
case LAST:
// Don't add last, after TerminalAsyncServerFilter, as that does not delegate to the chain
// Instead, add the filter just before it, making it effectively the last filter
filterChainDefinition.addBefore(StandardFilter.MAIN_HANDLER.name(), entry.filterHandler, entry.name);
break;
}
}
NamedElementChain<AsyncFilterHandler>.Node current = filterChainDefinition.getLast();
AsyncServerFilterChainElement execChain = null;
while (current != null) {
execChain = new AsyncServerFilterChainElement(current.getValue(), execChain);
current = current.getPrevious();
}
handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain, exceptionCallback);
} else {
handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(requestRouterCopy,
handler -> new BasicAsyncServerExpectationDecorator(handler, exceptionCallback));
}
final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory = new ServerH2StreamMultiplexerFactory(
httpProcessor != null ? httpProcessor : H2Processors.server(),
handlerFactory,
h2Config != null ? h2Config : H2Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
h2StreamListener);
final TlsStrategy actualTlsStrategy = tlsStrategy != null ? tlsStrategy : new H2ServerTlsStrategy();
final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
handlerFactory,
http1Config != null ? http1Config : Http1Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
DefaultConnectionReuseStrategy.INSTANCE,
new DefaultHttpRequestParserFactory(http1Config),
new DefaultHttpResponseWriterFactory(http1Config),
DefaultContentLengthStrategy.INSTANCE,
DefaultContentLengthStrategy.INSTANCE,
http1StreamListener,
exceptionCallback);
final IOEventHandlerFactory ioEventHandlerFactory = new ServerHttpProtocolNegotiationStarter(
http1StreamHandlerFactory,
http2StreamHandlerFactory,
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
actualTlsStrategy,
handshakeTimeout,
exceptionCallback);
return new HttpAsyncServer(ioEventHandlerFactory, ioReactorConfig, ioSessionDecorator, exceptionCallback,
sessionListener, threadPoolListener, null, actualCanonicalHostName);
}