Fix base string generation for array params #148
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
When duplicate params are passed (like ['test' => [ '123', '456' ]]), the signature should not add numeric indices to the generated base string.
The default behavior of
EncodesUrl::baseString()
is to parse the URL query string usingparse_str
. This works well for most cases, but in the case where clients repeat param names with different values (which is valid and accounted for in RFC 5849 Section 3.4.1.3.2 item 2) it does not work properly.The Guzzle PSR-7 package provides
Query::parse()
that can handle query strings containing duplicate params. Calling code can strip the query string from the passed URL and thebaseString()
method can receive these as additional parameters:This should work, but the base string generation adds additional index numbers to the param name, causing signature generation to fail:
Solution
This PR changes the following:
parse_str
to work as before, but also allows using another library (like Guzzle) to parse query params and pass them in tobaseString()
.A new protected method
paramsFromData()
is added. The existing protected methodqueryStringFromData()
is maintained, although it is now unused.Background
Why does this matter? Multi-value parameters are an edge case, and for folks who can control all sides of the request signing, they can work within the confines of
parse_str
or modify requests to work. Folks attempting to integrate with producers/consumers using spec-compliant implementations written in other languages can't make these changes, and need this implementation to work per the RFC.