C# Mono HTTPS异常-身份验证或解密失败

C# Mono HTTPS异常-身份验证或解密失败,c#,mono,C#,Mono,当我试图通过HTTPS发布一些数据时,会间歇性地出现此异常。在mono 2.10.1上运行(现在改为2.10.9)。我不知道为什么会发生这种情况,它似乎与请求大小(大约2.5MB)无关,因为其他类似大小的请求正在工作 // these arguments are not null, as I can see them in a log. var response1 = web1.UploadData(address, "POST", buffer); 堆栈跟踪mono 2.10.1: Syst

当我试图通过HTTPS发布一些数据时,会间歇性地出现此异常。在mono 2.10.1上运行(现在改为2.10.9)。我不知道为什么会发生这种情况,它似乎与请求大小(大约2.5MB)无关,因为其他类似大小的请求正在工作

// these arguments are not null, as I can see them in a log.
var response1 = web1.UploadData(address, "POST", buffer);
堆栈跟踪mono 2.10.1:

System.Net.WebException: An error occurred performing a WebClient request. ---> System.IO.IOException: IO exception during Write. ---> System.NullReferenceException: Object reference not set to an instance of an object
  at Mono.Security.Protocol.Tls.SslStreamBase.InternalBeginWrite (Mono.Security.Protocol.Tls.InternalAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslStreamBase.InternalBeginWrite (Mono.Security.Protocol.Tls.InternalAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslStreamBase.BeginWrite (System.Byte[] buffer, Int32 offset, Int32 count, System.AsyncCallback callback, System.Object state) [0x00000] in <filename unknown>:0 
  at System.Net.WebConnection.BeginWrite (System.Net.HttpWebRequest request, System.Byte[] buffer, Int32 offset, Int32 size, System.AsyncCallback cb, System.Object state) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Net.WebClient.UploadData (System.Uri address, System.String method, System.Byte[] data) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Net.WebClient:UploadData (System.Uri,string,byte[])
System.Net.WebException:执行WebClient请求时出错。-->System.IO.IOException:写入期间的IO异常。-->System.NullReferenceException:对象引用未设置为对象的实例
位于:0中的Mono.Security.Protocol.Tls.SslStreamBase.InternalBeginWrite(Mono.Security.Protocol.Tls.internalasynchresult-asynchresult)[0x00000]处
---内部异常堆栈跟踪的结束---
位于:0中的Mono.Security.Protocol.Tls.SslStreamBase.InternalBeginWrite(Mono.Security.Protocol.Tls.internalasynchresult-asynchresult)[0x00000]处
在Mono.Security.Protocol.Tls.SslStreamBase.BeginWrite(System.Byte[]缓冲区、Int32偏移量、Int32计数、System.AsyncCallback回调、System.Object状态)[0x00000]中:0
在System.Net.WebConnection.BeginWrite(System.Net.HttpWebRequest请求、System.Byte[]缓冲区、Int32偏移量、Int32大小、System.AsyncCallback cb、System.Object状态)[0x00000]中:0
---内部异常堆栈跟踪的结束---
在System.Net.WebClient.UploadData(System.Uri地址、System.String方法、System.Byte[]数据)[0x00000]中:0
在(带检查的包装器远程调用)System.Net.WebClient:UploadData(System.Uri,字符串,字节[])
对于mono 2.10.9,我得到了一个不同的错误:

System.Net.WebException: Error getting response stream (ReadDone1): ReceiveFailure ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00000] in <filename unknown>:0
  at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
  at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
  at System.Net.WebClient.GetWebResponse (System.Net.WebRequest request) [0x00000] in <filename unknown>:0
  at System.Net.WebClient.ReadAll (System.Net.WebRequest request, System.Object userToken) [0x00000] in <filename unknown>:0
  at System.Net.WebClient.UploadDataCore (System.Uri address, System.String method, System.Byte[] data, System.Object userToken) [0x00000] in <filename unknown>:0
  at System.Net.WebClient.UploadData (System.Uri address, System.String method, System.Byte[] data) [0x00000] in <filename unknown>:0
System.Net.WebException:获取响应流(ReadDone1)时出错:ReceiveFailure-->Mono.Security.Protocol.Tls.Tls异常:身份验证或解密失败。
在:0中的Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert(AlertLevel AlertLevel,AlertDescription alertDesc)[0x00000]处
位于:0中的Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback(IAsyncResult asyncResult)[0x00000]处
---内部异常堆栈跟踪的结束---
0中的System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)[0x00000]处
位于:0中的System.Net.HttpWebRequest.GetResponse()[0x00000]
在0中的System.Net.WebClient.GetWebResponse(System.Net.WebRequest请求)[0x00000]处
0中的System.Net.WebClient.ReadAll(System.Net.WebRequest请求,System.Object userToken)[0x00000]处
在System.Net.WebClient.UploadDataCore(System.Uri地址、System.String方法、System.Byte[]数据、System.Object userToken)[0x00000]中:0
在System.Net.WebClient.UploadData(System.Uri地址、System.String方法、System.Byte[]数据)[0x00000]中:0

这似乎是网络层应该处理的间歇性网络问题。这个问题随着后来的尝试而消失

证书无效。解决这个问题的唯一方法是捕获异常并重试请求,创建一个新的WebClient对象(当某些头被清除时)

我基本上把代码放在一个循环中,该循环多次尝试上传数据

int maxAttempts = 5;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
        if (attempt > 1) {
             // Wait a few seconds
             Thread.Sleep(new TimeSpan(0, 0, 10));
             Logger.Output(string.Format("Retrying request, try: {0}", attempt));
        }
        using (var webClient = new WebClient()) {
            webClient.Headers.Add("Content-Type", string.Format("multipart/form-data; boundary={0}", boundary));
            Logger.Output(webClient.Headers.ToString());
            var response1 = webClient.UploadData(address, "POST", buffer);
        }
        Logger.Output("Table {0} added successfully", table);
        break;
    } catch (WebException e) {
        // More logging here
        if (attempt == maxAttempts) {
            throw; // Re-throw it, clearly something is wrong if it fails x times.
        }
    }
}
int最大尝试次数=5;
for(int尝试=1;尝试1){
//等几秒钟
睡眠(新的时间跨度(0,0,10));
输出(string.Format(“重试请求,尝试:{0}”,尝试));
}
使用(var webClient=new webClient()){
Add(“内容类型”,string.Format(“多部分/表单数据;边界={0}”,边界));
输出(webClient.Headers.ToString());
var response1=webClient.UploadData(地址,“POST”,缓冲区);
}
输出(“表{0}添加成功”,表);
打破
}捕获(WebE例外){
//更多日志记录在这里
如果(尝试==最大尝试次数){
抛出;//重新抛出,如果失败x次,显然是出了问题。
}
}
}

验证或解密失败。可能是mono的错误,使用curl应该可以

尝试使用mono 2.10.9,但错误消息现在有所不同,请参见上面的堆栈跟踪。mono 3.x比2.x好一个数量级,请尝试3,而不是2。因为这是一个与HTTPS相关的问题,我建议您尝试捕获网络数据包,以查看TLS/SSL握手数据包是否可以判断罪魁祸首。在此之前,您可以运行
mozroot--import--sync
更新本地证书,然后重试。