# File lib/excon/socket.rb, line 104
    def write(data)
      # We normally return from the return in the else block below, but
      # we guard that data is still something in case we get weird
      # values and String#[] returns nil. (This behavior has been observed
      # in the wild, so this is a simple defensive mechanism)
      while data
        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 => error
          if error.message == 'write would block'
            if IO.select(nil, [@socket], nil, @params[:write_timeout])
              retry
            else
              raise(Excon::Errors::Timeout.new("write timeout reached"))
            end
          end

          # If there is an unknown OpenSSL error, don't just swallow
          # it, raise it out.
          raise Excon::Errors::SocketError.new(error)
        rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable
          if IO.select(nil, [@socket], nil, @params[:write_timeout])
            retry
          else
            raise(Excon::Errors::Timeout.new("write timeout reached"))
          end
        else
          # Fast, common case.
          # The >= seems weird, why would it have written MORE than we
          # requested. But we're getting some weird behavior when @socket
          # is an OpenSSL socket, where it seems like it's saying it wrote
          # more (perhaps due to SSL packet overhead?).
          #
          # Pretty weird, but this is a simple defensive mechanism.
          return 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
    end