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.
> I guess it's idiomatic in go to return the zero value for the given type
> in the case the function returns an error. If there is an error, the value is ignored anyway.

+1