Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for querystrings (qs) #1437

Merged
merged 15 commits into from Mar 27, 2023
Merged

Better support for querystrings (qs) #1437

merged 15 commits into from Mar 27, 2023

Conversation

sladg
Copy link
Contributor

@sladg sladg commented Mar 3, 2023

PR based on #1383. Credits to @Nyholm.

This pull requests removed reliance on build-in parse_str function in favour of @otsch's https://github.com/crwlrsoft/query-string.

Allows to use dots and dashes in query parameters (won't covert them to underscores as parse_str does).

Fixes #756.

Makes #1042 and #1383 redundant.


Extra reading on dealing with parse_str:

@sladg
Copy link
Contributor Author

sladg commented Mar 3, 2023

@mnapoli I picked up on @Nyholm's work and switched to 3rd party solution. Let me know if this is up to the standards or some work is necessary on my end. Thanks!

Copy link
Contributor

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely.

Thank you. I got stuck with other things and it slipped my mind.
Im happy with the PR, I did two small comments.

composer.json Outdated Show resolved Hide resolved
src/Event/Http/HttpRequestEvent.php Outdated Show resolved Hide resolved
Copy link
Contributor

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you

@sladg
Copy link
Contributor Author

sladg commented Mar 4, 2023

Issue opened to address failing pipeline: crwlrsoft/query-string#4

@otsch
Copy link
Contributor

otsch commented Mar 23, 2023

@sladg Can I maybe help bringing it to Bref v2 as discussed in crwlrsoft/query-string#4?

@sladg sladg changed the base branch from master to v2 March 23, 2023 11:03
@mnapoli mnapoli changed the base branch from v2 to master March 23, 2023 11:03
@mnapoli
Copy link
Member

mnapoli commented Mar 23, 2023

I've changed the target for this PR to master (now that v2 is released).

@sladg could you rebase or merge master into your PR? That may make the build pass now.

@sladg sladg changed the base branch from master to v2 March 23, 2023 11:14
@sladg sladg changed the base branch from v2 to master March 23, 2023 11:14
@sladg
Copy link
Contributor Author

sladg commented Mar 23, 2023

@mnapoli got it! thought that the change did not work at first, anyways, let me rebase and I will be back in a second

@sladg
Copy link
Contributor Author

sladg commented Mar 23, 2023

@mnapoli rebased, we should be good to go :)

composer.json Outdated Show resolved Hide resolved
@@ -4,7 +4,7 @@
"type": "project",
"description": "Bref is a framework to write and deploy serverless PHP applications on AWS Lambda.",
"homepage": "https://bref.sh",
"keywords": ["bref", "serverless", "aws", "lambda", "faas"],
"keywords": [ "bref", "serverless", "aws", "lambda", "faas" ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated change shouldn't be included.

@sladg
Copy link
Contributor Author

sladg commented Mar 27, 2023

@mnapoli heya! checking if we can move forward with better qs support or there are some additional blockers :) thanks!

@sladg sladg requested a review from mnapoli March 27, 2023 12:11
@mnapoli
Copy link
Member

mnapoli commented Mar 27, 2023

All good, thank you for this beautiful work to everyone involved!

@aran112000
Copy link
Contributor

Seems this PR introduced a bug for a rare edge case; if you have duplicate query string keys, only the final value will be passed through, these aren't treated as an array as expected.

Just submitted a PR to resolve this here:
crwlrsoft/query-string#5

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

Seems this PR introduced a bug for a rare edge case;

Correct me if I'm wrong, but I think actually it didn't introduce that behavior? I think it already behaved that way in previous (1.x) versions of bref.

I tried this, with both (v1.7 and v2.0):

include 'vendor/autoload.php';

use Bref\Event\Http\HttpRequestEvent;

$requestEvent = new HttpRequestEvent([
    'rawQueryString' => 'foo=bar&foo=baz',
    'httpMethod' => 'GET',
    'version' => '2.0',
]);

var_dump($requestEvent->getQueryParameters());

$requestEvent = new HttpRequestEvent([
    'requestContext' => ['elb' => true, 'http' => ['method' => 'GET']],
    'queryStringParameters' => [
        'foo' => 'bar',
        'foo' => 'baz',
    ],
]);

var_dump($requestEvent->getQueryParameters());

And in both cases the output is:

array(1) {
  ["foo"]=>
  string(3) "baz"
}
array(1) {
  ["foo"]=>
  string(3) "baz"
}

And looking at the bref source code, I think changing this behavior, would also require a change in bref, because:

So, in the second situation the incoming array would already have to be ['foo' => ['bar', 'baz']], because an array with the same key twice isn't possible.

Further, I think it'd best to keep the current behavior and just use a query string like foo[]=bar&foo[]=baz in those situations. Generally I think there is no strict rule what foo=bar&foo=baz should result in, server implementations can solve it as they want. But I think in most implementations (e.g. laravel) it results in ['foo' => 'baz'].
Is this OK for you @mnapoli @aran112000 ?

@aran112000
Copy link
Contributor

aran112000 commented Apr 12, 2023

Correct me if I'm wrong, but I think actually it didn't introduce that behavior? I think it already behaved that way in previous (1.x) versions of bref.

Seems you're right 👍

And looking at the bref source code, I think changing this behavior, would also require a change in bref, because:

I don't believe that to be the case:

  1. Correct, this does now work with API Gateway V2 with the changes in the PR (this is also the default for Bref these days I believe @mnapoli ?)
  2. In other scenarios (ELB or API GW < 2), we have access to more in the Event payload (multiValueQueryStringParameters) which sorts this out from what I've seen in Bref and the tests coverage already there. I did start a PR for Bref earlier thinking that wasn't the case and closed it off after realising it already worked on older versions.

Further, I think it'd best to keep the current behaviour and just use a query string like foo[]=bar&foo[]=baz in those situations. Generally I think there is no strict rule what foo=bar&foo=baz should result in, server implementations can solve it as they want. But I think in most implementations (e.g. laravel) it results in ['foo' => 'baz'].

Completely agree the 'best' structure uses array notation[] on the parameters, but it's not uncommon to have query strings repeated. Even Google use it for Google Fonts for example when specifying multiple font families - for example:
https://fonts.googleapis.com/css2?family=Baloo&family=Roboto

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

  1. Correct, this does now work with API Gateway V2 with the changes in the PR

Yes, with API Gateway V2 I guess it would work with the changes from the PR, but I don't think it's a good idea if it works differently in different environments.

  1. In other scenarios (ELB or API GW < 2), we have access to more in the Event payload (multiValueQueryStringParameters) which sorts this out from what I've seen in Bref and the tests coverage already there. I did start a PR for Bref earlier thinking that wasn't the case and closed it off after realising it already worked on older versions.

OK, I just read a bit further on https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers and in the comments in bref's source. So, when multi-value is enabled, it reads like the multiValueQueryStringParameters already is an array like ['foo' => ['bar', 'baz']]. The crwlr/query-string is totally fine with that and wouldn't throw away any element, but actually bref converts it

So, maybe the solution in this case is to just create the crwlr Query instance directly from the multiValueQueryStringParameters array, because it actually does the same back and forth conversion that bref does, inside the Query object. I'll try this and maybe send a PR.

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

Addition: I'll consider accepting your PR to the crwlr/query-string package @aran112000 👍🏻 have to take a closer look.

@aran112000
Copy link
Contributor

So, maybe the solution in this case is to just create the crwlr Query instance directly from the array, because it actually does the same back and forth conversion that bref does, inside the Query object. I'll try this and maybe send a PR.

I tried this route, API GW 2 doesn't provide multiValueQueryStringParameters, which I why I went this route

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

I tried this route, API GW 2 doesn't provide multiValueQueryStringParameters, which I why I went this route

Yes, that's why I then added, that I consider accepting your PR as well 👍🏻 I'm currently reviewing it...would you mind if I do some minor changes instead of requesting changes?

@aran112000
Copy link
Contributor

Gotcha, sure thing. If I can help at all, just shout

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

@mnapoli we changed the behavior in crwlr/query-string => crwlrsoft/query-string#5
In bref I know see that there's one test case failing with the new version of the package. It's FpmHandlerLoadBalancerTest::test alb query strings encoded with multi value enabled(). Is this bad?

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

@mnapoli OK, I found that the change introduced a new bug 🙈 already working on the fix.

@otsch
Copy link
Contributor

otsch commented Apr 12, 2023

@mnapoli OK, the tests are succeeding again with crwlr/query-string 1.0.3

@mnapoli
Copy link
Member

mnapoli commented Apr 13, 2023

Awesome, thanks a lot @otsch!

So anyone running composer update will get the fix I guess 👍

@otsch
Copy link
Contributor

otsch commented Apr 13, 2023

@mnapoli Yes 👍🏻 and as 1.0.2 only was the latest version for about an hour, not a lot (if any) should have gotten that version.

otsch added a commit to otsch/bref that referenced this pull request Apr 13, 2023
Support for getting array structure from duplicate query string keys
without array syntax (brackets) was added in crwlr/query-string (v1.0.2)
as requested in the discussion of this PR
brefphp#1437.

Example:
foo=bar&foo=baz
becomes
['foo' => ['bar', 'baz']]

Add test case to make sure this actually works (and keeps working) in
bref.
@sladg sladg deleted the old-pr branch April 13, 2023 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Value of $_SERVER['QUERY_STRING] different when deployed
7 participants