mirror of
https://github.com/expressjs/express.git
synced 2026-02-27 11:09:29 +00:00
Compare commits
42 Commits
req.is
...
bsebas/che
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28cb20ec1d | ||
|
|
ae265a90c7 | ||
|
|
9a3f7ff412 | ||
|
|
2cd372e34c | ||
|
|
04d3a49976 | ||
|
|
bc7d155f53 | ||
|
|
00bb633ca6 | ||
|
|
3c0ad4e8dc | ||
|
|
4ae96bdf5e | ||
|
|
6cd404eb28 | ||
|
|
3e81873b52 | ||
|
|
b5aae87594 | ||
|
|
b8fc000f31 | ||
|
|
c2fb76e99f | ||
|
|
9eb700151b | ||
|
|
dbac741a49 | ||
|
|
697547cde6 | ||
|
|
4007ad103b | ||
|
|
2f64f68c37 | ||
|
|
ed0ba3f1dc | ||
|
|
8eace4603c | ||
|
|
30bae81027 | ||
|
|
758d4355d4 | ||
|
|
77bcd5274a | ||
|
|
f33caf1f89 | ||
|
|
54af593b73 | ||
|
|
2551a7d8af | ||
|
|
4453d83cca | ||
|
|
db507669ca | ||
|
|
374fc1a0f9 | ||
|
|
1b196c8b82 | ||
|
|
64e7373d69 | ||
|
|
e4fb370ad8 | ||
|
|
60d4c16cc9 | ||
|
|
9e6760e186 | ||
|
|
ffa89f2ccf | ||
|
|
b9b9f52b2f | ||
|
|
9a7afb2886 | ||
|
|
2eb42059f3 | ||
|
|
aa907945cd | ||
|
|
89f198c6a5 | ||
|
|
d9a62f9833 |
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@@ -27,11 +27,11 @@ jobs:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
|
||||
@@ -46,19 +46,19 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
node-version: [18, 19, 20, 21, 22, 23, 24]
|
||||
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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
@@ -80,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
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
contents: read
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
run: sudo apt-get -y install lcov
|
||||
|
||||
- name: Collect coverage reports
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
with:
|
||||
path: ./coverage
|
||||
pattern: coverage-node-*
|
||||
@@ -112,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
|
||||
|
||||
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -39,13 +39,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.29.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config: |
|
||||
@@ -71,4 +71,4 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.29.5
|
||||
|
||||
12
.github/workflows/legacy.yml
vendored
12
.github/workflows/legacy.yml
vendored
@@ -37,12 +37,12 @@ jobs:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
@@ -64,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
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
contents: read
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
run: sudo apt-get -y install lcov
|
||||
|
||||
- name: Collect coverage reports
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
with:
|
||||
path: ./coverage
|
||||
pattern: coverage-node-*
|
||||
@@ -96,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
|
||||
|
||||
8
.github/workflows/scorecard.yml
vendored
8
.github/workflows/scorecard.yml
vendored
@@ -32,12 +32,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
|
||||
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@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.29.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,6 +5,10 @@ npm-shrinkwrap.json
|
||||
*.log
|
||||
*.gz
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
yarn.lock
|
||||
|
||||
# Coveralls
|
||||
.nyc_output
|
||||
coverage
|
||||
|
||||
19
History.md
19
History.md
@@ -1,3 +1,22 @@
|
||||
# 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)
|
||||
|
||||
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
|
||||
========================
|
||||
|
||||
|
||||
24
Readme.md
24
Readme.md
@@ -40,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
|
||||
@@ -152,7 +154,7 @@ 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?tab=security-ov-file).
|
||||
|
||||
### Running Tests
|
||||
|
||||
@@ -206,13 +208,12 @@ 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)
|
||||
|
||||
<details>
|
||||
<summary>Triagers emeriti members</summary>
|
||||
@@ -251,6 +252,9 @@ 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>
|
||||
|
||||
@@ -259,14 +263,14 @@ 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/.github/blob/HEAD/CODE_OF_CONDUCT.md
|
||||
|
||||
56
SECURITY.md
56
SECURITY.md
@@ -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.
|
||||
@@ -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)
|
||||
|
||||
@@ -75,24 +75,20 @@ req.header = function header(name) {
|
||||
switch (lc) {
|
||||
case 'referer':
|
||||
case 'referrer':
|
||||
return this.headers.referrer
|
||||
|| this.headers.referer;
|
||||
return this.headers.referer || this.headers.referrer;
|
||||
default:
|
||||
return this.headers[lc];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 +103,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 +111,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 +142,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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -282,12 +294,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;
|
||||
}
|
||||
|
||||
@@ -406,7 +418,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
|
||||
|
||||
@@ -850,7 +850,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(){
|
||||
|
||||
@@ -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,7 +33,7 @@
|
||||
],
|
||||
"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",
|
||||
@@ -52,7 +52,7 @@
|
||||
"once": "^1.4.0",
|
||||
"parseurl": "^1.3.3",
|
||||
"proxy-addr": "^2.0.7",
|
||||
"qs": "^6.14.0",
|
||||
"qs": "^6.14.1",
|
||||
"range-parser": "^1.2.1",
|
||||
"router": "^2.2.0",
|
||||
"send": "^1.1.0",
|
||||
@@ -84,7 +84,6 @@
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"History.md",
|
||||
"Readme.md",
|
||||
"index.js",
|
||||
"lib/"
|
||||
@@ -92,7 +91,7 @@
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"test": "mocha --require test/support/env --exit --reporter spec --check-leaks test/ test/acceptance/",
|
||||
"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",
|
||||
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
|
||||
|
||||
@@ -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);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -33,6 +33,20 @@ describe('req', function(){
|
||||
.expect('http://foobar.com', done);
|
||||
})
|
||||
|
||||
it('should prefer Referer over Referrer', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.end(req.get('Referer'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.set('Referrer', 'http://foobar.com')
|
||||
.set('Referer', 'http://example.com')
|
||||
.expect('http://example.com', done);
|
||||
})
|
||||
|
||||
it('should throw missing header name', function (done) {
|
||||
var app = express()
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
var express = require('..')
|
||||
var request = require('supertest')
|
||||
var after = require('after')
|
||||
|
||||
describe('req.is()', function () {
|
||||
describe('when given a mime type', function () {
|
||||
@@ -28,24 +27,10 @@ describe('req.is()', function () {
|
||||
})
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('application/json')
|
||||
.send('{}')
|
||||
.expect(200, 'false', done)
|
||||
})
|
||||
|
||||
it('should return false when none in list matches', function (done) {
|
||||
var app = express()
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.json(req.is(['image/jpeg', 'text/html']))
|
||||
})
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('application/json')
|
||||
.send('{}')
|
||||
.expect(200, 'false', done)
|
||||
.post('/')
|
||||
.type('application/json')
|
||||
.send('{}')
|
||||
.expect(200, 'false', done)
|
||||
})
|
||||
|
||||
it('should ignore charset', function (done) {
|
||||
@@ -56,15 +41,15 @@ describe('req.is()', function () {
|
||||
})
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('application/json; charset=UTF-8')
|
||||
.send('{}')
|
||||
.expect(200, '"application/json"', done)
|
||||
.post('/')
|
||||
.type('application/json; charset=UTF-8')
|
||||
.send('{}')
|
||||
.expect(200, '"application/json"', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when content-type is not present', function(){
|
||||
it('should return false for single type', function (done) {
|
||||
it('should return false', function (done) {
|
||||
var app = express()
|
||||
|
||||
app.use(function (req, res) {
|
||||
@@ -76,19 +61,6 @@ describe('req.is()', function () {
|
||||
.send('{}')
|
||||
.expect(200, 'false', done)
|
||||
})
|
||||
|
||||
it('should return false for multiple types', function (done) {
|
||||
var app = express()
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.json(req.is(['application/json', 'image/jpeg']))
|
||||
})
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.send('{}')
|
||||
.expect(200, 'false', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when given an extension', function(){
|
||||
@@ -105,27 +77,6 @@ describe('req.is()', function () {
|
||||
.send('{}')
|
||||
.expect(200, '"json"', done)
|
||||
})
|
||||
|
||||
it('should lookup the first matching extension from list', function (done) {
|
||||
var app = express()
|
||||
var cb = after(2, done)
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.json(req.is(['json', 'html']))
|
||||
})
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('application/json')
|
||||
.send('{}')
|
||||
.expect(200, '"json"', cb)
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('text/html')
|
||||
.send('{}')
|
||||
.expect(200, '"html"', cb)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when given */subtype', function(){
|
||||
@@ -215,31 +166,4 @@ describe('req.is()', function () {
|
||||
.expect(200, '"application/json"', done)
|
||||
})
|
||||
})
|
||||
|
||||
it('should match wildcards in list and return full type or false', function (done){
|
||||
var app = express()
|
||||
var cb = after(3, done)
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.json(req.is(['application/*', '*/jpeg']))
|
||||
})
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('image/jpeg')
|
||||
.send('{}')
|
||||
.expect(200, '"image/jpeg"', cb)
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('text/html')
|
||||
.send('{}')
|
||||
.expect(200, 'false', cb)
|
||||
|
||||
request(app)
|
||||
.post('/')
|
||||
.type('application/json')
|
||||
.send('{}')
|
||||
.expect(200, '"application/json"', cb)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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'me%3E</p>', done)
|
||||
.expect(302, '<!DOCTYPE html><head><title>Found</title></head><body><p>Found. Redirecting to %3Cla'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);
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user