20
votes

My code making https request. This is my code

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(UploadUrl);
            request.Method = "POST";
            request.KeepAlive = false;
            request.Credentials = new NetworkCredential(userid, testpwd);

            postData = "<root></root>";
            request.ContentType = "application/x-www-form-urlencoded";

            byte[] postDataBytes = Encoding.UTF8.GetBytes(postData);
            request.ContentLength = postDataBytes.Length;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(postDataBytes, 0, postDataBytes.Length);
            requestStream.Close();

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                StreamReader responseReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                var result = responseReader.ReadToEnd();
                responseReader.Close();
                Console.WriteLine(result);
            }

This code was running good but all of a sudden throwing following exception

System.Net.WebException

The exception message is: The underlying connection was closed: An unexpected error occurred on a send.

Stack Trace: at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context) at System.Net.HttpWebRequest.GetRequestStream() at CustomerProcessor.Delivery.Deliver(String content, Int32 productCategory, String identifier, String xsltFile)

The Exception has an inner exception: An Exception occurred: System.IO.IOException The exception message is: Received an unexpected EOF or 0 bytes from the transport stream.

Stack Trace: at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.TlsStream.CallProcessAuthentication(Object state) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 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)

Is there any chance to see what could be the cause of this issue?

5

5 Answers

23
votes

Adding this call before request helped me:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

So if you are using https try to change the default SecurityProtocol.

12
votes

Another potential cause of this - if you are running on Windows Server 2003 it supports only SSL 2.0, SSL 3.0, TLS 1.0. All of these protocols are now recommended to be disabled in light of recent exploits that have been found for these protocols, so you may find that a tightly secured server just can't be connected to from windows server 2003 whereas it will be fine from your development machine. There's nothing you can really do about this situation other than ask the destination server administrator's team to allow TLS1.0, or upgrade your production server.

Source of SSL support on Win2k3Server: http://blogs.msdn.com/b/kaushal/archive/2011/10/02/support-for-ssl-tls-protocols-on-windows.aspx

6
votes

This worked for me:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

I have put that line before creating the web request.

2
votes

My experienced is just as elRobbo described. I have to upgrade the Win2k3 server to Win2k8.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 

is only supported in .net 4.5, which is not supported in Win2k3...

0
votes

I have no idea why (especially since it goes against docs I've seen on the matter) but I've found that leaving out the assignment of RequestLength. Rather, just write to the request stream without setting the header.

This also has the advantage that:

using(Stream stm = req.GetRequestStream())
using(StreamWriter sw = new StreamWriter(stm))
{
  sw.Write(postData);
}

is to my mind simpler, along with having greater advantages in cases where the data is larger and written piece by piece, or comes from something like an XMLWriter that can be set up to write straight to the stream in question.