internal/v4: implement archive uploading

We don't yet verify bundles against charms in the store.

This required some refactoring of the testing code;
the most important change is AssertJSONCall actually
makes a real HTTP call through a socket, as that
allows us to correctly test the ContentLength logic.
It also gives us greater assurance that the logic
will work over a real HTTP connection. The overhead
seems to be negligible.
Good catch. We aren't using the sha256 name because the hash is not actually an sha256 hash.
It's a concatenation of sha256 and md5 hashes, because that's what the github.com/juju/blobstore
currently uses. I'm not fully satisfied what we're going to end up with, so we've left it as just "hash"
for the time being.

Currently, we do require the hash, so I think it should probably be "must" in the spec.