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

Do not set Content-Type if params are explicitly set to nil #212

Merged
merged 3 commits into from Feb 27, 2018

Conversation

barthez
Copy link
Contributor

@barthez barthez commented Nov 30, 2017

The breaking change was introduced with d016695 that disallows to send the payload with DELETE requests.

Make the request method skip setting default Content-Type header if params are explicitly set to nil.

It solves the problem from the #200, keeping a way to achieve goal requested in #132.

@barthez
Copy link
Contributor Author

barthez commented Nov 30, 2017

Hi @perlun, as you suggested, I've created a PR. Please review at any time convenient.

lib/rack/test.rb Outdated
# merge :params with the query string
if params = env[:params]
if params = params
Copy link
Contributor

Choose a reason for hiding this comment

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

Would an if params do the same thing as this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, just copy-paste error. Fixed!

The breaking change was introduced with d016695
that disallows to send the payload with DELETE requests.

Make the request method skip setting default Content-Type header
if params are explicitly set to `nil`.
@perlun
Copy link
Contributor

perlun commented Feb 27, 2018

Thanks @barthez, a great PR! I made some minor adjustments.

Merging now.

@perlun perlun merged commit 5b4bcb1 into rack:master Feb 27, 2018
@perlun
Copy link
Contributor

perlun commented Feb 27, 2018

New release out: https://github.com/rack-test/rack-test/releases/tag/v0.8.3 🎉

@rafaelfranca
Copy link

This broken compatibility with Rails in POST request.

Rails always pass nil as parameters unless you explicitly pass. This change made the content type in post requests to be nil too. I don't think params being nil should be the indicative to set the content type or not.

@perlun
Copy link
Contributor

perlun commented Mar 9, 2018

This broken compatibility with Rails in POST request.

Do you have some more details about this - some example code, or a GitHub issue in another repo that I can look at to investigate it further?

Rails always pass nil as parameters unless you explicitly pass. This change made the content type in post requests to be nil too. I don't think params being nil should be the indicative to set the content type or not.

I must say, I'm not 100% sure on this one.

If you are passing in nil as the parameters, you are effectively saying "I do not have a request body". Why would you provide a content type in such cases, and what would the appropriate value be?

RFC 7231 is unfortunately a bit vague in this regard:

A sender that generates a message containing a payload body SHOULD
generate a Content-Type header field in that message unless the
intended media type of the enclosed representation is unknown to the
sender.

So it's a bit open to interpretation.

Looking at other tools, curling with -d '' for "empty POST body" provides:

Content-Length: 0
Content-Type: application/x-www-form-urlencoded

I would argue that this is perhaps the simpler way, to always provide the content type regardless if we have a POST body or not. Content-Length: 0 will be used to indicate that it's empty, I have a vague remembrance of seeing a behavior like that elsewhere.

Will try to put in a PR for this asap.

@rafaelfranca
Copy link

If you are passing in nil as the parameters, you are effectively saying "I do not have a request body". Why would you provide a content type in such cases, and what would the appropriate value be?

You may have the request body in the rack.input env key.

I have a test for rack-test, I'll commit and push to a branch, but in Rails case the code is:

post '/foo', env: { 'rack.input' => SringIO.new('Something').b }

We can also fix this on the Rails said always passing the Content-Type header, but I wanted to point the backwards incompatible change in a patch release.

I agree that we should keep defaulting to application/x-www-form-urlencoded and set the Content-Length to 0 in those cases.

@perlun
Copy link
Contributor

perlun commented Mar 9, 2018

We can also fix this on the Rails said always passing the Content-Type header, but I wanted to point the backwards incompatible change in a patch release.

Thanks. According to SemVer, it's actually fine for a 0.x release - "anything can change at any time". But I agree it's not great. We will also try to reach 1.0 as soon as we can, so you can have something to rely on in a different way than a 0.x release can provide.

I agree that we should keep defaulting to application/x-www-form-urlencoded and set the Content-Length to 0 in those cases.

Yes - working on a patch/PR right now to that avail.

perlun added a commit that referenced this pull request Mar 9, 2018
...even when no parameters are provided (or the provided parameters are `nil`)

The long story:

- #132 changed the behavior for HTTP DELETE requests to behave like GET: put the parameters in the query string, and don't set the Content-Type. This change was merged in d016695
- This broke `rack-test` for certain people, which was highlighted in #200. Arguably, the change incorporated in d016695 was too brutal.
- #212 tried to sort it out, by not setting Content-Type if params are nil, and also reverting the change to put DELETE parameters in the query string. The first part of this (params being nil) caused issues for certain people.

So this PR now tries to once and for all sort this out by:

- Always setting `env['CONTENT_TYPE']`, even when params are `nil`.
- Adding more tests for how `CONTENT_TYPE` and `CONTENT_LENGTH` should behave; some of this does not come from us, but from Rack upstream.

I encourage everyone to give this a try before we merge, to ensure we don't have to revert once more.
perlun added a commit that referenced this pull request Mar 9, 2018
...even when no parameters are provided (or the provided parameters are `nil`)

The long story:

- #132 changed the behavior for HTTP DELETE requests to behave like GET: put the parameters in the query string, and don't set the Content-Type. This change was merged in d016695
- This broke `rack-test` for certain people, which was highlighted in #200. Arguably, the change incorporated in d016695 was too brutal.
- #212 tried to sort it out, by not setting Content-Type if params are nil, and also reverting the change to put DELETE parameters in the query string. The first part of this (params being nil) caused issues for certain people.

So this PR now tries to once and for all sort this out by:

- Always setting `env['CONTENT_TYPE']`, even when params are `nil`.
- Adding more tests for how `CONTENT_TYPE` and `CONTENT_LENGTH` should behave; some of this does not come from us, but from Rack upstream.
- Settles with the discussion in #220: if you are using `DELETE` and must use query params, put them manually in there like this: `delete '/foo?bar=baz'`. Arguably not very clean, but better than changing back and forth. `params` are overloaded in rack 0.x and will be so in 1.0 also. I am thinking that we should go with the excellent suggestion provided by @malacalypse in #200 to use dedicated `body` and `params` parameters in the long run (and probably use keyword parameters instead, but that's definitely a 2.x feature since it breaks all existing usage.) For now, I think we'll live with the ugliness.

I encourage everyone to give this a try before we merge, to ensure we don't have to revert once more.
@perlun
Copy link
Contributor

perlun commented Mar 9, 2018

See #223. Let's move the discussion there.

@rack rack locked as resolved and limited conversation to collaborators Mar 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants