c# - 通过 HTTPS 的 HttpWebRequest 的随机问题

标签 c# apache .net-3.5 https httpwebrequest

我们有一个应用程序使用 HttpWebRequest 通过 HTTPS(由 apache 前端处理)将数据发布到远程服务器。

大多数时候,一切正常。

有时,我们会遇到以下异常:

    WebException occured SecureChannelFailure ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
   at System.Net.HttpWebRequest.GetRequestStream()

但是这个异常被捕获了,应用程序稍后重试,一切又恢复正常(HTTPS 握手中肯定有什么东西失败了,我不知道是什么)。

最近,我们遇到了一个无法重现的新问题:

在网站端 (apache),我们有一个 HTTP 403,消息为“重新协商握手失败:客户端未接受!?”。

在 .NET 客户端,我们发生了静默崩溃(或者应用程序在没有超时的情况下卡住了,我说不出来)。我们唯一知道的是:应用程序正确处理的不是 WebException。 不幸的是,这部分代码没有足够的异常日志记录,我们无法使用 System.Net 跟踪轻松部署新版本的应用程序以调查握手。

有没有人知道可能是什么问题?

代码如下:

        HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;

        // set client certificate and server certificate validation callback
        ConfigureWebRequestSecurity(req); 

        req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");
        req.AutomaticDecompression = DecompressionMethods.GZip;
        req.Method = "POST";
        req.ContentType = "text/xml";
        req.ContentLength = data.Length;

        HttpWebResponse resp = null;
        try
        {
            using (Stream post = req.GetRequestStream())
            {
                post.Write(data, 0, data.Length);
            }

            resp = req.GetResponse() as HttpWebResponse;

            Log.Logger.DebugFormat("REST : HTTP Response={0}({1})", (int)resp.StatusCode, resp.StatusCode.ToString());

            if (!resp.StatusCode.Equals(HttpStatusCode.OK))
            {
                throw new MOServerErrorException("The server did not respond with status 200 (OK), but with " + resp.StatusCode);
            }
        }
        catch (WebException e)
        {
            string m = string.Format("REST : WebException occured {0}", e.Status.ToString());
            throw new MOServerErrorException(m, e);
        }
        finally
        {
            if (resp != null)
                resp.Close();
        }

编辑: 好的,我已经设法重现了这个问题。线程在 GetRequestStream() 中挂起。 这是堆栈:

    mscorlib.dll!System.Threading.WaitHandle.WaitOne(long timeout, bool exitContext) + 0x2f bytes   
    mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x25 bytes    
>   System.dll!System.Net.LazyAsyncResult.WaitForCompletion(bool snap) + 0xd3 bytes 
    System.dll!System.Net.Security.SslState.CheckEnqueueRead(byte[] buffer = {byte[4096]}, int offset = 0, int count = 4096, System.Net.AsyncProtocolRequest request) + 0x194 bytes 
    System.dll!System.Net.Security._SslStream.StartReading(byte[] buffer = {byte[4096]}, int offset = 0, int count = 4096, System.Net.AsyncProtocolRequest asyncRequest = null) + 0x6d bytes    
    System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest = null) + 0x6b bytes   
    System.dll!System.Net.TlsStream.Read(byte[] buffer, int offset, int size) + 0x58 bytes  
    System.dll!System.Net.PooledStream.Read(byte[] buffer, int offset, int size) + 0x1b bytes   
    System.dll!System.Net.Connection.SyncRead(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, bool userRetrievedStream = false, bool probeRead = true) + 0x12a bytes   
    System.dll!System.Net.Connection.PollAndRead(System.Net.HttpWebRequest request, bool userRetrievedStream) + 0x5a bytes  
    System.dll!System.Net.ConnectStream.PollAndRead(bool userRetrievedStream) + 0x1b bytes  
    System.dll!System.Net.HttpWebRequest.EndWriteHeaders(bool async) + 0xa2 bytes   
    System.dll!System.Net.HttpWebRequest.WriteHeadersCallback(System.Net.WebExceptionStatus errorStatus, System.Net.ConnectStream stream = {System.Net.ConnectStream}, bool async) + 0x16 bytes 
    System.dll!System.Net.ConnectStream.WriteHeaders(bool async) + 0x2d1 bytes  
    System.dll!System.Net.HttpWebRequest.EndSubmitRequest() + 0x82 bytes    
    System.dll!System.Net.HttpWebRequest.SetRequestSubmitDone(System.Net.ConnectStream submitStream) + 0xf7 bytes   
    System.dll!System.Net.Connection.CompleteConnection(bool async, System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}) + 0x158 bytes  
    System.dll!System.Net.Connection.CompleteStartConnection(bool async, System.Net.HttpWebRequest httpWebRequest) + 0x177 bytes    
    System.dll!System.Net.Connection.CompleteStartRequest(bool onSubmitThread, System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, System.Net.TriState needReConnect = True) + 0x9a bytes  
    System.dll!System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}) + 0x293 bytes   
    System.dll!System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, string connName = "S>1054081937") + 0x7c bytes    
    System.dll!System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint servicePoint) + 0xf9 bytes   
    System.dll!System.Net.HttpWebRequest.GetRequestStream(out System.Net.TransportContext context = null) + 0x1d3 bytes 
    System.dll!System.Net.HttpWebRequest.GetRequestStream() + 0xe bytes 

这里挂了,没有超时。听起来像是网络堆栈中的错误!!

最佳答案

似乎是 KB980817

我没有设法安装建议的修补程序(安装正常...但 System.dll 保持不变)。 作为一种解决方法,我使用 API 的异步版本(开始...结束)并自行管理超时。

关于c# - 通过 HTTPS 的 HttpWebRequest 的随机问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4936574/

相关文章:

c# - 如何在本地正确存储密码

php - Laravel 5.6 部署的应用程序路由给出 404 错误

c# - FirstOrDefault() 无法与 ??运算符(operator)

linux - 如果我是普通用户,我会收到一条错误消息,提示 :/var/run/renderd/renderd. sock 套接字绑定(bind)失败,否则一切正常?

Apache 代理 cookie 仅适用于第一个应用程序

c# - 无法将 IEnumerable<Triangle> 传递到正在寻找 IEnumerable<IShape> 的函数中

c# - 在对象数组中查找

c# - 将 T[] 转换为 IList<T> 有什么注意事项吗?

c# - 以 Win8.1 + Metro 为目标时使用 SharpDX 保存 Texture2D?