Reputation: 3964
I'm posting some data to the server but the application is throwing exception. Here's the code.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
Dim bytes As Byte() = Encoding.UTF8.GetBytes(xml)
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
request.Method = "POST"
request.ContentLength = bytes.Length
request.ContentType = "text/xml"
Using requestStream As Stream = request.GetRequestStream()
requestStream.Write(bytes, 0, bytes.Length)
End Using
Here's the exception stacktrace.
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
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)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
I've updated my code as per the answer/s here but to no avail. I've also checked that the proxy server has been disconnected.
Upvotes: 2
Views: 3605
Reputation: 82136
The highest enabled TLS version of the .NET framework you are using on the client-side is incompatible with the current TLS version used by the server.
This is causing an empty response.
System.Net.WebException: The underlying connection was closed:
An unexpected error occurred on a send. ---> System.IO.IOException:
Received an unexpected EOF or 0 bytes from the transport stream. at
System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
You either need to update your .NET framework, or enable TLS-compatibility in the registry,
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
or enable it in your .NET code using System.Net.ServicePointManager.SecurityProtocol
.
e.g.
namespace Gdp
{
public static class TlsFix
{
public static void UseLatestAvailableSslProtocol()
{
try
{
// Using TLS 1.3
System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)12288 | (System.Net.SecurityProtocolType)3072 | (System.Net.SecurityProtocolType)768 | System.Net.SecurityProtocolType.Tls;
System.Console.WriteLine("Using TLS 1.3");
}
catch (System.NotSupportedException) // exNoTls13'
{
try
{
// Using TLS 1.2
System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072 | (System.Net.SecurityProtocolType)768 | System.Net.SecurityProtocolType.Tls;
System.Console.WriteLine("Using TLS 1.2");
}
catch (System.NotSupportedException) // exNoTls12
{
try
{
// Using TLS 1.1
System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)768 | System.Net.SecurityProtocolType.Tls;
System.Console.WriteLine("Using TLS 1.1");
}
catch (System.NotSupportedException) // exNoTls11
{
// Using TLS 1.0
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;
} // End Catch TLS 1.1
} // End Catch TLS 1.2
} // End Catch TLS 1.3
} // End Sub UseLatestAvailableSslProtocol
} // End Class TlsFix
} // End Namespace
If you are using an old version of .NET-Core, you can set this in the HttpClientHandler that you pass to your HttpClient
internal class HttpClientHelper
{
public static System.Net.Http.HttpClient Factory()
{
// For .NET 5.0+
System.Net.Http.HttpClientHandler handler = new System.Net.Http.HttpClientHandler
{
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 |
System.Security.Authentication.SslProtocols.Tls13
};
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(handler);
return client;
} // End Function Factory
} // End Class HttpClientHelper
TLS 1.1 is deprecated.
There are also plans to deprecate obsolete key-exchange methods in TLS 1.2.
So you better upgrade to TLS 1.3 STAT/ASAP.
(and by the way, Google Chrome has already dropped support for TLS 1.1 in Version 72+, and planned removal in Chrome 81 anno 2020)
Upvotes: 0
Reputation: 3964
I was able to find that the server that I was POST
ing to was only accepting requests having security protocol TLS 1.1 and above. The application is running on .NET 3.5 which only supports SSL and TLS 1.0 protocols. The solution will be to upgrade the application to .NET 4.5 and use TLS 1.1 and above to make requests to the HTTP service.
Upvotes: 1