def seek(self, offset, whence=0):
        """Seek to the specified position.

        :param int offset: The offset in bytes.
        :param int whence: Where the offset is from.

        Returns the position after seeking."""
        logger.debug('seeking to offset: %r whence: %r', offset, whence)
        if whence not in s3.WHENCE_CHOICES:
            raise ValueError('invalid whence, expected one of %r' % s3.WHENCE_CHOICES)

        if not self.seekable():
            raise OSError

        if whence == s3.START:
            new_pos = offset
        elif whence == s3.CURRENT:
            new_pos = self._current_pos + offset
        elif whence == s3.END:
            new_pos = self.content_length + offset

        new_pos = s3.clamp(new_pos, 0, self.content_length)

        if self._current_pos == new_pos:
            return self._current_pos

        logger.debug("http seeking from current_pos: %d to new_pos: %d", self._current_pos, new_pos)

        self._current_pos = new_pos

        if new_pos == self.content_length:
            self.response = None
            self._read_iter = None
            self._read_buffer.empty()
        else:
            response = self._partial_request(new_pos)
            if response.ok:
                self.response = response
                self._read_iter = self.response.iter_content(self.buffer_size)
                self._read_buffer.empty()
            else:
                self.response = None

        return self._current_pos
Seek to the specified position.

        :param int offset: The offset in bytes.
        :param int whence: Where the offset is from.

        Returns the position after seeking.