class Excon::Socket

def write_nonblock(data)

def write_nonblock(data)
  data = binary_encode(data)
  loop do
    written = nil
    begin
      # I wish that this API accepted a start position, then we wouldn't
      # have to slice data when there is a short write.
      written = @socket.write_nonblock(data)
    rescue Errno::EFAULT => error
      if OpenSSL.const_defined?(:OPENSSL_LIBRARY_VERSION) && OpenSSL::OPENSSL_LIBRARY_VERSION.split(' ')[1] == '1.0.2'
        msg = "The version of OpenSSL this ruby is built against (1.0.2) has a vulnerability
               which causes a fault. For more, see https://github.com/excon/excon/issues/467"
        raise SecurityError.new(msg)
      else
        raise error
      end
    rescue OpenSSL::SSL::SSLError, *WRITE_RETRY_EXCEPTION_CLASSES => error
      if error.is_a?(OpenSSL::SSL::SSLError) && error.message != 'write would block'
        raise error
      else
        select_with_timeout(@socket, :write) && retry
      end
    end
    # Fast, common case.
    break if written == data.size
    # This takes advantage of the fact that most ruby implementations
    # have Copy-On-Write strings. Thusly why requesting a subrange
    # of data, we actually don't copy data because the new string
    # simply references a subrange of the original.
    data = data[written, data.size]
  end
end