fix some uri edge cases in signing logic
fix some uri edge cases in signing logic

tl;dr fixes two uri encoding edge cases:
  1. Already encoded uris being passed for signing.
  2. +'s in query strings (which don't get encoded as '%2B' like normal)

---------------------------

How this change came about:

recently I was working on some horrible C code for work for signing
AWS V4 objects in S3. We ran into quite a number of issues from very
random pieces of data. Which caused us to sign things incorrectly.

although I don't think rusoto will ever recieve as random pieces of
data as we recieved, I figured why not see how rusoto handles these?
for some rusoto managed to get them right the first time (which was
exciting!), but for two cases it seemed to fail in the same way we did.

So I figured I might as well make a change to make signing work, and
so no one would have to dig through RFCs like we did.

-----------------------------

First Issue: Double Encoding

In certain cases we may get already uri encoded data! Someone may
have done it in their crate/code/however else they're passing in
the url to sign. this can happen not only in the uri, but in the
query strings as well.

in order to handle both cases, the easiest solution is to first
decode the uri, and then re-encode it from scratch. if the user
didn't pass in uri encoded data it becomes a no-op, and if the
user did pass in uri encoded data we decode it and re-encode it.
this is slightly less effecient, but allows us to handle both use
cases.

-----------------------------

Second Issue: Query String +'s

This one is a super weird issue, and really perplexed us. I'm sure
you're probably wondering "why don't we want to encode +'s as %2B
in query strings?"

Well the tl;dr is because RFCs say not to. Specifically Two RFCs:
  - https://tools.ietf.org/html/rfc2396#section-3.4
  - https://tools.ietf.org/html/rfc3986#appendix-D.2

Tl;dr "+" is a reserved chracater ONLY IN QUERY STRINGS for " ".
In the rest of the time it's an actual plus (though some people who
don't conform to RFCs use + as space in URIs as well, but that's
the wrong thing to do).

The Documentation doesn't really touch on this unfortunately, but
you can validate it manually with the aws cli (and other aws tools
out in this space).

Internally at my company we asked our AWS TAM to fix this
documentation so maybe it'll be updated there soon? But I think as
long as we have the same behavior as the CLI (and others) encoding
+'s as %20 in Query Strings only, we'll be okay.

DualSpark/rusoto,DualSpark/rust-aws,rusoto/rusoto,DualSpark/rusoto,SecurityInsanity/rusoto,rusoto/rusoto,SecurityInsanity/rusoto,DualSpark/rust-aws,DualSpark/rust-aws,mattico/rusoto,DualSpark/rusoto,mattico/rusoto,rusoto/rusoto,mattico/rusoto