-
Notifications
You must be signed in to change notification settings - Fork 192
File response #256
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
File response #256
Conversation
|
As discussed in #255 that diff could be a solution already. The unit test could test on HTTP status NOT equal to 200 instead? Or test equal to 500? |
If `http_response::get_raw_response()` returns nullptr instead of a valid `MHD_Response*` for whatever reason, that pointer would be passed on to `http_response::decorate_response()` and `http_response::enqueue_response()` eventually, leading to different API calls to libmicrohttpd with NULL as argument `struct MHD_Response *response`. MHD does not guarantee any form of behaviour for invalid input, so we have to consider it undefined behaviour and avoid passing invalid input to MHD. HTTP status 500 (Internal Server Error) is returned for consistency with surrounding error handling, we don't know what caused `http_response::get_raw_response()` to return nullptr, so we can not give a better answer here. Fixes: etr#255
Both `open()` and `lseek()` might fail depending on how `filename` is set in object of class `httpserver::file_response()`. In the case of a missing file *fd* got -1 and lseek set *size* (which had the wrong type btw.) to 0xffffffff aka (off_t) -1. Passing an invalid file descriptor and a massively huge size value on to `MHD_create_response_from_fd()` might lead to unpredictable results depending how well libmicrohttpd treats such invalid values. Note: Before f9b7691 ("Use MHD_create_response_from_fd for files") `httpserver::http::load_file()` was used, which throws an exception in case a file can not be opened successfully. That exception would have lead to returning HTTP status 500 (Internal Server Error). References: etr#255
The constructor of class `httpserver::file_response` can be called with a `filename` pointing into the void, to a file which does not actually exist. The webserver should fail predictably in that case. References: etr#255
ddb09d7 to
103aedb
Compare
|
I force pushed a possible solution as discussed in #255, but did not change description etc. of this PR, yet. Should I? |
| size_t size = lseek(fd, 0, SEEK_END); | ||
| if (fd == -1) return nullptr; | ||
|
|
||
| off_t size = lseek(fd, 0, SEEK_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.
Type of size taking return value of lseek() should be off_t. That was introduced wrong with f9b7691. Could be fixed in a separate commit or just fixed here en passant.
|
I just discovered another problem: if that |
We should just manage this in the same way (direction = invalid) and express it in the documentation making it clear that only existing files (not directories) are acceptable.
Given the broad changes that are going to happen in this method, I think we can just do it in this change. |
61536f8 to
3089c89
Compare
It was possible before to pass a path to a directory, or a to a device file, or to basically any path. `open()` would happily open it. In case of a directory, `lseek()` returns LONG_MAX (0x7FFFFFFFFFFFFFFF) and `MHD_create_response_from_fd()` is invoked. To avoid such nonsense, we test the path now and allow regular files only. References: etr#255
3089c89 to
123d5db
Compare
|
Those unit test are very repetitive. Maybe that can be improved later? |
Yeah, I think it would be worth keeping a change to those in an isolated change. |
etr
left a comment
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 we also add information about the method new failing path in the README file?
This documents a possible pitfall for users when passing filename of not existing files. References: etr#255
The constructor of class `httpserver::file_response` can be called with a `filename` pointing to a directory instead of a regular file. The webserver should fail predictably in that case. References: etr#255
ce5960d to
81bcc4d
Compare
|
I updated the API doc to the constructor of the
Not sure in what direction that should go? There is this section Building responses to requests which describes the different flavors of http_response classes. The improved failure handling was in the |
|
In the section called "Building responses to requests" there is piece dedicated to the file_response.
Don't need to make it too complicated. I'd just change it as below (the diff is in bold):
|
Suggested-by: Sebastiano Merlino <sebastiano@hey.com> References: etr#255
|
Thanks! This was a great piece of improvement for the library. |
Requirements for Contributing a Bug Fix
Identify the Bug
See: #255
Description of the Change
Adds a unit test highlighting the bug, no real fix so far.
Alternate Designs
This snippet at least fixes the webserver to return a 500 Internal Server Error:
The unit test just fails different then, but that confirms the unit test itself is ok:
Possible Drawbacks
n.a.
Verification Process
Tested against multiple different version of libmicrohttpd.
Release Notes
n.a.