Factor out request logic into two functions
Rewrite without obtainJS

The new API is a subset of obtainJS's: the ‘async’ argument is a flag,
and if truthy, a Promise is returned.

The implementation is a third of its original size (counting with cloc).