I wasn't correctly handling the case where the seekableReader had
cached a bunch of data, and then the caller sought backward and
subsequently read _less_ data than what was in the cache. I now
handle that, and have a new test to cover this case.
I hadn't tested the case where the caller tries to Read() into
buffer that has more space than needed. ioutil.ReadAll() does this,
so it's important that this work right.
By caching all reads from an io.Reader, you can make an io.ReadSeeker
out of it. MakeSeekable() actually returns something that is all of
io.Reader, io.Seeker and io.Closer, because the returned object
actually requires closing to clean up gracefully.