npgsql: Read with timeout is incompatible with SslStream

As @Emill wrote in gitter, our current synchronous implementation of Wait() will fail if a timeout is passed and SslStream is used, because:

SslStream assumes that a timeout along with any other IOException when one is thrown from the inner stream will be treated as fatal by its caller. Reusing a SslStream instance after a timeout will return garbage. An application should Close the SslStream and throw an exception in these cases.

See http://stackoverflow.com/questions/37177401/how-to-repeatedly-read-from-net-sslstream-with-a-timeout.

Note sure if there’s a good workaround for SslStream. For now, adding a check that throws NotSupportedException.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 22 (22 by maintainers)

Commits related to this issue

Most upvoted comments

I agree. We can just let it do the timeout on netstandard2.0 (i.e. not block it), and if the user is on .NET Framework it’s their problem…

Well then… great! So I guess just conditionally-compile the check for net461?

I would also assume that it doesn’t work on .NET Core 3.1 because of dotnet/runtime#22496

It actually does work - results.

[Test]
public void WaitWithSsl()
{
	var csb = new NpgsqlConnectionStringBuilder(ConnectionString)
	{
		SslMode = SslMode.Require,
		TrustServerCertificate = true,
	};
	using (var conn = OpenConnection(csb.ToString()))
	{
		conn.ExecuteNonQuery("LISTEN notifytest");
		Assert.That(conn.Wait(1000), Is.EqualTo(false));
		Assert.That(conn.ExecuteScalar("SELECT 1"), Is.EqualTo(1));
	}
}

Oh, very good! If it also works for .NET 3.1 we could just close this issue because .NET Framework is on the way to a graveyard.

I think we can just conditional-compile the check to only throw for TFMs where the timeout doesn’t work (i.e. net461).