Iterator generator that iterates over chunks in specified range

    This generator is meant to be used when returning file descriptor as a
    response to Range request (byte serving). It limits the reads to the region
    specified by ``offset`` (in bytes form start of the file) and ``limit``
    (number of bytes to read), and returns the file contents in chunks of
    ``chunk`` bytes.

    The read offset is set either by using the file descriptor's ``seek()``
    method, or by using ``emulate_seek()`` function if file descriptor does not
    implement ``seek()``.

    The file descriptor is automatically closed when iteration is finished.

def range_iter(fd, offset, length, chunk=CHUNK):
    """ Iterator generator that iterates over chunks in specified range

    This generator is meant to be used when returning file descriptor as a
    response to Range request (byte serving). It limits the reads to the region
    specified by ``offset`` (in bytes form start of the file) and ``limit``
    (number of bytes to read), and returns the file contents in chunks of
    ``chunk`` bytes.

    The read offset is set either by using the file descriptor's ``seek()``
    method, or by using ``emulate_seek()`` function if file descriptor does not
    implement ``seek()``.

    The file descriptor is automatically closed when iteration is finished.
    """
    force_seek(fd, offset, chunk)
    while length > 0:
        ret = fd.read(chunk)
        if not ret:
            return
        length -= chunk
        yield ret
    fd.close()