我试图做一个客户端SNI应用程序,进行集成测试我正在使用Grizzly服务器测试SNI正在通过。我按照docs使用过滤器。但是从不调用过滤器。
文档没有显示完整的示例。我发现添加过滤器的机制似乎被忽略了。 2.2中使用的旧方法不再公开。
以下是我的代码:
private TCPNIOTransport createMockServerTransport() {
final SSLEngineConfigurator sslServerEngineConfig = new SSLEngineConfigurator(createSSLContextConfigurator().createSSLContext(), false, false, false);
return TCPNIOTransportBuilder.newInstance().setProcessor(getFilters()).build();
}
private FilterChain getFilters() {
SNIFilter sniFilter = getSniFilter();
final FilterChain chain = FilterChainBuilder.stateless()
.add(new TransportFilter())
.add(sniFilter)
.add(new StringFilter())
.add(new BaseFilter() {
@Override
public NextAction handleRead(final FilterChainContext ctx)
throws IOException {
return ctx.getInvokeAction();
}
})
.build();
return chain;
}
private SNIFilter getSniFilter() {
final Attribute<String> sniHostAttr = Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute("sni-host-attr");
SNIFilter sniFilter = new SNIFilter();
sniFilter.setServerSSLConfigResolver(new SNIServerConfigResolver() {
@Override
public SNIConfig resolve(Connection connection, String hostname) {
sniHostAttr.set(connection, hostname);
if (StringUtils.isEmpty(hostname)) {
throw new IllegalArgumentException("SNI Has not been sent");
}
return SNIConfig.newServerConfig(sslServerEngineConfig);
}
});
return sniFilter;
}
private SSLContextConfigurator createSSLContextConfigurator() {
SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator();
ClassLoader cl = HttpRequestSNITestCase.class.getClassLoader();
URL cacertsUrl = cl.getResource("trustStore");
if (cacertsUrl != null) {
sslContextConfigurator.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfigurator.setTrustStorePass("myPassword");
}
URL keystoreUrl = cl.getResource("serverKeystore");
if (cacertsUrl != null) {
sslContextConfigurator.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfigurator.setKeyStorePass("myPassword");
sslContextConfigurator.setKeyPass("myPassword");
}
return sslContextConfigurator;
}
public class Server {
private HttpServer webServer;
protected void startServer() throws IOException {
SSLEngineConfigurator sslServerEngineConfig = new SSLEngineConfigurator(createSSLContextConfigurator().createSSLContext(), false, false, false);
NetworkListener networkListener = new NetworkListener("sample-listener", "localhost", httpsPort.getNumber());
networkListener.setTransport(createMockServerTransport());
networkListener.setSSLEngineConfig(sslServerEngineConfig);
webServer = HttpServer.createSimpleServer();
webServer.addListener(networkListener);
networkListener.setSecure(true);
networkListener.getTransport().setProcessor(getFilters());
FilterChain chain = networkListener.getFilterChain();
webServer.start();
}
protected void stopServer() {
webServer.shutdownNow();
}
}
答案 0 :(得分:2)
要更新HttpServer过滤器链,您必须使用AddOn:
protected void startServer() throws IOException {
NetworkListener networkListener = new NetworkListener("sample-listener", "localhost", 8081);
sslServerEngineConfig = new SSLEngineConfigurator(createSSLContextConfigurator().createSSLContext(), false, false, false);
networkListener.setSSLEngineConfig(sslServerEngineConfig);
networkListener.setSecure(true);
networkListener.registerAddOn(new SniAddOn());
webServer = HttpServer.createSimpleServer();
webServer.addListener(networkListener);
webServer.start();
}
private class SniAddOn implements AddOn {
public void setup(NetworkListener networkListener,
FilterChainBuilder builder) {
// replace SSLFilter (if any) with SNIFilter
final int idx = builder.indexOfType(SSLBaseFilter.class);
if (idx != -1) {
builder.set(idx, getSniFilter());
}
}
}