Skip to content

http: fix keep-alive not timing out after post-request empty line #58178

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

islandryu
Copy link
Contributor

Fixes: #58140

As shown in the test code, sending an empty line after a request can result in a state where the keep-alive timer is reset, but neither requestTimeout nor keepAliveTimeout is active.
Unless a custom timeout is implemented, this allows the client to hold the socket indefinitely.

Modified behavior so that data like an empty line, which does not indicate the start of an HTTP message, no longer resets the keep-alive timeout.

FYI

Here is the behavior of other HTTP servers:

nginx: When client_header_timeout is set, sending an empty line after a request triggers a 408 timeout response once the timeout period expires.

Apache: When RequestReadTimeout header=5-10,MinRate=500 is configured, the connection times out after the specified duration, but no error code is sent.

However, since the timing for resetting the keep-alive timeout is not clearly defined in RFC 9112 or similar specifications, I believe this change is appropriate.

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels May 5, 2025
@islandryu
Copy link
Contributor Author

node/lib/_http_server.js

Lines 1040 to 1041 in c46b2b9

function parserOnIncoming(server, socket, state, req, keepAlive) {
resetSocketTimeout(server, socket, state);

The timing for resetting the keep-alive timeout should be limited to this part—specifically, when llhttp determines that parsing is necessary.

Copy link

codecov bot commented May 5, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.13%. Comparing base (a36981a) to head (350b680).
Report is 121 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #58178      +/-   ##
==========================================
- Coverage   90.21%   90.13%   -0.09%     
==========================================
  Files         630      630              
  Lines      186391   186782     +391     
  Branches    36608    36654      +46     
==========================================
+ Hits       168161   168357     +196     
- Misses      11052    11203     +151     
- Partials     7178     7222      +44     
Files with missing lines Coverage Δ
lib/_http_server.js 97.06% <ø> (-0.01%) ⬇️

... and 78 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ShogunPanda ShogunPanda added the request-ci Add this label to start a Jenkins CI on a PR. label May 5, 2025
@github-actions github-actions bot added request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. and removed request-ci Add this label to start a Jenkins CI on a PR. labels May 5, 2025
Copy link
Contributor

github-actions bot commented May 5, 2025

Failed to start CI
   ⚠  No approving reviews found
   ✘  Refusing to run CI on potentially unsafe PR
https://github.com/nodejs/node/actions/runs/14841662619


server.listen(0);

const client = connect({
Copy link
Member

Choose a reason for hiding this comment

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

I would create the connection after the server emits the 'listening' event.

}, 100);

client.on('data', (data) => {
const status = data.toString().split(' ')[1];
Copy link
Member

Choose a reason for hiding this comment

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

There is no guarantee that all data will be received in a single chunk.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thx, fixed test code.

Copy link
Contributor

@ShogunPanda ShogunPanda left a comment

Choose a reason for hiding this comment

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

LGTM!

@ShogunPanda ShogunPanda added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. labels May 9, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label May 9, 2025
@nodejs-github-bot
Copy link
Collaborator

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

Lgtm

@mcollina mcollina added the commit-queue Add this label to land a pull request using GitHub Actions. label May 9, 2025
@nodejs-github-bot
Copy link
Collaborator

@RafaelGSS RafaelGSS added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label May 9, 2025
@nodejs-github-bot nodejs-github-bot added commit-queue-failed An error occurred while landing this pull request using GitHub Actions. and removed commit-queue Add this label to land a pull request using GitHub Actions. labels May 9, 2025
@nodejs-github-bot
Copy link
Collaborator

Commit Queue failed
- Loading data for nodejs/node/pull/58178
✔  Done loading data for nodejs/node/pull/58178
----------------------------------- PR info ------------------------------------
Title      http: fix keep-alive not timing out after post-request empty line (#58178)
   ⚠  Could not retrieve the email or name of the PR author's from user's GitHub profile!
Branch     islandryu:fix/httpEmptyLine -> nodejs:main
Labels     http, author ready, needs-ci
Commits    2
 - http: fix keep-alive not timing out after post-request empty line
 - fix test
Committers 1
 - islandryu <[email protected]>
PR-URL: https://github.com/nodejs/node/pull/58178
Fixes: https://github.com/nodejs/node/issues/58140
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/58178
Fixes: https://github.com/nodejs/node/issues/58140
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Mon, 05 May 2025 08:46:23 GMT
   ✔  Approvals: 2
   ✔  - Paolo Insogna (@ShogunPanda) (TSC): https://github.com/nodejs/node/pull/58178#pullrequestreview-2829062997
   ✔  - Matteo Collina (@mcollina) (TSC): https://github.com/nodejs/node/pull/58178#pullrequestreview-2829334728
   ✘  Last GitHub CI failed
   ℹ  Last Full PR CI on 2025-05-09T18:21:27Z: https://ci.nodejs.org/job/node-test-pull-request/66736/
- Querying data for job/node-test-pull-request/66736/
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  Aborted `git node land` session in /home/runner/work/node/node/.ncu
https://github.com/nodejs/node/actions/runs/14936022305

@ShogunPanda
Copy link
Contributor

@islandryu Can you please fix failing test so we can move this forward?

@islandryu
Copy link
Contributor Author

@ShogunPanda
Sorry, I should have mentioned you, but I’ve already made the fix here.
#58324

Separately, I used to be able to view the Jenkins results until recently, but now I’m getting a permission error and can no longer access them.
Do you know what might be causing this?

@lpinca
Copy link
Member

lpinca commented May 15, 2025

CI is under security embargo.

@ShogunPanda
Copy link
Contributor

No worries, let's wait for the other PR to land and then you can rebase this.

About your question, maybe @nodejs/build-infra has some idea?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-failed An error occurred while landing this pull request using GitHub Actions. http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timers headersTimeout and requestTimeout not restarted on keep-alive HTTP connections
6 participants