storage: support resumable uploads

## Do not merge

- [x] Allow a choice in `upload` and `createWriteStream` between simple/resumable upload technique
- [x] `upload`: Stat the incoming file for size, default to simple for < 5mb, resumable for > 5mb
- [x] `createWriteStream`: default to resumable uploads
- [x] Integrate { resumableThreshold: n } option on storage instantiation (defaults to 5mb)
- [ ] test integrity upload stream

RE: #298

`createWriteStream` uses the Resumable Upload API: http://goo.gl/jb0e9D.

The process involves these steps:

1. POST the file's metadata. We get a resumable upload URI back, then cache it with ConfigStore.
2. PUT data to that URI with a Content-Range header noting what position the data is beginning from. We also cache, at most, the first 16 bytes of the data being uploaded.
3. Delete the ConfigStore cache after the upload completes.

If the initial upload operation is interrupted, the next time the user uploads the file, these steps occur:

1. Detect the presence of a cached URI in ConfigStore.
2. Make an empty PUT request to that URI to get the last byte written to the remote file.
3. PUT data to the URI starting from the first byte after the last byte returned from the call above.

If the user tries to upload entirely different data to the remote file:

1. -- same as above --
2. -- same as above --
3. -- same as above --
4. Compare the first chunk of the new data with the chunk in cache. If it's different, start a new resumable upload (Step 1 of the first example).
Reminder to self to make sure this is how to write custom error objects. ApiError in lib/common/utils does this differently.