Move upload target selection/management code to its own object.

Weighted selection will be a bit more complicated, and doing this makes
it easier to unit test the upload target selection/management code.
Ensure upload target URLs always end in a /.

HTTP uploads may not care, but rsync's behavior in

    (1) rsync -avz file rsync://example.com/module/foo

and

    (2) rsync -avz file rsync://example.com/module/foo/

are very different.  Example (1) copies file to *file* foo in the
module, overwriting the file if it exists; example (2) copies file into
*directory* foo in the module, creating that directory if it doesn't
exist.

(I don't recall an rsync client option to disable overwrites, but if
there is one, we should probably turn that on too.)