-
-
Notifications
You must be signed in to change notification settings - Fork 974
Support HEAD for static routes #2491
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?
Support HEAD for static routes #2491
Conversation
…pen/stat file for HEAD requests.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2491 +/- ##
===========================================
- Coverage 100.00% 99.94% -0.06%
===========================================
Files 64 64
Lines 7866 7871 +5
Branches 1078 1080 +2
===========================================
+ Hits 7866 7867 +1
- Misses 0 2 +2
- Partials 0 2 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Hi, this is a great start, thanks!
One thing that needs to be changed though, is that HEAD should actually perform stat() (but we don't need to open the file).
The response to a HEAD request should roughly mirror what is rendered in the case of GET, bar the actual content.
When in doubt, we can simply check what the popular Nginx (or any other popular all-round HTTP server, like Apache, Caddy, etc) does in one or another case.
We can start Nginx in a Docker container:
docker run --rm -it -p 8000:80 nginx
Then
HEAD http://localhost:8000/index.html
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 615
Content-Type: text/html
Date: Sun, 20 Jul 2025 17:51:29 GMT
Etag: "685adee1-267"
Last-Modified: Tue, 24 Jun 2025 17:22:41 GMT
Server: nginx/1.29.0HEAD http://localhost:8000/index.html 'If-None-Match:"685adee1-267"'
HTTP/1.1 304 Not Modified
Connection: keep-alive
Date: Sun, 20 Jul 2025 17:54:01 GMT
Etag: "685adee1-267"
Last-Modified: Tue, 24 Jun 2025 17:22:41 GMT
Server: nginx/1.29.0HEAD http://localhost:8000/index.html If-Modified-Since:"Tue, 24 Jun 2025 17:22:41 GMT"
HTTP/1.1 304 Not Modified
Connection: keep-alive
Date: Sun, 20 Jul 2025 17:53:25 GMT
Etag: "685adee1-267"
Last-Modified: Tue, 24 Jun 2025 17:22:41 GMT
Server: nginx/1.29.0HEAD http://localhost:8000/index.html Range:bytes=0-14
HTTP/1.1 206 Partial Content
Connection: keep-alive
Content-Length: 15
Content-Range: bytes 0-14/615
Content-Type: text/html
Date: Sun, 20 Jul 2025 17:54:49 GMT
Etag: "685adee1-267"
Last-Modified: Tue, 24 Jun 2025 17:22:41 GMT
Server: nginx/1.29.0To summarize, we need to render almost the same responses as to GET, but not include the actual content (and ideally not open the file in question, just perform a stat()).
I don't know what the best way to structure this is, but I would try to factor out metadata-methods like _is_not_modified to primarily accept a stat data structure, and then try to reuse as much as possible.
|
Note that we don't want to follow Nginx blindly here either, though 😈 Nginx's So I think our implementation is better in that aspect 🙂 |
|
@AbduazizZiyodov to summarize, in a pinch, conceptually it might be enough to do this for current_static_route_get_implementation(req, resp)
resp.stream.close()
resp.stream = NoneBut as discussed, ideally we would like to do Regardless of the chosen solution, we should be able to DRY the absolute majority of the implementation with |
|
@vytas7 That's also fine, but I guess if we won't "touch" file & keep "DRY" it'll be more satisfiable. I'm thinking about adding flag to existing |
|
agree with @vytas7 regarding status that should mirror the get |
|
@vytas7 What should we do regarding to
I might skip section related to |
|
That's a very good question @AbduazizZiyodov, and I don't have a definite answer yet, I need to reread the newest RFCs on the matter. Previously, my understanding was that we SHOULD render a |
|
@vytas7 As I mentioned, I'm thinking about setting it as |
|
@AbduazizZiyodov I have carefully reread the relevant part of RFC 9110 (9.3.2, HEAD), and I still stand by my original interpretation.
(emphasis mine ⬆️) To summarize, we should include |
|
@AbduazizZiyodov just checking if you're still working on this, or could we find new contributors from Hacktoberfest on this one? |
@vytas7 Hi, yes I am! I couldn't make progress a lot prev. month, however I'm sure I'll be able to make it ) |
|
@vytas7 Hi, can you verify current implementation ? I tried to achieve the goal with minimal changes/diff (+ DRY). I'll add test cases. |
Summary of Changes
PR is not complete for now, I wanted to have discussion along with development process.
What I did is that in static route call, I'm raising a method not allowed exception if req.method is not GET or HEAD (OPTIONS handled before that line). I also think that in OPTIONS request, we need to change it to that:
... if req.method == 'OPTIONS': # it's likely a CORS request. Set the allow header to the appropriate value. resp.set_header('Allow', 'GET, HEAD') # <- here resp.set_header('Content-Length', '0') return ...I did not committed it yet, there were some related tests to it, they kept failing. I will change them later (if above is correct).
As described in the issue, HEAD request should behave as GET, but file should not be opened (also doing "stat"), so I added little "switch" to open/stat file if req.method is get.
I wanted to know whether I'm in right track, previous tests are PASSING after that change. If implementation will become as expected, I will write tests for that.
Thanks.
Related Issues
#2337
Pull Request Checklist
This is just a reminder about the most common mistakes. Please make sure that you tick all appropriate boxes. Reading our contribution guide at least once will save you a few review cycles!
If an item doesn't apply to your pull request, check it anyway to make it apparent that there's nothing to do.
tox.docs/.docs/.versionadded,versionchanged, ordeprecateddirectives.docs/_newsfragments/, with the file name format{issue_number}.{fragment_type}.rst. (Runtowncrier --draftto ensure it renders correctly.)If you have any questions to any of the points above, just submit and ask! This checklist is here to help you, not to deter you from contributing!
PR template inspired by the attrs project.