riemann / riemann-ruby-client

A Ruby client for the Riemann event system
MIT License
65 stars 27 forks source link

Fix sending large batch of events over TLS #51

Closed smortex closed 1 year ago

smortex commented 1 year ago

When writing data over an OpenSSL::SSL::SSLSocket, we have two buffers that can fill-in: the TCPSocket and the SSLSocket.

However, SSLClient#write is a wrapper around TcpClient#write, and when it retry after caching a OpenSSL::SSL::SSLErrorWaitWritable it has no idea of the amount of data that got send and restart a full transfer of the data with TcpClient#write. When this happen, the new transfer can fail in a similar fashion any number of time and will eventually come to completion after sending multiple partial copies of the message followed by a complete copy, which is just garbage for Riemann on the other side. Riemann will discard the message and return an error that will be passed to the calling code.

In order to fix this, make TcpClient#write aware of IO::WaitWritable (a base class of OpenSSL::SSL::SSLErrorWaitWritable) and remove the SSLClient#write method so that the parent class method is used directly instead.

While here, do the same for TcpClient#read / SSLClient#read for consistency.

While here, also handle IO::WaitReadable exception in TcpClient#write to cope with TLS renegociation as recommended in the IO#select documentation.