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