Compare commits

..

83 Commits

Author SHA1 Message Date
Ishita Singh
b4ab7d65d7 test: include edge case tests for res.type() (#7037) 2026-02-23 10:58:26 +01:00
Pavan Shinde
c4cc78bdf5 docs: fix README security policy link (#7029) 2026-02-21 22:15:11 -05:00
Dave Tashner
925a1dff1e fix: bump qs minimum to ^6.14.2 for CVE-2026-2391 (#7057)
qs versions before 6.14.2 have an arrayLimit bypass in comma parsing
that allows denial of service (GHSA-w7fw-mjwx-w883).

While the existing ^6.14.1 semver range allows 6.14.2 on fresh
installs, bumping the minimum ensures the vulnerable version cannot
be resolved.

Signed-off-by: davetashner <5702882+davetashner@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 22:11:08 -05:00
Murat Kirazkaya
9c85a25c02 Remove duplicate tests in res.location and res.jsonp (#6996)
* test: remove duplicated tests

* test: fix typo in data URI encoding test description
2026-02-14 12:25:36 -05:00
dependabot[bot]
1140301f6a build(deps): bump github/codeql-action from 4.31.9 to 4.32.0 (#7013)
* build(deps): bump github/codeql-action from 4.31.9 to 4.32.0

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.9 to 4.32.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](5d4e8d1aca...b20883b0cd)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: fix version tag comments

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Phillip Barta <barta.phillip@gmail.com>
2026-02-10 00:10:13 +01:00
dependabot[bot]
c76ed5ae05 build(deps): bump actions/setup-node from 6.1.0 to 6.2.0 (#7012)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](395ad32622...6044e13b5d)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-10 00:05:17 +01:00
dependabot[bot]
2d4192ebb3 build(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#7011)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8e8c483db8...de0fac2e45)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-10 00:04:00 +01:00
Sebastian Beltran
66404b347a docs: Add @GroophyLifefor to the triage team (#6995) 2026-02-01 13:04:08 +01:00
Viny Brun Kriesang
d12772393c fix: search example to support Redis v4+ and Express 4/5 (#6274)
* Fix Redis example to support Redis v4+ and Express 4/5

* update optional route syntax to /{:query} and refactor Redis initialization into dedicated function to guarantee that it is complete before server starts

---------

Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2026-01-31 22:12:23 -05:00
Ayoub Mabrouk
6b7ccfcf12 test: add test for normalizeType fallback when mime lookup fails (#6894)
Add test to verify that utils.normalizeType correctly defaults to
'application/octet-stream' when mime.lookup() returns null/undefined
for unknown file extensions. This covers the fallback behavior on
line 64 of lib/utils.js and ensures proper handling of unrecognized
MIME types.

Co-authored-by: bjohansebas <103585995+bjohansebas@users.noreply.github.com>
2026-01-31 21:53:38 -05:00
AkaHarshit
c9ecf7b658 feat: Allow passing null or undefined as the value for options in app.render (#6903)
* fix: allow null options in app.render

* fix: ensure options are initialized to an empty object in app.render

* docs: add history entry

---------

Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2026-01-31 21:51:17 -05:00
Sebastian Beltran
a479419b16 feat: do not modify the Content-Type twice when sending strings (#6991)
* fix: improve content-type handling in res.send method

* fix: ensure content-type is a string before setting charset in res.send

* fix: refactor content-type handling in res.send to use const and improve clarity

* Apply suggestion from @bjohansebas

* docs: update History.md
2026-01-19 09:56:53 -05:00
Sebastian Beltran
5a4568abfe chore: remove benchmarks directory (#6992) 2026-01-17 17:36:22 -05:00
sukdev24
912893c07c test: added unit tests for utils.compileETag to cover valid and invalid inputs (#6534)
* Added unit tests for utils.compileETag to cover valid and invalid inputs

* test: enhance compileETag tests for various input types

---------

Co-authored-by: sucem029 <sucem029@vippan-118.ad.liu.se>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2026-01-16 21:27:22 -05:00
Marcos Molina
ae265a90c7 docs: fix JSDoc for req.accepts() return value and parameter format (#6936)
* fixed request accept jsdoc

* reverted format

* reverted format

* updated jsdoc

* updated the rest of the documentation
2026-01-16 16:19:39 -05:00
Bernice Wu
9a3f7ff412 Polish HTML structure of the response in the res.redirect() function (#5167)
* structure the DOM body

* structure the DOM body

* test: add html title to redirect test

* fix: update HTML structure for include body and head tags

* docs: improve HTML structure in res.redirect() responses for better browser compatibility

---------

Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2026-01-16 10:29:01 -05:00
Sebastian Beltran
2cd372e34c docs: add @krzysdz to the triage team (#6482) 2026-01-12 10:28:54 +01:00
dependabot[bot]
04d3a49976 build(deps): bump actions/setup-node from 6.0.0 to 6.1.0 (#6962)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](2028fbc5c2...395ad32622)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 09:48:47 -05:00
dependabot[bot]
bc7d155f53 build(deps): bump actions/checkout from 6.0.0 to 6.0.1 (#6963)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](1af3b93b68...8e8c483db8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 09:47:41 -05:00
Gabriel Alves
00bb633ca6 deps: qs@^6.14.1 2026-01-07 15:46:37 +01:00
dependabot[bot]
3c0ad4e8dc build(deps): bump github/codeql-action from 4.31.6 to 4.31.9 (#6964)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.6 to 4.31.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fe4161a26a...5d4e8d1aca)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.31.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 09:46:20 -05:00
dependabot[bot]
4ae96bdf5e build(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0 (#6965)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](330a01c490...b7c566a772)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 09:45:47 -05:00
AbdelMonaam Aouini
6cd404eb28 fix: enhance req.acceptsCharsets method (#6088)
* fix: enhance req.acceptsCharsets method

* Update req.acceptsCharsets.js

---------

Co-authored-by: Monaam Aouini <abdelmonaem.aouini@mispay.co>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2026-01-07 09:41:34 -05:00
dependabot[bot]
3e81873b52 build(deps): bump actions/download-artifact from 6.0.0 to 7.0.0 (#6961)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](018cc2cf5b...37930b1c2a)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 09:38:53 -05:00
Jon Church
b5aae87594 doc: fix security.md link to point to security tab 2026-01-05 17:54:09 -05:00
Ulises Gascon
b8fc000f31 docs: use global Security policy
We should inherit https://github.com/expressjs/.github/blob/master/SECURITY.md directly.
2026-01-05 17:46:28 -05:00
Rick Markins
c2fb76e99f docs: add @rxmarbles to triagers (#6953) 2025-12-19 10:44:49 +01:00
ctcpip
9eb700151b 📝 add note to history 2025-12-09 09:32:11 -06:00
Ulises Gascon
dbac741a49 5.2.1 2025-12-01 15:27:35 -05:00
Ulises Gascon
697547cde6 Revert "sec: security patch for CVE-2024-51999"
This reverts commit 2f64f68c37.
2025-12-01 15:27:35 -05:00
Ulises Gascón
4007ad103b Release: 5.2.0 (#6920) 2025-12-01 17:17:31 +01:00
Chris de Almeida
2f64f68c37 sec: security patch for CVE-2024-51999 2025-12-01 17:15:17 +01:00
dependabot[bot]
ed0ba3f1dc build(deps): bump actions/checkout from 5.0.0 to 6.0.0 (#6928)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](08c6903cd8...1af3b93b68)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 13:13:45 +01:00
dependabot[bot]
8eace4603c build(deps): bump github/codeql-action from 4.31.2 to 4.31.6 (#6929)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.2 to 4.31.6.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](0499de31b9...fe4161a26a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.31.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 13:12:52 +01:00
dependabot[bot]
30bae81027 build(deps): bump coverallsapp/github-action from 2.3.6 to 2.3.7 (#6930)
Bumps [coverallsapp/github-action](https://github.com/coverallsapp/github-action) from 2.3.6 to 2.3.7.
- [Release notes](https://github.com/coverallsapp/github-action/releases)
- [Commits](648a8eb78e...5cbfd81b66)

---
updated-dependencies:
- dependency-name: coverallsapp/github-action
  dependency-version: 2.3.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 13:12:08 +01:00
Shivam Sharma
758d4355d4 deps: body-parser@^2.2.1 (#6922)
Includes the security patch for CVE-2025-13466
2025-11-26 15:19:57 +01:00
Sebastian Beltran
77bcd5274a docs: update emeritus triagers (#6890)
* docs: update emeritus triagers
---------

Co-authored-by: Ulises Gascón <ulisesgascongonzalez@gmail.com>
2025-11-25 11:32:32 +01:00
Sebastian Beltran
f33caf1f89 Nominate to @efekrskl for triage team (#6888)
* Nominate to @efekrskl for triage team

* Update Readme.md
2025-11-24 22:32:28 -05:00
TheMysterious
54af593b73 refactor: use cached slice in app.listen (#6897)
Signed-off-by: Tacit1 <tacitim5@gmail.com>
2025-11-23 18:52:16 -05:00
Phillip Barta
2551a7d8af docs: switch badges from badgen.net to shields.io (#6900) 2025-11-18 10:42:56 +01:00
dependabot[bot]
4453d83cca build(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 (#6868)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-01 10:46:37 +01:00
dependabot[bot]
db507669ca build(deps): bump github/codeql-action from 3.30.5 to 4.31.2 (#6869)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-01 10:45:51 +01:00
dependabot[bot]
374fc1a0f9 build(deps): bump actions/setup-node from 5.0.0 to 6.0.0 (#6870)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-01 10:45:07 +01:00
dependabot[bot]
1b196c8b82 build(deps): bump actions/download-artifact from 5.0.0 to 6.0.0 (#6871)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-01 10:44:12 +01:00
Phillip Barta
64e7373d69 ci: add node.js 25 to test matrix (#6843) 2025-10-16 13:51:39 +02:00
dependabot[bot]
e4fb370ad8 build(deps): bump actions/download-artifact from 4.3.0 to 5.0.0 (#6793)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 5.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](d3f86a106a...634f93cb29)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 14:44:02 +02:00
dependabot[bot]
60d4c16cc9 build(deps): bump actions/setup-node from 4.4.0 to 5.0.0 (#6794)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.4.0 to 5.0.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](49933ea528...a0853c2454)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 14:43:54 +02:00
dependabot[bot]
9e6760e186 build(deps): bump ossf/scorecard-action from 2.4.2 to 2.4.3 (#6795)
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.2 to 2.4.3.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](05b42c6244...4eaacf0543)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 14:43:45 +02:00
dependabot[bot]
ffa89f2ccf build(deps): bump github/codeql-action from 3.29.7 to 3.30.5 (#6796)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.29.7 to 3.30.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](51f77329af...3599b3baa1)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.30.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 14:40:08 +02:00
dependabot[bot]
b9b9f52b2f build(deps): bump actions/checkout from 4.2.2 to 5.0.0 (#6797)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 5.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](11bd71901b...08c6903cd8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 14:34:25 +02:00
Jean Burellier
9a7afb2886 chore: remove history.md from being packaged on publish (#6780) 2025-09-25 07:20:45 +02:00
dependabot[bot]
2eb42059f3 build(deps): bump github/codeql-action from 3.29.2 to 3.29.5 (#6675)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.29.2 to 3.29.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](181d5eefc2...51f77329af)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Co-authored-by: bjohansebas <103585995+bjohansebas@users.noreply.github.com>
2025-09-14 09:39:32 -05:00
Shivam Sharma
aa907945cd doc: update express app example (#6718) 2025-08-22 09:12:09 +02:00
Sebastian Beltran
89f198c6a5 lib: use req.socket over deprecated req.connection (#6705)
Signed-off-by: Sebastian Beltran <bjohansebas@gmail.com>
2025-08-21 10:05:29 -05:00
Shivam Sharma
d9a62f9833 chore: update git rules to ignore yarn.lock file (#6588)
Co-authored-by: Ulises Gascón <ulisesgascongonzalez@gmail.com>
2025-08-20 15:18:36 +02:00
Shivam Sharma
8f21493cc5 lint: add --fix flag to automatic fix linting issue (#6644)
* lint: add --fix flag to automatic fix linting issue

* add dedicated lint script
2025-08-12 17:58:13 -05:00
dependabot[bot]
6616e39d4d build(deps-dev): bump cookie-session from 2.1.0 to 2.1.1 (#6678)
Bumps [cookie-session](https://github.com/expressjs/cookie-session) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/expressjs/cookie-session/releases)
- [Changelog](https://github.com/expressjs/cookie-session/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/cookie-session/compare/v2.1.0...v2.1.1)

---
updated-dependencies:
- dependency-name: cookie-session
  dependency-version: 2.1.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 20:24:48 -05:00
dependabot[bot]
ed64290e4a build(deps-dev): bump morgan from 1.10.0 to 1.10.1 (#6679)
Bumps [morgan](https://github.com/expressjs/morgan) from 1.10.0 to 1.10.1.
- [Release notes](https://github.com/expressjs/morgan/releases)
- [Changelog](https://github.com/expressjs/morgan/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/morgan/compare/1.10.0...1.10.1)

---
updated-dependencies:
- dependency-name: morgan
  dependency-version: 1.10.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 20:24:22 -05:00
shubham oulkar
b52ff7ca60 update contributing and COC links (#6601) 2025-07-30 08:41:53 -05:00
Jon Church
9420cd3f9b doc: fix the Contributing.md link (#6653) 2025-07-21 19:14:33 -04:00
Sebastian Beltran
ef5f2e13ef ci: run CI when the markdown changes (#6632) 2025-07-15 21:27:50 -05:00
Sebastian Beltran
c5b8d55a6a feat: add deprecation warnings for redirect arguments undefined (#6405) 2025-07-14 22:18:10 -05:00
dependabot[bot]
7a9311216a build(deps): bump github/codeql-action from 3.28.18 to 3.29.2 (#6618)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.18 to 3.29.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](ff0a06e83c...181d5eefc2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-09 10:27:41 +02:00
mountdisk
b0ed15b452 chore: fix typo (#6609)
Signed-off-by: mountdisk <mountdisk@icloud.com.>
2025-07-04 09:47:31 -05:00
Shivam Sharma
3910323d09 chore: use node protocol for node builtin module (#6520)
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2025-07-02 21:33:10 -05:00
Shivam Sharma
98c85eb0dd chore: enforce explicit Buffer import and add lint rule (#6525)
Signed-off-by: Shivam Sharma <meshivam81@gmail.com>
2025-06-27 20:10:36 -05:00
dependabot[bot]
a039e49175 build(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.2 (#6548)
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](f49aabe0b5...05b42c6244)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 23:36:52 +02:00
dependabot[bot]
ffc562c7d1 build(deps): bump github/codeql-action from 3.28.16 to 3.28.18 (#6549)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.16 to 3.28.18.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](28deaeda66...ff0a06e83c)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 23:36:20 +02:00
Sebastian Beltran
52872b84ca fix(docs): move documentation and charters to the discussions and .github … (#6427)
* docs: move documentation and charters to the discussions and .github repository

* Update Readme.md
2025-06-09 15:34:53 -05:00
kgarg1
b8ab46594d test: add coverage for app.listen() variants (#6476)
* test: add coverage for app.listen() variants

- verify alternate signatures (port+host+backlog)
- verify server.address() shape

* fix linter issue

---------

Co-authored-by: kuldeep <kuldeep@wanclouds.net>
2025-05-28 19:26:16 -05:00
Shivam Sharma
fedd60e642 ci: allow manual triggering of workflow (#6515) 2025-05-28 19:16:44 -05:00
Mert Şişmanoğlu
99a0bd3354 ci: disable credential persistence for checkout actions (#6522)
Signed-off-by: Mert Şişmanoğlu <mertssmnoglu@gmail.com>
2025-05-28 18:55:05 -05:00
Noritaka Kobayashi
dfd1851245 test: fix typos in test descriptions (#6535) 2025-05-27 10:36:50 +02:00
Jon Church
9f4dbe3a13 chore: wider range for query test skip (#6512) 2025-05-15 11:40:26 -05:00
Phillip Barta
9784321e89 ci: update codeql config (#6488) 2025-05-09 15:29:27 +02:00
Phillip Barta
ee1ef41bd3 ci: add node.js 24 to test matrix (#6504) 2025-05-07 21:08:25 -05:00
dependabot[bot]
1ca803dd55 build(deps): bump actions/download-artifact from 4.2.1 to 4.3.0 (#6496)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.2.1 to 4.3.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](95815c38cf...d3f86a106a)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 23:02:23 +02:00
dependabot[bot]
73555815b9 build(deps): bump actions/setup-node from 4.3.0 to 4.4.0 (#6497)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.3.0 to 4.4.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](cdca7365b2...49933ea528)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 23:02:09 +02:00
dependabot[bot]
a1161b4686 build(deps): bump github/codeql-action from 3.28.13 to 3.28.16 (#6498)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.13 to 3.28.16.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](1b549b9259...28deaeda66)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 23:01:58 +02:00
dufucun
f9954dd317 fix(test): remove duplicate word (#6456)
Signed-off-by: dufucun <dufuchun@sohu.com>
2025-04-16 11:18:38 -05:00
Ashish Sharma
5da5a11a49 increased code coverage of utils.js file (#6386)
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
2025-04-10 20:57:43 -05:00
Ayoub Mabrouk
3dc96995df Refactor: simplify acceptsLanguages implementation using spread operator (#6137)
Refactored `req.acceptsLanguages` to use the spread operator for passing arguments directly to `accept.languages`, eliminating the need for `.apply`. This approach improves readability and streamlines the function call.
2025-04-10 20:49:23 -05:00
dependabot[bot]
fa40ecfe76 build(deps): bump github/codeql-action from 3.28.11 to 3.28.13 (#6429) 2025-04-04 21:53:14 -05:00
48 changed files with 450 additions and 1255 deletions

View File

@@ -8,3 +8,7 @@ rules:
indent: [error, 2, { MemberExpression: "off", SwitchCase: 1 }]
no-trailing-spaces: error
no-unused-vars: [error, { vars: all, args: none, ignoreRestSiblings: true }]
no-restricted-globals:
- error
- name: Buffer
message: Use `import { Buffer } from "node:buffer"` instead of the global Buffer.

View File

@@ -11,8 +11,7 @@ on:
paths-ignore:
- '*.md'
pull_request:
paths-ignore:
- '*.md'
workflow_dispatch:
permissions:
contents: read
@@ -28,9 +27,11 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
@@ -45,19 +46,19 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [18, 19, 20, 21, 22, 23]
node-version: [18, 19, 20, 21, 22, 23, 24, 25]
# Node.js release schedule: https://nodejs.org/en/about/releases/
name: Node.js ${{ matrix.node-version }} - ${{matrix.os}}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
@@ -79,7 +80,7 @@ jobs:
run: npm run test-ci
- name: Upload code coverage
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: coverage-node-${{ matrix.node-version }}-${{ matrix.os }}
path: ./coverage/lcov.info
@@ -92,14 +93,16 @@ jobs:
contents: read
checks: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install lcov
shell: bash
run: sudo apt-get -y install lcov
- name: Collect coverage reports
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: ./coverage
pattern: coverage-node-*
@@ -109,6 +112,6 @@ jobs:
run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./lcov.info
- name: Upload coverage report
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7
with:
file: ./lcov.info

View File

@@ -19,6 +19,7 @@ on:
branches: ["master"]
schedule:
- cron: "0 0 * * 1"
workflow_dispatch:
permissions:
contents: read
@@ -31,16 +32,25 @@ jobs:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [javascript, actions]
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0
with:
languages: javascript
languages: ${{ matrix.language }}
config: |
paths-ignore:
- test
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
@@ -61,6 +71,4 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
with:
category: "/language:javascript"
uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0

View File

@@ -13,7 +13,8 @@ on:
pull_request:
paths-ignore:
- '*.md'
workflow_dispatch:
permissions:
contents: read
@@ -36,12 +37,12 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
@@ -63,7 +64,7 @@ jobs:
run: npm run test-ci
- name: Upload code coverage
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: coverage-node-${{ matrix.node-version }}-${{ matrix.os }}
path: ./coverage/lcov.info
@@ -76,14 +77,16 @@ jobs:
contents: read
checks: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install lcov
shell: bash
run: sudo apt-get -y install lcov
- name: Collect coverage reports
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: ./coverage
pattern: coverage-node-*
@@ -93,6 +96,6 @@ jobs:
run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./lcov.info
- name: Upload coverage report
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7
with:
file: ./lcov.info

View File

@@ -32,12 +32,12 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
@@ -59,7 +59,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: SARIF file
path: results.sarif
@@ -67,6 +67,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0
with:
sarif_file: results.sarif

4
.gitignore vendored
View File

@@ -5,6 +5,10 @@ npm-shrinkwrap.json
*.log
*.gz
# Yarn
yarn-error.log
yarn.lock
# Coveralls
.nyc_output
coverage

View File

@@ -1,92 +0,0 @@
# Express Charter
## Section 0: Guiding Principles
The Express project is part of the OpenJS Foundation which operates
transparently, openly, collaboratively, and ethically.
Project proposals, timelines, and status must not merely be open, but
also easily visible to outsiders.
## Section 1: Scope
Express is a HTTP web server framework with a simple and expressive API
which is highly aligned with Node.js core. We aim to be the best in
class for writing performant, spec compliant, and powerful web servers
in Node.js. As one of the oldest and most popular web frameworks in
the ecosystem, we have an important place for new users and experts
alike.
### 1.1: In-scope
Express is made of many modules spread between three GitHub Orgs:
- [expressjs](https://github.com/expressjs/): Top level middleware and
libraries
- [pillarjs](https://github.com/pillarjs/): Components which make up
Express but can also be used for other web frameworks
- [jshttp](https://github.com/jshttp/): Low level HTTP libraries
### 1.2: Out-of-Scope
Section Intentionally Left Blank
## Section 2: Relationship with OpenJS Foundation CPC.
Technical leadership for the projects within the OpenJS Foundation is
delegated to the projects through their project charters by the OpenJS
Cross Project Council (CPC). In the case of the Express project, it is
delegated to the Express Technical Committee ("TC").
This Technical Committee is in charge of both the day-to-day operations
of the project, as well as its technical management. This charter can
be amended by the TC requiring at least two approvals and a minimum two
week comment period for other TC members or CPC members to object. Any
changes the CPC wishes to propose will be considered a priority but
will follow the same process.
### 2.1 Other Formal Project Relationships
Section Intentionally Left Blank
## Section 3: Express Governing Body
The Express project is managed by the Technical Committee ("TC").
Members can be added to the TC at any time. Any committer can nominate
another committer to the TC and the TC uses its standard consensus
seeking process to evaluate whether or not to add this new member.
Members who do not participate consistently at the level of a majority
of the other members are expected to resign.
## Section 4: Roles & Responsibilities
The Express TC manages all aspects of both the technical and community
parts of the project. Members of the TC should attend the regular
meetings when possible, and be available for discussion of time
sensitive or important issues.
### Section 4.1 Project Operations & Management
Section Intentionally Left Blank
### Section 4.2: Decision-making, Voting, and/or Elections
The Express TC uses a "consensus seeking" process for issues that are
escalated to the TC. The group tries to find a resolution that has no
open objections among TC members. If a consensus cannot be reached
that has no objections then a majority wins vote is called. It is also
expected that the majority of decisions made by the TC are via a
consensus seeking process and that voting is only used as a last-resort.
Resolution may involve returning the issue to committers with
suggestions on how to move forward towards a consensus. It is not
expected that a meeting of the TC will resolve all issues on its
agenda during that meeting and may prefer to continue the discussion
happening among the committers.
### Section 4.3: Other Project Roles
Section Intentionally Left Blank
## Section 5: Definitions
Section Intentionally Left Blank

View File

@@ -1,139 +0,0 @@
# Contributor Covenant Code of Conduct
As a member of the Open JS Foundation, Express has adopted the
[Contributor Covenant 2.0][cc-20-doc].
If an issue arises and you cannot resolve it directly with the parties
involved, you can report it to the Express project TC through the following
email: express-coc@lists.openjsf.org
In addition, the OpenJS Foundation maintains a Code of Conduct Panel (CoCP).
This is a foundation-wide team established to manage escalation when a reporter
believes that a report to a member project or the CPC has not been properly
handled. In order to escalate to the CoCP send an email to
coc-escalation@lists.openjsf.org.
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances
of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for
moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail
address, posting via an official social media account, or acting as an
appointed representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
express-coc@lists.openjsf.org. All complaints will be reviewed and
investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited
interaction with those enforcing the Code of Conduct, is allowed during this
period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
project community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant, version 2.0][cc-20-doc].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
[cc-20-doc]: https://www.contributor-covenant.org/version/2/0/code_of_conduct/
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -1,51 +0,0 @@
# Express Collaborator Guide
## Website Issues
Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
## PRs and Code contributions
* Tests must pass.
* Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
* If you fix a bug, add a test.
## Branches
Use the `master` branch for bug fixes or minor work that is intended for the
current release stream.
Use the correspondingly named branch, e.g. `5.0`, for anything intended for
a future release of Express.
## Steps for contributing
1. [Create an issue](https://github.com/expressjs/express/issues/new) for the
bug you want to fix or the feature that you want to add.
2. Create your own [fork](https://github.com/expressjs/express) on GitHub, then
checkout your fork.
3. Write your code in your local copy. It's good practice to create a branch for
each new issue you work on, although not compulsory.
4. To run the test suite, first install the dependencies by running `npm install`,
then run `npm test`.
5. Ensure your code is linted by running `npm run lint` -- fix any issue you
see listed.
6. If the tests pass, you can commit your changes to your fork and then create
a pull request from there. Make sure to reference your issue from the pull
request comments by including the issue number e.g. `#123`.
## Issues which are questions
We will typically close any vague issues or questions that are specific to some
app you are writing. Please double check the docs and other references before
being trigger happy with posting a question issue.
Things that will help get your question issue looked at:
* Full and runnable JS code.
* Clear description of the problem or unexpected behavior.
* Clear description of the expected result.
* Steps you have taken to debug it yourself.
If you post a question and do not outline the above items or make it easy for
us to understand and reproduce your issue, it will be closed.

View File

@@ -1,245 +0,0 @@
# Express.js Community Contributing Guide 1.0
The goal of this document is to create a contribution process that:
* Encourages new contributions.
* Encourages contributors to remain involved.
* Avoids unnecessary processes and bureaucracy whenever possible.
* Creates a transparent decision making process that makes it clear how
contributors can be involved in decision making.
## Vocabulary
* A **Contributor** is any individual creating or commenting on an issue or pull request.
* A **Committer** is a subset of contributors who have been given write access to the repository.
* A **Project Captain** is the lead maintainer of a repository.
* A **TC (Technical Committee)** is a group of committers representing the required technical
expertise to resolve rare disputes.
* A **Triager** is a subset of contributors who have been given triage access to the repository.
## Logging Issues
Log an issue for any question or problem you might have. When in doubt, log an issue, and
any additional policies about what to include will be provided in the responses. The only
exception is security disclosures which should be sent privately.
Committers may direct you to another repository, ask for additional clarifications, and
add appropriate metadata before the issue is addressed.
Please be courteous and respectful. Every participant is expected to follow the
project's Code of Conduct.
## Contributions
Any change to resources in this repository must be through pull requests. This applies to all changes
to documentation, code, binary files, etc. Even long term committers and TC members must use
pull requests.
No pull request can be merged without being reviewed.
For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
contributors in other timezones have time to review. Consideration should also be given to
weekends and other holiday periods to ensure active committers all have reasonable time to
become involved in the discussion and review process if they wish.
The default for each contribution is that it is accepted once no committer has an objection.
During a review, committers may also request that a specific contributor who is most versed in a
particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
process for contributions to land. Once all issues brought by committers are addressed it can
be landed by any committer.
In the case of an objection being raised in a pull request by another committer, all involved
committers should seek to arrive at a consensus by way of addressing concerns being expressed
by discussion, compromise on the proposed change, or withdrawal of the proposed change.
If a contribution is controversial and committers cannot agree about how to get it to land
or if it should land then it should be escalated to the TC. TC members should regularly
discuss pending contributions in order to find a resolution. It is expected that only a
small minority of issues be brought to the TC for resolution and that discussion and
compromise among committers be the default resolution mechanism.
## Becoming a Triager
Anyone can become a triager! Read more about the process of being a triager in
[the triage process document](Triager-Guide.md).
Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
a new triager. If you are interested in becoming a triager, our best advice is to actively participate
in the community by helping triaging issues and pull requests. As well we recommend
to engage in other community activities like attending the TC meetings, and participating in the Slack
discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
if you have questions or need guidance.
## Becoming a Committer
All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
and added as a committer, and be given write access to the repository.
Committers are expected to follow this policy and continue to send pull requests, go through
proper review, and have other committers merge their pull requests.
## TC Process
The TC uses a "consensus seeking" process for issues that are escalated to the TC.
The group tries to find a resolution that has no open objections among TC members.
If a consensus cannot be reached that has no objections then a majority wins vote
is called. It is also expected that the majority of decisions made by the TC are via
a consensus seeking process and that voting is only used as a last-resort.
Resolution may involve returning the issue to project captains with suggestions on
how to move forward towards a consensus. It is not expected that a meeting of the TC
will resolve all issues on its agenda during that meeting and may prefer to continue
the discussion happening among the project captains.
Members can be added to the TC at any time. Any TC member can nominate another committer
to the TC and the TC uses its standard consensus seeking process to evaluate whether or
not to add this new member. The TC will consist of a minimum of 3 active members and a
maximum of 10. If the TC should drop below 5 members the active TC members should nominate
someone new. If a TC member is stepping down, they are encouraged (but not required) to
nominate someone to take their place.
TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
necessary to be effective in the role.
To remain "active" a TC member should have participation within the last 12 months and miss
no more than six consecutive TC meetings. Our goal is to increase participation, not punish
people for any lack of participation, this guideline should be only be used as such
(replace an inactive member with a new active one, for example). Members who do not meet this
are expected to step down. If A TC member does not step down, an issue can be opened in the
discussions repo to move them to inactive status. TC members who step down or are removed due
to inactivity will be moved into inactive status.
Inactive status members can become active members by self nomination if the TC is not already
larger than the maximum of 10. They will also be given preference if, while at max size, an
active member steps down.
## Project Captains
The Express TC can designate captains for individual projects/repos in the
organizations. These captains are responsible for being the primary
day-to-day maintainers of the repo on a technical and community front.
Repo captains are empowered with repo ownership and package publication rights.
When there are conflicts, especially on topics that effect the Express project
at large, captains are responsible to raise it up to the TC and drive
those conflicts to resolution. Captains are also responsible for making sure
community members follow the community guidelines, maintaining the repo
and the published package, as well as in providing user support.
Like TC members, Repo captains are a subset of committers.
To become a captain for a project the candidate is expected to participate in that
project for at least 6 months as a committer prior to the request. They should have
helped with code contributions as well as triaging issues. They are also required to
have 2FA enabled on both their GitHub and npm accounts.
Any TC member or an existing captain on the **same** repo can nominate another committer
to the captain role. To do so, they should submit a PR to this document, updating the
**Active Project Captains** section (while maintaining the sort order) with the project
name, the nominee's GitHub handle, and their npm username (if different).
- Repos can have as many captains as make sense for the scope of work.
- A TC member or an existing repo captain **on the same project** can nominate a new captain.
Repo captains from other projects should not nominate captains for a different project.
The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
for comment and/or dissent. When the PR is merged, a TC member will add them to the
proper GitHub/npm groups.
### Active Projects and Captains
- [`expressjs/badgeboard`](https://github.com/expressjs/badgeboard): @wesleytodd
- [`expressjs/basic-auth-connect`](https://github.com/expressjs/basic-auth-connect): @ulisesGascon
- [`expressjs/body-parser`](https://github.com/expressjs/body-parser): @wesleytodd, @jonchurch, @ulisesGascon
- [`expressjs/compression`](https://github.com/expressjs/compression): @ulisesGascon
- [`expressjs/connect-multiparty`](https://github.com/expressjs/connect-multiparty): @ulisesGascon
- [`expressjs/cookie-parser`](https://github.com/expressjs/cookie-parser): @wesleytodd, @UlisesGascon
- [`expressjs/cookie-session`](https://github.com/expressjs/cookie-session): @ulisesGascon
- [`expressjs/cors`](https://github.com/expressjs/cors): @jonchurch, @ulisesGascon
- [`expressjs/discussions`](https://github.com/expressjs/discussions): @wesleytodd
- [`expressjs/errorhandler`](https://github.com/expressjs/errorhandler): @ulisesGascon
- [`expressjs/express-paginate`](https://github.com/expressjs/express-paginate): @ulisesGascon
- [`expressjs/express`](https://github.com/expressjs/express): @wesleytodd, @ulisesGascon
- [`expressjs/expressjs.com`](https://github.com/expressjs/expressjs.com): @crandmck, @jonchurch, @bjohansebas
- [`expressjs/flash`](https://github.com/expressjs/flash): @ulisesGascon
- [`expressjs/generator`](https://github.com/expressjs/generator): @wesleytodd
- [`expressjs/method-override`](https://github.com/expressjs/method-override): @ulisesGascon
- [`expressjs/morgan`](https://github.com/expressjs/morgan): @jonchurch, @ulisesGascon
- [`expressjs/multer`](https://github.com/expressjs/multer): @LinusU, @ulisesGascon
- [`expressjs/response-time`](https://github.com/expressjs/response-time): @UlisesGascon
- [`expressjs/serve-favicon`](https://github.com/expressjs/serve-favicon): @ulisesGascon
- [`expressjs/serve-index`](https://github.com/expressjs/serve-index): @ulisesGascon
- [`expressjs/serve-static`](https://github.com/expressjs/serve-static): @ulisesGascon
- [`expressjs/session`](https://github.com/expressjs/session): @ulisesGascon
- [`expressjs/statusboard`](https://github.com/expressjs/statusboard): @wesleytodd
- [`expressjs/timeout`](https://github.com/expressjs/timeout): @ulisesGascon
- [`expressjs/vhost`](https://github.com/expressjs/vhost): @ulisesGascon
- [`jshttp/accepts`](https://github.com/jshttp/accepts): @blakeembrey
- [`jshttp/basic-auth`](https://github.com/jshttp/basic-auth): @blakeembrey
- [`jshttp/compressible`](https://github.com/jshttp/compressible): @blakeembrey
- [`jshttp/content-disposition`](https://github.com/jshttp/content-disposition): @blakeembrey
- [`jshttp/content-type`](https://github.com/jshttp/content-type): @blakeembrey
- [`jshttp/cookie`](https://github.com/jshttp/cookie): @blakeembrey
- [`jshttp/etag`](https://github.com/jshttp/etag): @blakeembrey
- [`jshttp/forwarded`](https://github.com/jshttp/forwarded): @blakeembrey
- [`jshttp/fresh`](https://github.com/jshttp/fresh): @blakeembrey
- [`jshttp/http-assert`](https://github.com/jshttp/http-assert): @wesleytodd, @jonchurch, @ulisesGascon
- [`jshttp/http-errors`](https://github.com/jshttp/http-errors): @wesleytodd, @jonchurch, @ulisesGascon
- [`jshttp/media-typer`](https://github.com/jshttp/media-typer): @blakeembrey
- [`jshttp/methods`](https://github.com/jshttp/methods): @blakeembrey
- [`jshttp/mime-db`](https://github.com/jshttp/mime-db): @blakeembrey, @UlisesGascon
- [`jshttp/mime-types`](https://github.com/jshttp/mime-types): @blakeembrey, @UlisesGascon
- [`jshttp/negotiator`](https://github.com/jshttp/negotiator): @blakeembrey
- [`jshttp/on-finished`](https://github.com/jshttp/on-finished): @wesleytodd, @ulisesGascon
- [`jshttp/on-headers`](https://github.com/jshttp/on-headers): @blakeembrey
- [`jshttp/proxy-addr`](https://github.com/jshttp/proxy-addr): @wesleytodd, @ulisesGascon
- [`jshttp/range-parser`](https://github.com/jshttp/range-parser): @blakeembrey
- [`jshttp/statuses`](https://github.com/jshttp/statuses): @blakeembrey
- [`jshttp/type-is`](https://github.com/jshttp/type-is): @blakeembrey
- [`jshttp/vary`](https://github.com/jshttp/vary): @blakeembrey
- [`pillarjs/cookies`](https://github.com/pillarjs/cookies): @blakeembrey
- [`pillarjs/csrf`](https://github.com/pillarjs/csrf): @ulisesGascon
- [`pillarjs/encodeurl`](https://github.com/pillarjs/encodeurl): @blakeembrey
- [`pillarjs/finalhandler`](https://github.com/pillarjs/finalhandler): @wesleytodd, @ulisesGascon
- [`pillarjs/hbs`](https://github.com/pillarjs/hbs): @ulisesGascon
- [`pillarjs/multiparty`](https://github.com/pillarjs/multiparty): @blakeembrey
- [`pillarjs/parseurl`](https://github.com/pillarjs/parseurl): @blakeembrey
- [`pillarjs/path-to-regexp`](https://github.com/pillarjs/path-to-regexp): @blakeembrey
- [`pillarjs/request`](https://github.com/pillarjs/request): @wesleytodd
- [`pillarjs/resolve-path`](https://github.com/pillarjs/resolve-path): @blakeembrey
- [`pillarjs/router`](https://github.com/pillarjs/router): @wesleytodd, @ulisesGascon
- [`pillarjs/send`](https://github.com/pillarjs/send): @blakeembrey
- [`pillarjs/understanding-csrf`](https://github.com/pillarjs/understanding-csrf): @ulisesGascon
### Current Initiative Captains
- Triage team [ref](https://github.com/expressjs/discussions/issues/227): @UlisesGascon
## Developer's Certificate of Origin 1.1
```text
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```

View File

@@ -1,3 +1,32 @@
# Unreleased Changes
## 🚀 Improvements
* Improve HTML structure in `res.redirect()` responses when HTML format is accepted by adding `<!DOCTYPE html>`, `<title>`, and `<body>` tags for better browser compatibility - by [@Bernice55231](https://github.com/Bernice55231) in [#5167](https://github.com/expressjs/express/pull/5167)
* When calling `app.render` with options set to null, the locals object is handled correctly, preventing unexpected errors and making the method behave the same as when options is omitted or an empty object is passed - by [AkaHarshit](https://github.com/AkaHarshit) in [#6903](https://github.com/expressjs/express/pull/6903)
```js
app.render('index', null, callback); // now works as expected
```
## ⚡ Performance
* Avoid duplicate Content-Type header processing in `res.send()` when sending string responses without an explicit Content-Type header - by [@bjohansebas](https://github.com/bjohansebas) in [#6991](https://github.com/expressjs/express/pull/6991)
5.2.1 / 2025-12-01
=======================
* Revert security fix for [CVE-2024-51999](https://www.cve.org/CVERecord?id=CVE-2024-51999) ([GHSA-pj86-cfqh-vqx6](https://github.com/expressjs/express/security/advisories/GHSA-pj86-cfqh-vqx6))
* The prior release (5.2.0) included an erroneous breaking change related to the extended query parser. There is no actual security vulnerability associated with this behavior (CVE-2024-51999 has been rejected). The change has been fully reverted in this release.
5.2.0 / 2025-12-01
========================
* Security fix for [CVE-2024-51999](https://www.cve.org/CVERecord?id=CVE-2024-51999) ([GHSA-pj86-cfqh-vqx6](https://github.com/expressjs/express/security/advisories/GHSA-pj86-cfqh-vqx6))
* deps: `body-parser@^2.2.1`
* A deprecation warning was added when using `res.redirect` with undefined arguments, Express now emits a warning to help detect calls that pass undefined as the status or URL and make them easier to fix.
5.1.0 / 2025-03-31
========================

View File

@@ -1,125 +0,0 @@
# README guidelines
Every module in the expressjs, pillarjs, and jshttp organizations should have
a README file named `README.md`. The purpose of the README is to:
- Explain the purpose of the module and how to use it.
- Act as a landing page (both on GitHub and npmjs.com) for the module to help
people find it via search. Middleware module READMEs are also incorporated
into https://expressjs.com/en/resources/middleware.html.
- Encourage community contributions and participation.
Use the [README template](https://github.com/expressjs/express/wiki/README-template)
to quickly create a new README file.
## Top-level items
**Badges** (optional): At the very top (with no subheading), include any
applicable badges, such as npm version/downloads, build status, test coverage,
and so on. Badges should resolve properly (not display a broken image).
Possible badges include:
- npm version: `[![NPM Version][npm-image]][npm-url]`
- npm downloads: `[![NPM Downloads][downloads-image]][downloads-url]`
- Build status: `[![Build Status][travis-image]][travis-url]`
- Test coverage: `[![Test Coverage][coveralls-image]][coveralls-url]`
- Tips: `[![Gratipay][gratipay-image]][gratipay-url]`
**Summary**: Following badges, provide a one- or two-sentence description of
what the module does. This should be the same as the npmjs.org blurb (which
comes from the description property of `package.json`). Since npm doesn't
handle markdown for the blurb, avoid using markdown in the summary sentence.
**TOC** (Optional): For longer READMEs, provide a table of contents that has
a relative link to each section. A tool such as
[doctoc](https://www.npmjs.com/package/doctoc) makes it very easy to generate
a TOC.
## Overview
Optionally, include a section of one or two paragraphs with more high-level
information on what the module does, what problems it solves, why one would
use it and how. Don't just repeat what's in the summary.
## Installation
Required. This section is typically just:
```sh
$ npm install module-name
```
But include any other steps or requirements.
NOTE: Use the `sh` code block to make the shell command display properly on
the website.
## Basic use
- Provide a general description of how to use the module with code sample.
Include any important caveats or restrictions.
- Explain the most common use cases.
- Optional: a simple "hello world" type example (where applicable). This
example is in addition to the more comprehensive [example section](#examples)
later.
## API
Provide complete API documentation.
Formatting conventions: Each function is listed in a 3rd-level heading (`###`),
like this:
```
### Function_name(arg, options [, optional_arg] ... )
```
**Options objects**
For arguments that are objects (for example, options object), describe the
properties in a table, as follows. This matches the formatting used in the
[Express API docs](https://expressjs.com/en/4x/api.html).
|Property | Description | Type | Default|
|----------|-----------|------------|-------------|
|Name of the property in `monospace`. | Brief description | String, Number, Boolean, etc. | If applicable.|
If all the properties are required (i.e. there are no defaults), then you
can omit the default column.
Instead of very lengthy descriptions, link out to subsequent paragraphs for
more detailed explanation of specific cases (e.g. "When this property is set
to 'foobar', xyz happens; see &lt;link to following section &gt;.)
If there are options properties that are themselves options, use additional
tables. See [`trust proxy` and `etag` properties](https://expressjs.com/en/4x/api.html#app.settings.table).
## Examples
Every README should have at least one example; ideally more. For code samples,
be sure to use the `js` code block, for proper display in the website, e.g.:
```js
var csurf = require('csurf')
...
```
## Tests
What tests are included.
How to run them.
The convention for running tests is `npm test`. All our projects should follow
this convention.
## Contributors
Names of module "owners" (lead developers) and other developers who have
contributed.
## License
Link to the license, with a short description of what it is, e.g. "MIT" or
whatever. Ideally, avoid putting the license text directly in the README; link
to it instead.

View File

@@ -2,25 +2,32 @@
**Fast, unopinionated, minimalist web framework for [Node.js](https://nodejs.org).**
**This project has a [Code of Conduct][].**
**This project has a [Code of Conduct].**
## Table of contents
* [Installation](#Installation)
* [Features](#Features)
* [Docs & Community](#docs--community)
* [Quick Start](#Quick-Start)
* [Running Tests](#Running-Tests)
* [Philosophy](#Philosophy)
* [Examples](#Examples)
* [Contributing to Express](#Contributing)
* [TC (Technical Committee)](#tc-technical-committee)
* [Triagers](#triagers)
* [License](#license)
- [Table of contents](#table-of-contents)
- [Installation](#installation)
- [Features](#features)
- [Docs \& Community](#docs--community)
- [Quick Start](#quick-start)
- [Philosophy](#philosophy)
- [Examples](#examples)
- [Contributing](#contributing)
- [Security Issues](#security-issues)
- [Running Tests](#running-tests)
- [Current project team members](#current-project-team-members)
- [TC (Technical Committee)](#tc-technical-committee)
- [TC emeriti members](#tc-emeriti-members)
- [Triagers](#triagers)
- [Emeritus Triagers](#emeritus-triagers)
- [License](#license)
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-downloads-url]
[![Linux Build][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
@@ -33,7 +40,9 @@ app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(3000)
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000')
})
```
## Installation
@@ -137,18 +146,15 @@ node examples/content-negotiation
## Contributing
[![Linux Build][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
The Express.js project welcomes all constructive contributions. Contributions take many forms,
from code for bug fixes and enhancements, to additions and fixes to documentation, additional
tests, triaging incoming pull requests and issues, and more!
See the [Contributing Guide](Contributing.md) for more technical details on contributing.
See the [Contributing Guide] for more technical details on contributing.
### Security Issues
If you discover a security vulnerability in Express, please see [Security Policies and Procedures](Security.md).
If you discover a security vulnerability in Express, please see [Security Policies and Procedures](https://github.com/expressjs/express/security/policy).
### Running Tests
@@ -164,7 +170,9 @@ Then run `npm test`:
npm test
```
## People
## Current project team members
For information about the governance of the express.js project, see [GOVERNANCE.md](https://github.com/expressjs/discussions/blob/HEAD/docs/GOVERNANCE.md).
The original author of Express is [TJ Holowaychuk](https://github.com/tj)
@@ -200,13 +208,13 @@ The original author of Express is [TJ Holowaychuk](https://github.com/tj)
* [bjohansebas](https://github.com/bjohansebas) - **Sebastian Beltran**
* [carpasse](https://github.com/carpasse) - **Carlos Serrano**
* [CBID2](https://github.com/CBID2) - **Christine Belzie**
* [dpopp07](https://github.com/dpopp07) - **Dustin Popp**
* [UlisesGascon](https://github.com/UlisesGascon) - **Ulises Gascón** (he/him)
* [3imed-jaberi](https://github.com/3imed-jaberi) - **Imed Jaberi**
* [IamLizu](https://github.com/IamLizu) - **S M Mahmudul Hasan** (he/him)
* [Phillip9587](https://github.com/Phillip9587) - **Phillip Barta**
* [Sushmeet](https://github.com/Sushmeet) - **Sushmeet Sunger**
* [rxmarbles](https://github.com/rxmarbles) **Rick Markins** (He/him)
* [efekrskl](https://github.com/efekrskl) - **Efe Karasakal**
* [rxmarbles](https://github.com/rxmarbles) - **Rick Markins** (he/him)
* [krzysdz](https://github.com/krzysdz)
* [GroophyLifefor](https://github.com/GroophyLifefor) - **Murat Kirazkaya**
<details>
<summary>Triagers emeriti members</summary>
@@ -245,7 +253,10 @@ The original author of Express is [TJ Holowaychuk](https://github.com/tj)
* [dakshkhetan](https://github.com/dakshkhetan) - **Daksh Khetan** (he/him)
* [lucasraziel](https://github.com/lucasraziel) - **Lucas Soares Do Rego**
* [mertcanaltin](https://github.com/mertcanaltin) - **Mert Can Altin**
* [dpopp07](https://github.com/dpopp07) - **Dustin Popp**
* [Sushmeet](https://github.com/Sushmeet) - **Sushmeet Sunger**
* [3imed-jaberi](https://github.com/3imed-jaberi) - **Imed Jaberi**
</details>
@@ -253,14 +264,15 @@ The original author of Express is [TJ Holowaychuk](https://github.com/tj)
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/express/master
[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/express?branch=master
[coveralls-url]: https://coveralls.io/r/expressjs/express?branch=master
[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/express/master?label=CI
[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/express/ci.yml?branch=master&label=ci
[github-actions-ci-url]: https://github.com/expressjs/express/actions/workflows/ci.yml
[npm-downloads-image]: https://badgen.net/npm/dm/express
[npm-downloads-image]: https://img.shields.io/npm/dm/express
[npm-downloads-url]: https://npmcharts.com/compare/express?minimal=true
[npm-url]: https://npmjs.org/package/express
[npm-version-image]: https://badgen.net/npm/v/express
[npm-version-image]: https://img.shields.io/npm/v/express
[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/express/badge
[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/express
[Code of Conduct]: https://github.com/expressjs/express/blob/master/Code-Of-Conduct.md
[Code of Conduct]: https://github.com/expressjs/.github/blob/HEAD/CODE_OF_CONDUCT.md
[Contributing Guide]: https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md

View File

@@ -1,202 +0,0 @@
# Express Release Process
This document contains the technical aspects of the Express release process. The
intended audience is those who have been authorized by the Express Technical
Committee (TC) to create, promote and sign official release builds for Express,
as npm packages hosted on https://npmjs.com/package/express.
## Who can make releases?
Release authorization is given by the Express TC. Once authorized, an individual
must have the following access permissions:
### 1. Github release access
The individual making the release will need to be a member of the
expressjs/express team with Write permission level so they are able to tag the
release commit and push changes to the expressjs/express repository
(see Steps 4 and 5).
### 2. npmjs.com release access
The individual making the release will need to be made an owner on the
`express` package on npmjs.com so they are able to publish the release
(see Step 6).
## How to publish a release
Before publishing, the following preconditions should be met:
- A release proposal issue or tracking pull request (see "Proposal branch"
below) will exist documenting:
- the proposed changes
- the type of release: patch, minor or major
- the version number (according to semantic versioning - https://semver.org)
- The proposed changes should be complete.
There are two main release flows: patch and non-patch.
The patch flow is for making **patch releases**. As per semantic versioning,
patch releases are for simple changes, eg: typo fixes, patch dependency updates,
and simple/low-risk bug fixes. Every other type of change is made via the
non-patch flow.
### Branch terminology
"Master branch"
- There is a branch in git used for the current major version of Express, named
`master`.
- This branch contains the completed commits for the next patch release of the
current major version.
- Releases for the current major version are published from this branch.
"Version branch"
- For any given major version of Express (current, previous or next) there is
a branch in git for that release named `<major-version>.x` (eg: `4.x`).
- This branch points to the commit of the latest tag for the given major version.
"Release branch"
- For any given major version of Express, there is a branch used for publishing
releases.
- For the current major version of Express, the release branch is the
"Master branch" named `master`.
- For all other major versions of Express, the release branch is the
"Version branch" named `<major-version>.x`.
"Proposal branch"
- A branch in git representing a proposed new release of Express. This can be a
minor or major release, named `<major-version>.0` for a major release,
`<major-version>.<minor-version>` for a minor release.
- A tracking pull request should exist to document the proposed release,
targeted at the appropriate release branch. Prior to opening the tracking
pull request the content of the release may have be discussed in an issue.
- This branch contains the commits accepted so far that implement the proposal
in the tracking pull request.
### Pre-release Versions
Alpha and Beta releases are made from a proposal branch. The version number should be
incremented to the next minor version with a `-beta` or `-alpha` suffix.
For example, if the next beta release is `5.0.1`, the beta release would be `5.0.1-beta.0`.
The pre-releases are unstable and not suitable for production use.
### Patch flow
In the patch flow, simple changes are committed to the release branch which
acts as an ever-present branch for the next patch release of the associated
major version of Express.
The release branch is usually kept in a state where it is ready to release.
Releases are made when sufficient time or change has been made to warrant it.
This is usually proposed and decided using a github issue.
### Non-patch flow
In the non-patch flow, changes are committed to a temporary proposal branch
created specifically for that release proposal. The branch is based on the
most recent release of the major version of Express that the release targets.
Releases are made when all the changes on a proposal branch are complete and
approved. This is done by merging the proposal branch into the release branch
(using a fast-forward merge), tagging it with the new version number and
publishing the release package to npmjs.com.
### Flow
Below is a detailed description of the steps to publish a release.
#### Step 1. Check the release is ready to publish
Check any relevant information to ensure the release is ready, eg: any
milestone, label, issue or tracking pull request for the release. The release
is ready when all proposed code, tests and documentation updates are complete
(either merged, closed or re-targeted to another release).
#### Step 2. (Non-patch flow only) Merge the proposal branch into the release branch
In the patch flow: skip this step.
In the non-patch flow:
```sh
$ git checkout <release-branch>
$ git merge --ff-only <proposal-branch>
```
<release-branch> - see "Release branch" of "Branches" above.
<proposal-branch> - see "Proposal branch" of "Non-patch flow" above.
> [!NOTE]
> You may need to rebase the proposal branch to allow a fast-forward
> merge. Using a fast-forward merge keeps the history clean as it does
> not introduce merge commits.
### Step 3. Update the History.md and package.json to the new version number
The changes so far for the release should already be documented under the
"unreleased" section at the top of the History.md file, as per the usual
development practice. Change "unreleased" to the new release version / date.
Example diff fragment:
```diff
-unreleased
-==========
+4.13.3 / 2015-08-02
+===================
```
The version property in the package.json should already contain the version of
the previous release. Change it to the new release version.
Commit these changes together under a single commit with the message set to
the new release version (eg: `4.13.3`):
```sh
$ git checkout <release-branch>
<..edit files..>
$ git add History.md package.json
$ git commit -m '<version-number>'
```
### Step 4. Identify and tag the release commit with the new release version
Create a lightweight tag (rather than an annotated tag) named after the new
release version (eg: `4.13.3`).
```sh
$ git tag <version-number>
```
### Step 5. Push the release branch changes and tag to github
The branch and tag should be pushed directly to the main repository
(https://github.com/expressjs/express).
```sh
$ git push origin <release-branch>
$ git push origin <version-number>
```
### Step 6. Publish to npmjs.com
Ensure your local working copy is completely clean (no extra or changed files).
You can use `git status` for this purpose.
```sh
$ npm login <npm-username>
$ npm publish
```
> [!NOTE]
> The version number to publish will be picked up automatically from
> package.json.
### Step 7. Update documentation website
The documentation website https://expressjs.com/ documents the current release version in various places. To update these, follow these steps:
1. Manually run the [`Update External Docs` workflow](https://github.com/expressjs/expressjs.com/actions/workflows/update-external-docs.yml) in expressjs.com repository.
2. Add a new section to the [changelog](https://github.com/expressjs/expressjs.com/blob/gh-pages/en/changelog/index.md) in the expressjs.com website.

View File

@@ -1,56 +0,0 @@
# Security Policies and Procedures
This document outlines security procedures and general policies for the Express
project.
* [Reporting a Bug](#reporting-a-bug)
* [Disclosure Policy](#disclosure-policy)
* [Comments on this Policy](#comments-on-this-policy)
## Reporting a Bug
The Express team and community take all security bugs in Express seriously.
Thank you for improving the security of Express. We appreciate your efforts and
responsible disclosure and will make every effort to acknowledge your
contributions.
Report security bugs by emailing `express-security@lists.openjsf.org`.
To ensure the timely response to your report, please ensure that the entirety
of the report is contained within the email body and not solely behind a web
link or an attachment.
The lead maintainer will acknowledge your email within 48 hours, and will send a
more detailed response within 48 hours indicating the next steps in handling
your report. After the initial reply to your report, the security team will
endeavor to keep you informed of the progress towards a fix and full
announcement, and may ask for additional information or guidance.
Report security bugs in third-party modules to the person or team maintaining
the module.
## Pre-release Versions
Alpha and Beta releases are unstable and **not suitable for production use**.
Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
## Disclosure Policy
When the security team receives a security bug report, they will assign it to a
primary handler. This person will coordinate the fix and release process,
involving the following steps:
* Confirm the problem and determine the affected versions.
* Audit code to find any potential similar problems.
* Prepare fixes for all releases still under maintenance. These fixes will be
released as fast as possible to npm.
## The Express Threat Model
We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
## Comments on this Policy
If you have suggestions on how this process could be improved please submit a
pull request.

View File

@@ -1,72 +0,0 @@
# Express Triager Guide
## Issue Triage Process
When a new issue or pull request is opened the issue will be labeled with `needs triage`.
If a triage team member is available they can help make sure all the required information
is provided. Depending on the issue or PR there are several next labels they can add for further
classification:
* `needs triage`: This can be kept if the triager is unsure which next steps to take
* `awaiting more info`: If more info has been requested from the author, apply this label.
* `bug`: Issues that present a reasonable conviction there is a reproducible bug.
* `enhancement`: Issues that are found to be a reasonable candidate feature additions.
If the issue is a question or discussion, it should be moved to GitHub Discussions.
### Moving Discussions and Questions to GitHub Discussions
For issues labeled with `question` or `discuss`, it is recommended to move them to GitHub Discussions instead:
* **Questions**: User questions that do not appear to be bugs or enhancements should be moved to GitHub Discussions.
* **Discussions**: Topics for discussion should be moved to GitHub Discussions. If the discussion leads to a new feature or bug identification, it can be moved back to Issues.
In all cases, issues may be closed by maintainers if they don't receive a timely response when
further information is sought, or when additional questions are asked.
## Approaches and Best Practices for getting into triage contributions
Review the organization's [StatusBoard](https://expressjs.github.io/statusboard/),
pay special attention to these columns: stars, watchers, open issues, and contributors.
This gives you a general idea about the criticality and health of the repository.
Pick a few projects based on that criteria, your interests, and skills (existing or aspiring).
Review the project's contribution guideline if present. In a nutshell,
commit to the community's standards and values. Review the
documentation, for most of the projects it is just the README.md, and
make sure you understand the key APIs, semantics, configurations, and use cases.
It might be helpful to write your own test apps to re-affirm your
understanding of the key functions. This may identify some gaps in
documentation, record those as they might be good PR's to open.
Skim through the issue backlog; identify low hanging issues and mostly new ones.
From those, attempt to recreate issues based on the OP description and
ask questions if required. No question is a bad question!
## Removal of Triage Role
There are a few cases where members can be removed as triagers:
- Breaking the CoC or project contributor guidelines
- Abuse or misuse of the role as deemed by the TC
- Lack of participation for more than 6 months
If any of these happen we will discuss as a part of the triage portion of the regular TC meetings.
If you have questions feel free to reach out to any of the TC members.
## Other Helpful Hints:
- Everyone is welcome to attend the [Express Technical Committee Meetings](https://github.com/expressjs/discussions#expressjs-tc-meetings), and as a triager, it might help to get a better idea of what's happening with the project.
- When exploring the module's functionality there are a few helpful steps:
- Turn on `DEBUG=*` (see https://www.npmjs.com/package/debug) to get detailed log information
- It is also a good idea to do live debugging to follow the control flow, try using `node --inspect`
- It is a good idea to make at least one pass of reading through the entire source
- When reviewing the list of open issues there are some common types and suggested actions:
- New/unattended issues or simple questions: A good place to start
- Hard bugs & ongoing discussions: always feel free to chime in and help
- Issues that imply gaps in the documentation: open PRs with changes or help the user to do so
- For recurring issues, it is helpful to create functional examples to demonstrate (publish as gists or a repo)
- Review and identify the maintainers. If necessary, at-mention one or more of them if you are unsure what to do
- Make sure all your interactions are professional, welcoming, and respectful to the parties involved.
- When an issue refers to security concerns, responsibility is delegated to the repository captain or the security group in any public communication.
- If an issue has been open for a long time, the person in charge should be contacted internally through the private Slack chat.

View File

@@ -1,17 +0,0 @@
all:
@./run 1 middleware 50
@./run 5 middleware 50
@./run 10 middleware 50
@./run 15 middleware 50
@./run 20 middleware 50
@./run 30 middleware 50
@./run 50 middleware 50
@./run 100 middleware 50
@./run 10 middleware 100
@./run 10 middleware 250
@./run 10 middleware 500
@./run 10 middleware 1000
@echo
.PHONY: all

View File

@@ -1,34 +0,0 @@
# Express Benchmarks
## Installation
You will need to install [wrk](https://github.com/wg/wrk/blob/master/INSTALL) in order to run the benchmarks.
## Running
To run the benchmarks, first install the dependencies `npm i`, then run `make`
The output will look something like this:
```
50 connections
1 middleware
7.15ms
6784.01
[...redacted...]
1000 connections
10 middleware
139.21ms
6155.19
```
### Tip: Include Node.js version in output
You can use `make && node -v` to include the node.js version in the output.
### Tip: Save the results to a file
You can use `make > results.log` to save the results to a file `results.log`.

View File

@@ -1,20 +0,0 @@
var express = require('..');
var app = express();
// number of middleware
var n = parseInt(process.env.MW || '1', 10);
console.log(' %s middleware', n);
while (n--) {
app.use(function(req, res, next){
next();
});
}
app.use(function(req, res){
res.send('Hello World')
});
app.listen(3333);

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env bash
echo
MW=$1 node $2 &
pid=$!
echo " $3 connections"
sleep 2
wrk 'http://localhost:3333/?foo[bar]=baz' \
-d 3 \
-c $3 \
-t 8 \
| grep 'Requests/sec\|Latency' \
| awk '{ print " " $2 }'
kill $pid

View File

@@ -16,31 +16,47 @@ var path = require('node:path');
var redis = require('redis');
var db = redis.createClient();
// npm install redis
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
// populate search
// npm install redis
db.sadd('ferret', 'tobi');
db.sadd('ferret', 'loki');
db.sadd('ferret', 'jane');
db.sadd('cat', 'manny');
db.sadd('cat', 'luna');
/**
* Redis Initialization
*/
async function initializeRedis() {
try {
// connect to Redis
await db.connect();
// populate search
await db.sAdd('ferret', 'tobi');
await db.sAdd('ferret', 'loki');
await db.sAdd('ferret', 'jane');
await db.sAdd('cat', 'manny');
await db.sAdd('cat', 'luna');
} catch (err) {
console.error('Error initializing Redis:', err);
process.exit(1);
}
}
/**
* GET search for :query.
*/
app.get('/search/:query?', function(req, res, next){
var query = req.params.query;
db.smembers(query, function(err, vals){
if (err) return next(err);
res.send(vals);
});
app.get('/search/{:query}', function (req, res, next) {
var query = req.params.query || '';
db.sMembers(query)
.then((vals) => res.send(vals))
.catch((err) => {
console.error(`Redis error for query "${query}":`, err);
next(err);
});
});
/**
@@ -54,8 +70,14 @@ app.get('/client.js', function(req, res){
res.sendFile(path.join(__dirname, 'client.js'));
});
/* istanbul ignore next */
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}
/**
* Start the Server
*/
(async () => {
await initializeRedis();
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}
})();

View File

@@ -523,7 +523,7 @@ app.render = function render(name, options, callback) {
var cache = this.cache;
var done = callback;
var engines = this.engines;
var opts = options;
var opts = options || {};
var view;
// support callback function as second arg
@@ -597,7 +597,7 @@ app.render = function render(name, options, callback) {
app.listen = function listen() {
var server = http.createServer(this)
var args = Array.prototype.slice.call(arguments)
var args = slice.call(arguments)
if (typeof args[args.length - 1] === 'function') {
var done = args[args.length - 1] = once(args[args.length - 1])
server.once('error', done)

View File

@@ -83,16 +83,13 @@ req.header = function header(name) {
};
/**
* To do: update docs.
*
* Check if the given `type(s)` is acceptable, returning
* the best match when true, otherwise `undefined`, in which
* the best match when true, otherwise `false`, in which
* case you should respond with 406 "Not Acceptable".
*
* The `type` value may be a single MIME type string
* such as "application/json", an extension name
* such as "json", a comma-delimited list such as "json, html, text/plain",
* an argument list such as `"json", "html", "text/plain"`,
* such as "json", an argument list such as `"json", "html", "text/plain"`,
* or an array `["json", "html", "text/plain"]`. When a list
* or array is given, the _best_ match, if any is returned.
*
@@ -107,7 +104,7 @@ req.header = function header(name) {
* // => "html"
* req.accepts('text/html');
* // => "text/html"
* req.accepts('json, text');
* req.accepts('json', 'text');
* // => "json"
* req.accepts('application/json');
* // => "application/json"
@@ -115,12 +112,11 @@ req.header = function header(name) {
* // Accept: text/*, application/json
* req.accepts('image/png');
* req.accepts('png');
* // => undefined
* // => false
*
* // Accept: text/*;q=.5, application/json
* req.accepts(['html', 'json']);
* req.accepts('html', 'json');
* req.accepts('html, json');
* // => "json"
*
* @param {String|Array} type(s)
@@ -147,17 +143,34 @@ req.acceptsEncodings = function(){
};
/**
* Check if the given `charset`s are acceptable,
* otherwise you should respond with 406 "Not Acceptable".
* Checks if the specified `charset`s are acceptable based on the request's `Accept-Charset` header.
* Returns the best matching charset or an array of acceptable charsets.
*
* @param {String} ...charset
* @return {String|Array}
* The `charset` argument(s) can be:
* - A single charset string (e.g., "utf-8")
* - Multiple charset strings as arguments (e.g., `"utf-8", "iso-8859-1"`)
* - A comma-delimited list of charsets (e.g., `"utf-8, iso-8859-1"`)
*
* Examples:
*
* // Accept-Charset: utf-8, iso-8859-1
* req.acceptsCharsets('utf-8');
* // => "utf-8"
*
* req.acceptsCharsets('utf-8', 'iso-8859-1');
* // => "utf-8"
*
* req.acceptsCharsets('utf-8, utf-16');
* // => "utf-8"
*
* @param {...String} charsets - The charset(s) to check against the `Accept-Charset` header.
* @return {String|Array} - The best matching charset, or an array of acceptable charsets.
* @public
*/
req.acceptsCharsets = function(){
var accept = accepts(this);
return accept.charsets.apply(accept, arguments);
req.acceptsCharsets = function(...charsets) {
const accept = accepts(this);
return accept.charsets(...charsets);
};
/**
@@ -169,9 +182,8 @@ req.acceptsCharsets = function(){
* @public
*/
req.acceptsLanguages = function(){
var accept = accepts(this);
return accept.languages.apply(accept, arguments);
req.acceptsLanguages = function(...languages) {
return accepts(this).languages(...languages);
};
/**
@@ -283,12 +295,12 @@ req.is = function is(types) {
*/
defineGetter(req, 'protocol', function protocol(){
var proto = this.connection.encrypted
var proto = this.socket.encrypted
? 'https'
: 'http';
var trust = this.app.get('trust proxy fn');
if (!trust(this.connection.remoteAddress, 0)) {
if (!trust(this.socket.remoteAddress, 0)) {
return proto;
}
@@ -407,7 +419,7 @@ defineGetter(req, 'host', function host(){
var trust = this.app.get('trust proxy fn');
var val = this.get('X-Forwarded-Host');
if (!val || !trust(this.connection.remoteAddress, 0)) {
if (!val || !trust(this.socket.remoteAddress, 0)) {
val = this.get('Host');
} else if (val.indexOf(',') !== -1) {
// Note: X-Forwarded-Host is normally only ever a

View File

@@ -14,6 +14,7 @@
var contentDisposition = require('content-disposition');
var createError = require('http-errors')
var deprecate = require('depd')('express');
var encodeUrl = require('encodeurl');
var escapeHtml = require('escape-html');
var http = require('node:http');
@@ -31,6 +32,7 @@ var send = require('send');
var extname = path.extname;
var resolve = path.resolve;
var vary = require('vary');
const { Buffer } = require('node:buffer');
/**
* Response prototype.
@@ -124,7 +126,6 @@ res.send = function send(body) {
var chunk = body;
var encoding;
var req = this.req;
var type;
// settings
var app = this.app;
@@ -132,7 +133,12 @@ res.send = function send(body) {
switch (typeof chunk) {
// string defaulting to html
case 'string':
if (!this.get('Content-Type')) {
encoding = 'utf8';
const type = this.get('Content-Type');
if (typeof type === 'string') {
this.set('Content-Type', setCharset(type, 'utf-8'));
} else {
this.type('html');
}
break;
@@ -151,17 +157,6 @@ res.send = function send(body) {
break;
}
// write strings in utf-8
if (typeof chunk === 'string') {
encoding = 'utf8';
type = this.get('Content-Type');
// reflect this in content-type
if (typeof type === 'string') {
this.set('Content-Type', setCharset(type, 'utf-8'));
}
}
// determine if ETag should be generated
var etagFn = app.get('etag fn')
var generateETag = !this.get('ETag') && typeof etagFn === 'function'
@@ -825,6 +820,18 @@ res.redirect = function redirect(url) {
address = arguments[1]
}
if (!address) {
deprecate('Provide a url argument');
}
if (typeof address !== 'string') {
deprecate('Url must be a string');
}
if (typeof status !== 'number') {
deprecate('Status must be a number');
}
// Set location header
address = this.location(address).get('Location');
@@ -836,7 +843,8 @@ res.redirect = function redirect(url) {
html: function(){
var u = escapeHtml(address);
body = '<p>' + statuses.message[status] + '. Redirecting to ' + u + '</p>'
body = '<!DOCTYPE html><head><title>' + statuses.message[status] + '</title></head>'
+ '<body><p>' + statuses.message[status] + '. Redirecting to ' + u + '</p></body>'
},
default: function(){

View File

@@ -18,7 +18,9 @@ var etag = require('etag');
var mime = require('mime-types')
var proxyaddr = require('proxy-addr');
var qs = require('qs');
var querystring = require('querystring');
var querystring = require('node:querystring');
const { Buffer } = require('node:buffer');
/**
* A list of lowercased HTTP methods that are supported by Node.js.

View File

@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Fast, unopinionated, minimalist web framework",
"version": "5.1.0",
"version": "5.2.1",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
@@ -33,12 +33,13 @@
],
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.0",
"body-parser": "^2.2.1",
"content-disposition": "^1.0.0",
"content-type": "^1.0.5",
"cookie": "^0.7.1",
"cookie-signature": "^1.2.1",
"debug": "^4.4.0",
"depd": "^2.0.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
@@ -51,7 +52,7 @@
"once": "^1.4.0",
"parseurl": "^1.3.3",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"qs": "^6.14.2",
"range-parser": "^1.2.1",
"router": "^2.2.0",
"send": "^1.1.0",
@@ -64,7 +65,7 @@
"after": "0.8.2",
"connect-redis": "^8.0.1",
"cookie-parser": "1.4.7",
"cookie-session": "2.1.0",
"cookie-session": "2.1.1",
"ejs": "^3.1.10",
"eslint": "8.47.0",
"express-session": "^1.18.1",
@@ -72,7 +73,7 @@
"marked": "^15.0.3",
"method-override": "3.0.0",
"mocha": "^10.7.3",
"morgan": "1.10.0",
"morgan": "1.10.1",
"nyc": "^17.1.0",
"pbkdf2-password": "1.2.1",
"supertest": "^6.3.0",
@@ -83,13 +84,13 @@
},
"files": [
"LICENSE",
"History.md",
"Readme.md",
"index.js",
"lib/"
],
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test": "mocha --require test/support/env --reporter spec --check-leaks test/ test/acceptance/",
"test-ci": "nyc --exclude examples --exclude test --exclude benchmarks --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --exclude examples --exclude test --exclude benchmarks --reporter=html --reporter=text npm test",

View File

@@ -24,4 +24,32 @@ describe('app.listen()', function(){
})
})
})
it('accepts port + hostname + backlog + callback', function (done) {
const app = express();
const server = app.listen(0, '127.0.0.1', 5, function () {
const { address, port } = server.address();
assert.strictEqual(address, '127.0.0.1');
assert(Number.isInteger(port) && port > 0);
// backlog isnt directly inspectable, but if no error was thrown
// we know it was accepted.
server.close(done);
});
});
it('accepts just a callback (no args)', function (done) {
const app = express();
// same as app.listen(0, done)
const server = app.listen();
server.close(done);
});
it('server.address() gives a { address, port, family } object', function (done) {
const app = express();
const server = app.listen(0, () => {
const addr = server.address();
assert(addr && typeof addr === 'object');
assert.strictEqual(typeof addr.address, 'string');
assert(Number.isInteger(addr.port) && addr.port > 0);
assert(typeof addr.family === 'string');
server.close(done);
});
});
})

View File

@@ -331,6 +331,24 @@ describe('app', function(){
})
})
it('should accept null or undefined options', function (done) {
var app = createApp()
app.set('views', path.join(__dirname, 'fixtures'))
app.locals.user = { name: 'tobi' }
app.render('user.tmpl', null, function (err, str) {
if (err) return done(err);
assert.strictEqual(str, '<p>tobi</p>')
app.render('user.tmpl', undefined, function (err2, str2) {
if (err2) return done(err2);
assert.strictEqual(str2, '<p>tobi</p>')
done()
})
})
})
describe('caching', function(){
it('should cache with cache option', function(done){
var app = express();

View File

@@ -1156,7 +1156,7 @@ describe('app.router', function () {
assert.strictEqual(app.get('/', function () { }), app)
})
it('should should not use disposed router/middleware', function (done) {
it('should not use disposed router/middleware', function (done) {
// more context: https://github.com/expressjs/express/issues/5743#issuecomment-2277148412
var app = express();

View File

@@ -2,6 +2,7 @@
var assert = require('node:assert')
var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage
const { Buffer } = require('node:buffer');
var express = require('..')
var request = require('supertest')
@@ -539,7 +540,7 @@ describe('express.json()', function () {
this.app = app
})
it('should presist store', function (done) {
it('should persist store', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/json')
@@ -561,7 +562,7 @@ describe('express.json()', function () {
.end(done)
})
it('should presist store when inflated', function (done) {
it('should persist store when inflated', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'application/json')
@@ -572,7 +573,7 @@ describe('express.json()', function () {
test.end(done)
})
it('should presist store when inflate error', function (done) {
it('should persist store when inflate error', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'application/json')
@@ -582,7 +583,7 @@ describe('express.json()', function () {
test.end(done)
})
it('should presist store when parse error', function (done) {
it('should persist store when parse error', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/json')
@@ -592,7 +593,7 @@ describe('express.json()', function () {
.end(done)
})
it('should presist store when limit exceeded', function (done) {
it('should persist store when limit exceeded', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/json')

View File

@@ -5,6 +5,7 @@ var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage
var express = require('..')
var request = require('supertest')
const { Buffer } = require('node:buffer');
describe('express.raw()', function () {
before(function () {
@@ -368,7 +369,7 @@ describe('express.raw()', function () {
this.app = app
})
it('should presist store', function (done) {
it('should persist store', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/octet-stream')
@@ -379,7 +380,7 @@ describe('express.raw()', function () {
.end(done)
})
it('should presist store when unmatched content-type', function (done) {
it('should persist store when unmatched content-type', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/fizzbuzz')
@@ -389,7 +390,7 @@ describe('express.raw()', function () {
.end(done)
})
it('should presist store when inflated', function (done) {
it('should persist store when inflated', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'application/octet-stream')
@@ -400,7 +401,7 @@ describe('express.raw()', function () {
test.end(done)
})
it('should presist store when inflate error', function (done) {
it('should persist store when inflate error', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'application/octet-stream')
@@ -410,7 +411,7 @@ describe('express.raw()', function () {
test.end(done)
})
it('should presist store when limit exceeded', function (done) {
it('should persist store when limit exceeded', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/octet-stream')

View File

@@ -3,6 +3,8 @@
var assert = require('node:assert')
var express = require('..')
var path = require('node:path')
const { Buffer } = require('node:buffer');
var request = require('supertest')
var utils = require('./support/utils')

View File

@@ -2,7 +2,7 @@
var assert = require('node:assert')
var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage
const { Buffer } = require('node:buffer');
var express = require('..')
var request = require('supertest')
@@ -397,7 +397,7 @@ describe('express.text()', function () {
this.app = app
})
it('should presist store', function (done) {
it('should persist store', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'text/plain')
@@ -408,7 +408,7 @@ describe('express.text()', function () {
.end(done)
})
it('should presist store when unmatched content-type', function (done) {
it('should persist store when unmatched content-type', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/fizzbuzz')
@@ -418,7 +418,7 @@ describe('express.text()', function () {
.end(done)
})
it('should presist store when inflated', function (done) {
it('should persist store when inflated', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'text/plain')
@@ -429,7 +429,7 @@ describe('express.text()', function () {
test.end(done)
})
it('should presist store when inflate error', function (done) {
it('should persist store when inflate error', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'text/plain')
@@ -439,7 +439,7 @@ describe('express.text()', function () {
test.end(done)
})
it('should presist store when limit exceeded', function (done) {
it('should persist store when limit exceeded', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'text/plain')

View File

@@ -2,6 +2,7 @@
var assert = require('node:assert')
var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage
const { Buffer } = require('node:buffer');
var express = require('..')
var request = require('supertest')
@@ -642,7 +643,7 @@ describe('express.urlencoded()', function () {
this.app = app
})
it('should presist store', function (done) {
it('should persist store', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/x-www-form-urlencoded')
@@ -653,7 +654,7 @@ describe('express.urlencoded()', function () {
.end(done)
})
it('should presist store when unmatched content-type', function (done) {
it('should persist store when unmatched content-type', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/fizzbuzz')
@@ -663,7 +664,7 @@ describe('express.urlencoded()', function () {
.end(done)
})
it('should presist store when inflated', function (done) {
it('should persist store when inflated', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'application/x-www-form-urlencoded')
@@ -674,7 +675,7 @@ describe('express.urlencoded()', function () {
test.end(done)
})
it('should presist store when inflate error', function (done) {
it('should persist store when inflate error', function (done) {
var test = request(this.app).post('/')
test.set('Content-Encoding', 'gzip')
test.set('Content-Type', 'application/x-www-form-urlencoded')
@@ -684,7 +685,7 @@ describe('express.urlencoded()', function () {
test.end(done)
})
it('should presist store when limit exceeded', function (done) {
it('should persist store when limit exceeded', function (done) {
request(this.app)
.post('/')
.set('Content-Type', 'application/x-www-form-urlencoded')

View File

@@ -45,6 +45,19 @@ describe('req', function(){
.set('Accept-Charset', 'foo, bar')
.expect('no', done);
})
it('should return the best matching charset from multiple inputs', function (done) {
var app = express();
app.use(function(req, res, next){
res.end(req.acceptsCharsets('utf-8', 'iso-8859-1'));
});
request(app)
.get('/')
.set('Accept-Charset', 'iso-8859-1, utf-8')
.expect('iso-8859-1', done);
})
})
})
})

View File

@@ -39,7 +39,7 @@ describe('req', function(){
app.enable('trust proxy');
app.use(function(req, res){
req.connection.encrypted = true;
req.socket.encrypted = true;
res.end(req.protocol);
});

View File

@@ -108,7 +108,7 @@ function shouldHaveHeaderValues (key, values) {
return function (res) {
var headers = res.headers[key.toLowerCase()]
assert.ok(headers, 'should have header "' + key + '"')
assert.strictEqual(headers.length, values.length, 'should have ' + values.length + ' occurances of "' + key + '"')
assert.strictEqual(headers.length, values.length, 'should have ' + values.length + ' occurrences of "' + key + '"')
for (var i = 0; i < values.length; i++) {
assert.strictEqual(headers[i], values[i])
}

View File

@@ -1,5 +1,7 @@
'use strict'
const { Buffer } = require('node:buffer');
var express = require('../')
, request = require('supertest');

View File

@@ -3,6 +3,7 @@
var after = require('after');
var assert = require('node:assert')
var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage
const { Buffer } = require('node:buffer');
var express = require('..');
var path = require('node:path')
@@ -88,7 +89,7 @@ describe('res', function(){
})
describe('async local storage', function () {
it('should presist store', function (done) {
it('should persist store', function (done) {
var app = express()
var cb = after(2, done)
var store = { foo: 'bar' }
@@ -116,7 +117,7 @@ describe('res', function(){
.expect(200, 'tobi', cb)
})
it('should presist store on error', function (done) {
it('should persist store on error', function (done) {
var app = express()
var store = { foo: 'bar' }

View File

@@ -237,7 +237,7 @@ function test(app) {
})
describe('when no match is made', function(){
it('should should respond with 406 not acceptable', function(done){
it('should respond with 406 not acceptable', function(done){
request(app)
.get('/')
.set('Accept', 'foo/bar')

View File

@@ -327,18 +327,4 @@ describe('res', function(){
})
})
})
it('should not override previous Content-Types', function(done){
var app = express();
app.get('/', function(req, res){
res.type('application/vnd.example+json');
res.jsonp({ hello: 'world' });
});
request(app)
.get('/')
.expect('content-type', 'application/vnd.example+json; charset=utf-8')
.expect(200, '{"hello":"world"}', done)
})
})

View File

@@ -46,19 +46,7 @@ describe('res', function(){
.expect(200, done)
})
it('should encode data uri1', function (done) {
var app = express()
app.use(function (req, res) {
res.location('data:text/javascript,export default () => { }').end();
});
request(app)
.get('/')
.expect('Location', 'data:text/javascript,export%20default%20()%20=%3E%20%7B%20%7D')
.expect(200, done)
})
it('should encode data uri2', function (done) {
it('should encode data uri', function (done) {
var app = express()
app.use(function (req, res) {
res.location('data:text/javascript,export default () => { }').end();

View File

@@ -91,7 +91,7 @@ describe('res', function(){
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect('Location', 'http://google.com')
.expect(302, '<p>Found. Redirecting to http://google.com</p>', done)
.expect(302, '<!DOCTYPE html><head><title>Found</title></head><body><p>Found. Redirecting to http://google.com</p></body>', done)
})
it('should escape the url', function(done){
@@ -107,7 +107,7 @@ describe('res', function(){
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect('Location', '%3Cla\'me%3E')
.expect(302, '<p>Found. Redirecting to %3Cla&#39;me%3E</p>', done)
.expect(302, '<!DOCTYPE html><head><title>Found</title></head><body><p>Found. Redirecting to %3Cla&#39;me%3E</p></body>', done)
})
it('should not render evil javascript links in anchor href (prevent XSS)', function(done){
@@ -125,7 +125,7 @@ describe('res', function(){
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect('Location', encodedXss)
.expect(302, '<p>Found. Redirecting to ' + encodedXss +'</p>', done);
.expect(302, '<!DOCTYPE html><head><title>Found</title></head><body><p>Found. Redirecting to ' + encodedXss +'</p></body>', done);
});
it('should include the redirect type', function(done){
@@ -140,7 +140,7 @@ describe('res', function(){
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect('Location', 'http://google.com')
.expect(301, '<p>Moved Permanently. Redirecting to http://google.com</p>', done);
.expect(301, '<!DOCTYPE html><head><title>Moved Permanently</title></head><body><p>Moved Permanently. Redirecting to http://google.com</p></body>', done);
})
})

View File

@@ -1,6 +1,7 @@
'use strict'
var assert = require('node:assert')
const { Buffer } = require('node:buffer');
var express = require('..');
var methods = require('../lib/utils').methods;
var request = require('supertest');

View File

@@ -3,6 +3,7 @@
var after = require('after');
var assert = require('node:assert')
var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage
const { Buffer } = require('node:buffer');
var express = require('../')
, request = require('supertest')
@@ -277,7 +278,7 @@ describe('res', function(){
})
describe('async local storage', function () {
it('should presist store', function (done) {
it('should persist store', function (done) {
var app = express()
var cb = after(2, done)
var store = { foo: 'bar' }
@@ -304,7 +305,7 @@ describe('res', function(){
.expect(200, 'tobi', cb)
})
it('should presist store on error', function (done) {
it('should persist store on error', function (done) {
var app = express()
var store = { foo: 'bar' }

View File

@@ -42,5 +42,74 @@ describe('res', function(){
.get('/')
.expect('Content-Type', 'application/vnd.amazon.ebook', done);
})
describe('edge cases', function(){
it('should handle empty string gracefully', function(done){
var app = express();
app.use(function(req, res){
res.type('').end('test');
});
request(app)
.get('/')
.expect('Content-Type', 'application/octet-stream')
.end(done);
})
it('should handle file extension with dots', function(done){
var app = express();
app.use(function(req, res){
res.type('.json').end('{"test": true}');
});
request(app)
.get('/')
.expect('Content-Type', 'application/json; charset=utf-8')
.end(done);
})
it('should handle multiple file extensions', function(done){
var app = express();
app.use(function(req, res){
res.type('file.tar.gz').end('compressed');
});
request(app)
.get('/')
.expect('Content-Type', 'application/gzip')
.end(done);
})
it('should handle uppercase extensions', function(done){
var app = express();
app.use(function(req, res){
res.type('FILE.JSON').end('{"test": true}');
});
request(app)
.get('/')
.expect('Content-Type', 'application/json; charset=utf-8')
.end(done);
})
it('should handle extension with special characters', function(done){
var app = express();
app.use(function(req, res){
res.type('file@test.json').end('{"test": true}');
});
request(app)
.get('/')
.expect('Content-Type', 'application/json; charset=utf-8')
.end(done);
})
})
})
})

View File

@@ -5,6 +5,7 @@
*/
var assert = require('node:assert');
const { Buffer } = require('node:buffer');
/**
* Module exports.
@@ -76,10 +77,10 @@ function getMajorVersion(versionString) {
}
function shouldSkipQuery(versionString) {
// Skipping HTTP QUERY tests on Node 21, it is reported in http.METHODS on 21.7.2 but not supported
// update this implementation to run on supported versions of 21 once they exist
// Skipping HTTP QUERY tests below Node 22, QUERY wasn't fully supported by Node until 22
// we could update this implementation to run on supported versions of 21 once they exist
// upstream tracking https://github.com/nodejs/node/issues/51562
// express tracking issue: https://github.com/expressjs/express/issues/5615
return Number(getMajorVersion(versionString)) === 21
return Number(getMajorVersion(versionString)) < 22
}

View File

@@ -1,6 +1,7 @@
'use strict'
var assert = require('node:assert');
const { Buffer } = require('node:buffer');
var utils = require('../lib/utils');
describe('utils.etag(body, encoding)', function(){
@@ -25,6 +26,25 @@ describe('utils.etag(body, encoding)', function(){
})
})
describe('utils.normalizeType acceptParams method', () => {
it('should handle a type with a malformed parameter and break the loop in acceptParams', () => {
const result = utils.normalizeType('text/plain;invalid');
assert.deepEqual(result,{
value: 'text/plain',
quality: 1,
params: {} // No parameters are added since "invalid" has no "="
});
});
it('should default to application/octet-stream when mime lookup fails', () => {
const result = utils.normalizeType('unknown-extension-xyz');
assert.deepEqual(result, {
value: 'application/octet-stream',
params: {}
});
});
});
describe('utils.setCharset(type, charset)', function () {
it('should do anything without type', function () {
assert.strictEqual(utils.setCharset(), undefined);
@@ -68,3 +88,28 @@ describe('utils.wetag(body, encoding)', function(){
'W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"')
})
})
describe('utils.compileETag()', function () {
it('should return generateETag for true', function () {
const fn = utils.compileETag(true);
assert.strictEqual(fn('express!'), utils.wetag('express!'));
});
it('should return undefined for false', function () {
assert.strictEqual(utils.compileETag(false), undefined);
});
it('should return generateETag for string values "strong" and "weak"', function () {
assert.strictEqual(utils.compileETag('strong')("express"), utils.etag("express"));
assert.strictEqual(utils.compileETag('weak')("express"), utils.wetag("express"));
});
it('should throw for unknown string values', function () {
assert.throws(() => utils.compileETag('foo'), TypeError);
});
it('should throw for unsupported types like arrays and objects', function () {
assert.throws(() => utils.compileETag([]), TypeError);
assert.throws(() => utils.compileETag({}), TypeError);
});
});