class Excon::Socket

def write(data)

def write(data)
  if @nonblock
    if FORCE_ENC
      data.force_encoding('BINARY')
    end
    while true
      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 OpenSSL::SSL::SSLError, Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable => error
        if error.is_a?(OpenSSL::SSL::SSLError) && error.message != 'write would block'
          raise error
        else
          if IO.select(nil, [@socket], nil, @data[:write_timeout])
            retry
          else
            raise Excon::Errors::Timeout.new('write timeout reached')
          end
        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
  else
    begin
      Timeout.timeout(@data[:write_timeout]) do
        @socket.write(data)
      end
    rescue Timeout::Error
      raise(Excon::Errors::Timeout.new('write timeout reached'))
    end
  end
end