Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

Parsed form urlencoded requests. #19

Merged
merged 1 commit into from Oct 3, 2016
Merged

Parsed form urlencoded requests. #19

merged 1 commit into from Oct 3, 2016

Conversation

nesl247
Copy link
Contributor

@nesl247 nesl247 commented Aug 1, 2016

I'm not sure why urlencoded requests weren't being parsed.

@@ -78,7 +78,7 @@ public function notApplicableProvider()
['GET', 'application/json'],
['HEAD', 'application/json'],
['OPTIONS', 'application/json'],
['POST', 'application/x-www-form-urlencoded'],
['GET', 'application/x-www-form-urlencoded'],
Copy link

Choose a reason for hiding this comment

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

Why was this test case Changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because this makes POST of application/x-www-form-urlencoded an applicable type, thus the test would break if I didn't change it.

@weierophinney
Copy link
Member

They don't need to be parsed in most cases.

Diactoros uses the value of $_POST to seed the body parameters by default when creating the initial server request, and the other psr-7 implementations I've seen in the wild do so as well. Adding that here duplicates the parsing, adding overhead.

@nesl247
Copy link
Contributor Author

nesl247 commented Aug 2, 2016

Are you saying $request->getBody()->getContents() is supposed to be returning an array (basically the value of $_POST)? Because that's not what I'm experiencing with zend-expressive at all.

Also, if they are doing that, it seems very wrong as getBody() should be the raw, unmodified contents shouldn't it? Otherwise what is the purpose of getParsedBody()?

@weierophinney
Copy link
Member

Are you saying $request->getBody()->getContents() is supposed to be returning an array

No, I'm saying $request->getParsedBody() should be returning the value of $_POST by default, if that value was populated at the time of the initial request. And that's the reason the FormUrlEncodedStrategy was not doing any parsing by default for POST requests (it's only needed for PUT and PATCH).

@nesl247
Copy link
Contributor Author

nesl247 commented Aug 2, 2016

I was not experiencing what you are saying. It wasn't until I made these changes that I got the values of $_POST. I used getParsedBody() before I even looked at the strategy thinking it was already doing this, and then when I saw it wasn't, I started working on this PR.

@weierophinney
Copy link
Member

weierophinney commented Aug 2, 2016

I'd argue that if we do this, the following should occur:

$parsed = $request->getParsedBody();

if (! empty($parsed)) {
    return $request;
}

$raw = $request->getBody()->getContents();
if (empty($raw)) {
    return $request;
}

parse_str($raw, $parsed);
return $request->withBodyParams($parsed);

This would ensure that parsing only happens (a) if the parsed body is empty AND (b) if we have raw body contents.

This would require:

  • Reverting the data provider change you made (it will still pass with the above changes)
  • Adding new test cases for the new behavior

UPDATED to separate the parse_str call from the withBodyParams() call.

@weierophinney
Copy link
Member

I was not experiencing what you are saying.

I've used this myself on several sites, and have it working exactly as I described. The only thing I can think of is that it may be a difference in web server or how you're creating the ServerRequest instance, as the ServerRequestFactory::fromGlobals() method populates the parsed body from $_POST by default.

Anyways, with the changes I suggest above, we would eliminate unnecessary double-parsing, while providing a way to parse if it's not populated.

@nesl247
Copy link
Contributor Author

nesl247 commented Aug 2, 2016

Ok, I'll work on the changes based on what you said. And your explanation is definitely the reason. It's actually a functional test client I created for an application where I'm having the issue. We build up the request and pass it to the application to run it as it makes it much quicker and easier than going against a real server.

With these changes, at least we'll be guaranteed that this middleware will work regardless of how the request was built, which I think is the right way to do it.

I'll get to work on these changes sometime this week then as I have to switch focus to another project for a bit.

Thanks!

@michaelmoussa
Copy link
Contributor

@nesl247 I've flagged this for 2.1.0 in hopes that I can wrap up the remainder of pending issues and PRs in that release. Please let me know if you need some help with this, or if you think you'll be able to make the discussed changes yourself before long.

This parses urlencoded requests when a request is not built from
`ServerRequestFactory::fromGlobals()`.
Copy link
Contributor

@michaelmoussa michaelmoussa left a comment

Choose a reason for hiding this comment

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

Looks good to me. Will be released with 2.1.0.

@michaelmoussa michaelmoussa merged commit d0ad160 into zendframework:master Oct 3, 2016
michaelmoussa added a commit that referenced this pull request Oct 3, 2016
michaelmoussa added a commit that referenced this pull request Oct 3, 2016
michaelmoussa added a commit that referenced this pull request Oct 3, 2016
michaelmoussa added a commit that referenced this pull request Oct 3, 2016
@nesl247 nesl247 deleted the feature/parse-form-requests branch October 3, 2016 14:15
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants