Problem
When connecting to AWS IoT by "MQTT over WebSocket". To authenticate, we need to pre-sign the URL by AWS v4 signer. The signing process basically appends a bunch of query strings to the URL.
One of the query string parameters looks like this: X-Amz-Credential=keyid%2Fdate%2Fregion%2Fservice%2Faws4_req
It's encoded because the parameter contains slashes. It can be decoded to X-Amz-Credential=keyid/date/region/service/aws4_req
But the ipv6 zone identifier migration in ClientOptions#AddBroker, coming from bb7927e replaces all % in the URL to %25, which escapes all % in the URL even though the percentage sign itself is an escape.
https://github.com/eclipse/paho.mqtt.golang/blob/72d51366a6cf8fd0954a5991c03885915135dff8/options.go#L147
After the replacement, X-Amz-Credential=keyid%2Fdate%2Fregion%2Fservice%2Faws4_req becomes X-Amz-Credential=keyid%252Fdate%252Fregion%252Fservice%252Faws4_req, which will be decoded to X-Amz-Credential=keyid%2Fdate%2Fregion%2Fservice%2Faws4_req and the AWS will complain invalid credential.
Expected Behavior
url.Parse from Golang seems to have trouble with the zone identifier in the past. Here's the ticket
RFC6874 specifies how the zone identifier in the URI should be handled.
In section 2:
According to URI syntax [RFC3986], "%" is always treated as
an escape character in a URI, so, according to the established URI
syntax [RFC3986] any occurrences of literal "%" symbols in a URI MUST
be percent-encoded and represented in the form "%25". Thus, the
scoped address fe80::a%en1 would appear in a URI as
http://[fe80::a%25en1].
So perhaps the correct way is to remove the zone identifier mitigation and the users that intent to append the zone identifier in the URL should escape them properly before passing to ClientOptions#AddBroker
But I expect doing so will be a breaking change.
Problem
When connecting to AWS IoT by "MQTT over WebSocket". To authenticate, we need to pre-sign the URL by AWS v4 signer. The signing process basically appends a bunch of query strings to the URL.
One of the query string parameters looks like this:
X-Amz-Credential=keyid%2Fdate%2Fregion%2Fservice%2Faws4_reqIt's encoded because the parameter contains slashes. It can be decoded to
X-Amz-Credential=keyid/date/region/service/aws4_reqBut the ipv6 zone identifier migration in ClientOptions#AddBroker, coming from bb7927e replaces all
%in the URL to%25, which escapes all%in the URL even though the percentage sign itself is an escape.https://github.com/eclipse/paho.mqtt.golang/blob/72d51366a6cf8fd0954a5991c03885915135dff8/options.go#L147
After the replacement,
X-Amz-Credential=keyid%2Fdate%2Fregion%2Fservice%2Faws4_reqbecomesX-Amz-Credential=keyid%252Fdate%252Fregion%252Fservice%252Faws4_req, which will be decoded toX-Amz-Credential=keyid%2Fdate%2Fregion%2Fservice%2Faws4_reqand the AWS will complain invalid credential.Expected Behavior
url.Parsefrom Golang seems to have trouble with the zone identifier in the past. Here's the ticketRFC6874 specifies how the zone identifier in the URI should be handled.
In section 2:
So perhaps the correct way is to remove the zone identifier mitigation and the users that intent to append the zone identifier in the URL should escape them properly before passing to ClientOptions#AddBroker
But I expect doing so will be a breaking change.