我试图将文件上传到一个受SSL保护并需要客户端证书(由内部CA签名)的Web服务。与Web服务的通信正常工作(下载文件、查询、运行命令和执行各种POST操作都按预期正常工作),但上传文件除外。
当上传文件时,我会收到一个SSLException(javax.net.ssl.SSLException),其中写道“写入错误:ssl=0x5fe209c0:系统调用期间的I/O错误,连接被对等方重置”。
我创建了一个副本服务器并删除了SSL和客户端证书要求,并尝试通过“vanilla”HTTP上传,它完美地工作。
我已经尝试使用setFixedLengthStreamingMode(int)和setChunkedStreamingMode(int),但没有成功。当使用它们时,异常从
此外,我们已经添加了WCF的“MessageLogging”和详细的“跟踪”。MessageLogging没有显示任何消息的提示(可能在转换为消息之前被丢弃),但跟踪显示了以下内容:
现在,在您说“啊哈,这是服务器问题”之前,请记住44kb文件上传成功,并且我们的iOS应用程序也能够成功上传文件。
这是客户端收到的异常的调用堆栈:
当上传文件时,我会收到一个SSLException(javax.net.ssl.SSLException),其中写道“写入错误:ssl=0x5fe209c0:系统调用期间的I/O错误,连接被对等方重置”。
我创建了一个副本服务器并删除了SSL和客户端证书要求,并尝试通过“vanilla”HTTP上传,它完美地工作。
我已经尝试使用setFixedLengthStreamingMode(int)和setChunkedStreamingMode(int),但没有成功。当使用它们时,异常从
write
方法抛出,而不使用它们时,相同的异常从调用getResponseCode()
处抛出。
我在服务器的 EventVwr
中没有找到关于错误的任何信息。
我们的另一个客户端(iOS客户端)能够上传文件,所以问题肯定出在我的地方,但我无法弄清楚是什么问题。
我不确定如何进一步调试此问题。
请帮忙。
编辑1
我们已经做了很多调试工作,发现:
- 小文件可以正常上传(44kb是成功上传的最大文件大小,上传时间约为1200毫秒)。
- 一个46kb的文件上传失败。失败耗时约2分钟(134120毫秒)。
编辑2
根据备注中所述,现在我让Fiddler正常工作了(感谢this question)。Fiddler已经获得了该文件,但未能成功发送。
请求(原始)看起来像:
POST https://192.168.2.2/rest/transfer/strong/Upload/Full?Path=%5C20140807_113255_20.jpg&Root=2 HTTP/1.1
SessionToken: 1234 // We use this for session management
FileMetadata: {"FileSize":"1315496","FileName":"GrumpyCat.jpg"}
Connection: Keep-Alive
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.1; GT-N7100 Build/JRO03C)
Host: 192.168.2.2
Accept-Encoding: gzip
Content-Type: application/x-www-form-urlencoded
Content-Length: 1315496
;odiao;awriorijgoeijoeirj;oedfrvgerg... // The image
Fiddler的响应(也是RAW)如下:
HTTP/1.1 504 Fiddler - Send Failure
Date: Wed, 20 Aug 2014 17:40:29 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Timestamp: 20:40:29.420
[Fiddler] ResendRequest() failed: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. < An existing connection was forcibly closed by the remote host
此外,我们已经添加了WCF的“MessageLogging”和详细的“跟踪”。MessageLogging没有显示任何消息的提示(可能在转换为消息之前被丢弃),但跟踪显示了以下内容:
![The WCF Trace as seen from the SvcTraceViewer](https://istack.dev59.com/isbKe.webp)
这是客户端收到的异常的调用堆栈:
E/RestClientUploader(3196): javax.net.ssl.SSLException: Write error: ssl=0x5d94b8b0: I/O error during system call, Connection reset by peer
E/RestClientUploader(3196): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native Method)
E/RestClientUploader(3196): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:693)
E/RestClientUploader(3196): at java.io.ByteArrayOutputStream.writeTo(ByteArrayOutputStream.java:231)
E/RestClientUploader(3196): at libcore.net.http.ChunkedOutputStream.writeBufferedChunkToSocket(ChunkedOutputStream.java:129)
E/RestClientUploader(3196): at libcore.net.http.ChunkedOutputStream.write(ChunkedOutputStream.java:77)
E/RestClientUploader(3196): at java.io.DataOutputStream.write(DataOutputStream.java:98)
E/RestClientUploader(3196): at com.varonis.datanywhere.communication.RestClientUploader.uploadFileToServer(RestClientUploader.java:151)
E/RestClientUploader(3196): at com.varonis.datanywhere.communication.RestClientUploader.uploadFullFile(RestClientUploader.java:67)
E/RestClientUploader(3196): at com.varonis.datanywhere.communication.services.FileUploadService.doUpload(FileUploadService.java:128)
E/RestClientUploader(3196): at com.varonis.datanywhere.communication.services.FileUploadService.onHandleIntent(FileUploadService.java:98)
E/RestClientUploader(3196): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
E/RestClientUploader(3196): at android.os.Handler.dispatchMessage(Handler.java:99)
E/RestClientUploader(3196): at android.os.Looper.loop(Looper.java:137)
E/RestClientUploader(3196): at android.os.HandlerThread.run(HandlerThread.java:60)