def get_ranges(headervalue, content_length):
    """Return a list of (start, stop) indices from a Range header, or None.

    Each (start, stop) tuple will be composed of two ints, which are
    suitable for use in a slicing operation. That is, the header "Range:
    bytes=3-6", if applied against a Python string, is requesting
    resource[3:7]. This function will return the list [(3, 7)].

    If this function returns an empty list, you should return HTTP 416.
    """
    if not headervalue:
        return None

    result = []
    bytesunit, byteranges = headervalue.split('=', 1)
    for brange in byteranges.split(','):
        start, stop = [x.strip() for x in brange.split('-', 1)]
        if start:
            if not stop:
                stop = content_length - 1
            start, stop = int(start), int(stop)
            if start >= content_length:
                # From rfc 2616 sec 14.16:
                # "If the server receives a request (other than one
                # including an If-Range request-header field) with an
                # unsatisfiable Range request-header field (that is,
                # all of whose byte-range-spec values have a first-byte-pos
                # value greater than the current length of the selected
                # resource), it SHOULD return a response code of 416
                # (Requested range not satisfiable)."
                continue
            if stop < start:
                # From rfc 2616 sec 14.16:
                # "If the server ignores a byte-range-spec because it
                # is syntactically invalid, the server SHOULD treat
                # the request as if the invalid Range header field
                # did not exist. (Normally, this means return a 200
                # response containing the full entity)."
                return None
            result.append((start, stop + 1))
        else:
            if not stop:
                # See rfc quote above.
                return None
            # Negative subscript (last N bytes)
            #
            # RFC 2616 Section 14.35.1:
            #   If the entity is shorter than the specified suffix-length,
            #   the entire entity-body is used.
            if int(stop) > content_length:
                result.append((0, content_length))
            else:
                result.append((content_length - int(stop), content_length))

    return result
Return a list of (start, stop) indices from a Range header, or None.

    Each (start, stop) tuple will be composed of two ints, which are
    suitable for use in a slicing operation. That is, the header "Range:
    bytes=3-6", if applied against a Python string, is requesting
    resource[3:7]. This function will return the list [(3, 7)].

    If this function returns an empty list, you should return HTTP 416.
    
cherrypy/lib/httputil.py