Okay I finally got around to updating our resource handlers that deal with things like streaming video and single byte range handling does seem to work but there are some catches. I wanted to document them here in case anyone else runs into them.
First, the Skip method does work as needed but your handler must still parse any range request headers and respond appropriately with the 206 status code, content-range and content-length headers. I was thinking those headers may be handled for me but they are not.
Second, there is a bad DCHECK that will cause debug builds to fail unnecessarily. In StreamReaderURLLoader::OnReaderSkipCompleted below the initial range request for "0-" meaning beginning of file to the end will cause expected_content_length to be negative as first_byte_position will be zero, last_byte_position will be -1 (unknown). This also happens in subsequent range requests such as "18000-" meaning byte 18000 to the end. Likewise that calculation results in -18000. I skipped the DCHECK in the debugger and all the code seems to work so I think that check needs to be removed or changed to handle the cases I mention. In fact, I'm not sure what expected_content_length is even needed for in that method.
- Code: Select all
void StreamReaderURLLoader::OnReaderSkipCompleted(int64_t bytes_skipped) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!byte_range_valid()) {
// Expected content length is unspecified.
HeadersComplete(net::HTTP_OK, -1);
} else if (bytes_skipped == byte_range_.first_byte_position()) {
// We skipped the expected number of bytes.
int64_t expected_content_length = byte_range_.last_byte_position() -
byte_range_.first_byte_position() + 1;
DCHECK_GE(expected_content_length, 0);
HeadersComplete(net::HTTP_OK, expected_content_length);
} else {
RequestComplete(bytes_skipped < 0 ? bytes_skipped : net::ERR_FAILED);
}
}