-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Collect env
processing into client_env.rb
#3582
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
base: master
Are you sure you want to change the base?
Conversation
245660e
to
415eb00
Compare
lib/puma/server.rb
Outdated
@@ -576,6 +576,7 @@ def lowlevel_error(e, env, status=500) | |||
|
|||
def response_to_error(client, requests, err, status_code) | |||
status, headers, res_body = lowlevel_error(err, client.env, status_code) | |||
res_body = ["Payload Too Large"] if status == 413 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double checking my understanding: So with this refactoring, the lowlevel_error
is called (and potentially a user specified lowlevel_error_handler
), which didn't happen before? In order to preserve the existing behaviour – the hard-coded response body Payload Too Large
we set the body here
Question: Should we even call lowlevel_error
at all when status_code
is 413? If we didn't run the user specified lowlevel_error_handler
before this refactoring, we probably shouldn't start doing it now.
A future (major?) Puma version could let the user specified lowlevel_error_handler
to control the full response for the "Payload Too Large" scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we introduce HttpParserError413
and raise that instead of HttpParserError
(we already have HttpParserError501
)? Then we can, in client_error
, call prepare_response
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or is the HttpParserError
raise at https://github.com/puma/puma/pull/3582/files#r1897406430 problematic, in that either "Payload Too Large" or some other error can happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is @error_status_code
important or can we get by without it? I mean, can we pass the status code when we raise HttpParserError
? I think that is a clearer interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re adding HttpParserError413
, I'm not sure about the idea of having error classes for every possible request error. That's why I added @error_status_code
. We might need to add something like @error_status_message
or something like it.
I didn't want this PR to touch error handling, but once I got into it, it couldn't be avoided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about changing the code to:
def response_to_error(client, requests, err, status_code)
# @todo remove sometime later
if status_code == 413
status = 413
res_body = ["Payload Too Large"]
headers = {}
else
status, headers, res_body = lowlevel_error(err, client.env, status_code)
end
prepare_response(status, headers, res_body, requests, client)
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that will do it
But we could also pass information via the error object? Instead of adding @error_status_message
, HttpParserError
could hold status code and the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we could also pass information via the error object?
I didn't state one goal, of which this is the start. I think 'ruby' error handling can be totally contained in the new method Client#process_env_body
. I'd like to contain it all within Client, except it will need the call to generate the response.
Re: 1f7a775 and 4f6b798, if done in one commit, git (on the command line, not github.com) can detect moved lines. That's really useful IMHO. |
lib/puma/client.rb
Outdated
def process_env_body | ||
if above_http_content_limit(@parser.body.bytesize) | ||
@http_content_length_limit_exceeded = true | ||
@error_status_code = 413 | ||
end | ||
temp = setup_body | ||
normalize_env | ||
req_env_post_parse | ||
if @error_status_code | ||
# @env[HTTP_CONNECTION] = 'close' | ||
raise HttpParserError | ||
end | ||
temp | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can @error_status_code
be anything other than 413 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not with this PR. Future PR's that consolidate the request error handling will probably add more values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that will do it
I added it and rebased.
415eb00
to
59b54fb
Compare
lib/puma/client.rb
Outdated
normalize_env | ||
req_env_post_parse | ||
if @error_status_code | ||
# @env[HTTP_CONNECTION] = 'close' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this, or is it a future TODO so you want to keep the reminder for it?
Questions about exception/error handling during request processing and up to and including calling the app. I believe there are four types of exceptions: A. A socket error. B. An invalid request is submitted which does not meet the specs for a proper request. C. A request is submitted which fails due to user defined constraints like D. The app raises an exception. Questions: 1. When is/should 2. Previous discussions have been concerned with ‘finger printing’ that Puma is the web server. If so, should all ‘production’ error responses not include a response body/content? 3. Should users have control over which error types are logged? Or, should all be logged? 4. Similar to above, should users have control over which error types generate a response via the |
|
I'm working on a significant update to this, currently cleaning up tests. When I'm finished, I'll help review PR's. |
d018dc6
to
b1827cb
Compare
Today's Puma has grown quite a bit from its origins. Over time, Back in October of 2020 (PR #2419),
Much of the code to modify and validate the Since the By encapsulating all the request code in There many tests that create an app to return a response of request env properties, send a single request, and then check the response. These can moved to Although not contained in this PR, renaming |
Not sure whether to open an issue regarding this. The issue is when should
Note that requests that are invalid based on 2 & 3 may be 'valid' requests, the limits may be set because they could be malicious requests. This PR isn't tagged |
ee2ab27
to
790e126
Compare
790e126
to
ea1d8e8
Compare
ea1d8e8
to
2c08d89
Compare
Description
Currently, code that processes the request
env
is contained in bothclient.rb
andrequest.rb
. Move the code toclient_env.rb
, and add an additional test filetest_request.rb
. This doesn't require creating a server.Will move more tests to the file, some from
test_puma_server.rb
and some fromtest_request_invalid.rb
.Closes #3540
Your checklist for this pull request
[ci skip]
to the title of the PR.#issue
" to the PR description or my commit messages.