无法在Grizzly 2.3.19的HTTPS服务器上使用SNI过滤器

时间:2015-04-23 02:19:18

标签: grizzly

我试图做一个客户端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();
    }
}

1 个答案:

答案 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());
        }
    }
}