文件上载时间歇性SSL / TLS错误

时间:2017-05-10 15:06:41

标签: c# spring tomcat ssl restsharp

在使用REST Web服务时,我在解决SSL / TLS错误方面遇到了一些困难。

REST Web服务是使用Spring Framework使用Spring Framework开发的。

客户端是.NET应用程序,使用RestSharp进行REST Web服务消费。

在文件上传过程中,一个客户端出错,一切正常。

System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

此时我还在使用嵌入式Tomcat v8.5.5。在我的Spring Boot应用程序中,我遇到以下错误:

java.lang.NullPointerException: null
    at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.getSslSupport(NioEndpoint.java:1329) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
    // Etc.
java.lang.NullPointerException: null
    at org.apache.tomcat.util.net.SecureNioChannel.handshake(SecureNioChannel.java:182) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
    // Etc.

经过一些研究,我发现this topic有关与嵌入式Tomcat v8.5.5相关的类似错误。根据他们的建议,我将嵌入式Tomcat升级到v8.5.13。

很好,没有更多来自apache Tomcat的NPE。所以,我的.NET应用程序应该工作......或者不工作。

System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

仍然是同样的错误。由于我不再有Tomcat错误,因此我将org.apache的日志记录级别更改为DEBUG。我在DEBUG级别发现了一些新的错误:

2017-05-10 14:58:05.889 DEBUG 928 --- [-nio-443-exec-4] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@3678fe26:org.apache.tomcat.util.net.SecureNioChannel@63c88911:java.nio.channels.SocketChannel[connected local=/... remote=/...]], Read from buffer: [0]
2017-05-10 14:58:05.889 DEBUG 928 --- [-nio-443-exec-4] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header

java.io.EOFException: null
    at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1242) ~[tomcat-embed-core-8.5.13.jar!/:8.5.13]
    // Etc.

2017-05-10 14:58:05.889 DEBUG 928 --- [-nio-443-exec-4] o.apache.coyote.http11.Http11Processor   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@3678fe26:org.apache.tomcat.util.net.SecureNioChannel@63c88911:java.nio.channels.SocketChannel[connected local=/... remote=/...]], Status in: [OPEN_READ], State out: [CLOSED]
2017-05-10 14:58:05.889 DEBUG 928 --- [-nio-443-exec-4] org.apache.tomcat.util.net.NioEndpoint   : Failed to close socket

java.nio.channels.ClosedChannelException: null
    at sun.nio.ch.SocketChannelImpl.ensureWriteOpen(Unknown Source) ~[na:1.8.0_91]
    // Etc.

2017-05-10 14:58:05.889 DEBUG 928 --- [-nio-443-exec-4] o.apache.tomcat.util.threads.LimitLatch  : Counting down[https-jsse-nio-443-exec-4] latch=1
2017-05-10 15:00:34.593 DEBUG 928 --- [-nio-443-exec-9] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@58361212:org.apache.tomcat.util.net.SecureNioChannel@63c88911:java.nio.channels.SocketChannel[connected local=/... remote=/...]], Read from buffer: [0]
2017-05-10 15:00:34.593 DEBUG 928 --- [-nio-443-exec-9] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header

java.io.IOException: Unable to unwrap data, invalid status [CLOSED]
    at org.apache.tomcat.util.net.SecureNioChannel.read(SecureNioChannel.java:604) ~[tomcat-embed-core-8.5.13.jar!/:8.5.13]
    // Etc.

2017-05-10 15:00:34.593 DEBUG 928 --- [-nio-443-exec-9] o.apache.coyote.http11.Http11Processor   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@58361212:org.apache.tomcat.util.net.SecureNioChannel@63c88911:java.nio.channels.SocketChannel[connected local=/... remote=/...]], Status in: [OPEN_READ], State out: [CLOSED]
2017-05-10 15:00:34.593 DEBUG 928 --- [-nio-443-exec-9] org.apache.tomcat.util.net.NioEndpoint   : Failed to close socket

java.nio.channels.ClosedChannelException: null
    at sun.nio.ch.SocketChannelImpl.ensureWriteOpen(Unknown Source) ~[na:1.8.0_91]
    // Etc.

2017-05-10 15:00:34.593 DEBUG 928 --- [-nio-443-exec-9] o.apache.tomcat.util.threads.LimitLatch  : Counting down[https-jsse-nio-443-exec-9] latch=1

根据我的理解,客户端似乎成功连接到服务器,但由于SSL / TLS错误导致文件传输期间中断连接,导致那些ClosedChannelException服务器端。

我是否错误地使用了RestSharp?

RestRequest request = new RestRequest("path/to/uri", Method.PUT);

request.AddQueryParameter("myParam", myParam.ToString());
request.AddFile("myFile", "path/to/file", "multipart");

IRestResponse<MyResponse> response = myRestClient.Execute<MyResponse>(request);

此请求的Spring Boot代码:

@RequestMapping(method = RequestMethod.PUT, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public MyResponse replace(@RequestParam Integer myParam, @RequestParam MultipartFile myFile) {
    // Etc.

Spring中默认不支持PUT的{​​{1}}方法,但我创建了自己的multipart来处理它,所以问题不在这里。

看起来问题只发生在一个地方,而且只在文件传输过程中发生。所有其他地方都可以正常工作,但仍有MultipartResolverEOFException服务器端,即使它在客户端工作也是如此。

另一个不起眼的事情......它有时只会发生。有时候上传有效,有时候没有。

我不是SSL专家,所以我想知道它能做什么。

  • 客户端和服务器之间没有同步的东西?
  • 客户端和服务器之间的中断,导致ClosedChannelException

我对所有建议持开放态度,并会继续调查,并希望找到一些东西......

编辑2017-05-11

来自评论的精确度:

  • .NET应用程序是使用Microsoft Windows .NET Framework(而不是Mono)构建的。
  • SSL证书(服务器端)是PKCS#12文件中的完整链。

自我发布问题后检索到的信息:

  • 只有在.NET应用程序打开一段时间后才会出现该错误;如果在不到一分钟的时间内打开和关闭,就不会发生这种情况。
  • 主机操作系统:Windows 10 Pro x64 ...但ClosedChannelException提供Windows NT 6.2.9200.0。根据{{​​3}},此内核版本对应于Windows 8或Server 2012,而不是10. 编辑确定,这是一种已知行为。请参阅Wikipediahere。所以这与错误无关。
  • 尝试重现该错误,但没有成功。我怀疑主机或网络上的配置越来越糟。
  • 如上面的代码所示,System.Environment.OSVersion.VersionString对象仅实例化一次,并在应用程序的任何位置使用。这可能是一个问题吗?

调查仍在继续。

0 个答案:

没有答案