Using HttpWebRequest to perform HTTPS post fails with strange error message
Recently, after upgrading a server to Server 2008, some developers (ok, about 15 developers and BAs) began complaining that a post to a 3rd party vendor was no longer functioning. One of the devs whipped up a winform app to test from the server and locally from his workstation. From his Windows XP workstation, it was fine. From the Server 2008 box (and from my Vista laptop) it failed to connect with:
The underlying connection was closed: An unexpected error occurred on a send.
Descriptive.
A full stack trace revealed:
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. —> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
— End of inner exception stack trace —
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
The underlying connection was closed: An unexpected error occurred on a send.
at System.Net.HttpWebRequest.GetRequestStream()
Keep in mind that this worked fine on XP and 2003. Vista and 2008 always threw that exception…without exception. The code was just doing a basic XML post to an HTTPS service with authentication enabled.
ASCIIEncoding ascii = new ASCIIEncoding();
string requestToSend = body;
byte[] data = ascii.GetBytes(requestToSend);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(destination);
webRequest.Credentials = new NetworkCredential("User", "Pass");
webRequest.Method = "POST";
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2";
webRequest.ContentType = "text/xml";
webRequest.ContentLength = data.Length;
webRequest.KeepAlive = false;
//Throws an exception HERE
Stream outStream = webRequest.GetRequestStream();
outStream.Write(data, 0, data.Length);
outStream.Close();
From that stack trace, I could see that the remote server was closing the connection…but, I had no idea why. Something in how it made the request was different than XP or 2003.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
As it turns out, the defult behavior in Vista and Server 2008 is to use TLS first for secure connections. If the server doesn’t support TLS, it’s supposed to negotiate with the client to use SSL3. In this case, the remote server wasn’t negotiating at all…It was just dropping the connection.
http://blogs.msdn.com/wndp/archive/2006/04/12/tls_enabled_by_default.aspx
Long story short:
If you upgrade to Server 2008 or Vista, and your HTTPS XML POSTs are failing due to some strange error, try to force SSL3.





