![当客户端未完成 SSL 握手时,Tomcat 会出现 NullPointerException](https://linux22.com/image/546918/%E5%BD%93%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%9C%AA%E5%AE%8C%E6%88%90%20SSL%20%E6%8F%A1%E6%89%8B%E6%97%B6%EF%BC%8CTomcat%20%E4%BC%9A%E5%87%BA%E7%8E%B0%20NullPointerException.png)
我有使用 APR 和 OpenSSL 的 Tomcat 7.0.12。一切似乎都运行良好,但我看到NullPointerException
日志中出现了一些堆栈跟踪。据我所知,每当客户端连接、启动 TLS 握手、接收服务器的证书,然后立即关闭 TCP 连接而不继续进行密钥交换时,似乎都会发生这种情况。
我使用的是自签名证书,因此每当浏览器不信任证书并必须要求用户验证时,就会发生这种情况(例如)。客户端显然不在乎,因为它是断开连接的一方。
DEBUG ["http-apr-443"-exec-3] org.apache.tomcat.util.net.AprEndpoint: Handshake failed: error:00000000:lib(0):func(0):reason(0)
ERROR ["http-apr-443"-exec-3] org.apache.coyote.http11.Http11AprProtocol: Error reading request, ignored
java.lang.NullPointerException
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:221)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:323)
at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:1675)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
如果客户端在收到来自服务器的证书后没有断开连接,而是继续进行握手,则一切都会按预期进行,日志中不会出现任何错误。也许这只是表面现象,但也许我做错了什么。
连接器配置如下(或多或少是从某处的示例复制而来):
<Connector
SSLCertificateFile="/etc/ssl/certs/server.crt"
SSLCertificateKeyFile="/etc/ssl/private/server.key"
SSLEnabled="true"
acceptCount="100"
clientAuth="optional"
disableUploadTimeout="true"
enableLookups="false"
maxHttpHeaderSize="8192"
maxThreads="150"
port="443"
scheme="https"
secure="true"
sslProtocol="TLSv1"
/>
编辑添加,FWIW,我刚刚注意到有一个相似的catalina.out
堆栈跟踪同时结束:
Exception in thread ""http-apr-443"-exec-3" java.lang.NullPointerException
at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:1678)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
答案1
这是个转移注意力的花招;它捕获了来自连接处理程序的异常并转储了跟踪。正是这种神秘的错误导致我建议使用mod_jk
将请求转发到 Tomcat 上的 AJP 连接器。