primer cambio
This commit is contained in:
336
node_modules/compression/HISTORY.md
generated
vendored
Normal file
336
node_modules/compression/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
1.8.1 / 2025-07-17
|
||||
==========
|
||||
|
||||
* deps: on-headers@~1.1.0
|
||||
- Fix [CVE-2025-7339](https://www.cve.org/CVERecord?id=CVE-2025-7339) ([GHSA-76c9-3jph-rj3q](https://github.com/expressjs/on-headers/security/advisories/GHSA-76c9-3jph-rj3q))
|
||||
|
||||
1.8.0 / 2025-02-10
|
||||
==================
|
||||
|
||||
* Use `res.headersSent` when available
|
||||
* Replace `_implicitHeader` with `writeHead` property
|
||||
* add brotli support for versions of node that support it
|
||||
* Add the enforceEncoding option for requests without `Accept-Encoding` header
|
||||
|
||||
1.7.5 / 2024-10-31
|
||||
==================
|
||||
|
||||
* deps: Replace accepts with negotiator@~0.6.4
|
||||
- Add preference option
|
||||
* deps: bytes@3.1.2
|
||||
- Add petabyte (`pb`) support
|
||||
- Fix "thousandsSeparator" incorrecting formatting fractional part
|
||||
- Fix return value for un-parsable strings
|
||||
* deps: compressible@~2.0.18
|
||||
- Mark `font/ttf` as compressible
|
||||
- Remove compressible from `multipart/mixed`
|
||||
- deps: mime-db@'>= 1.43.0 < 2'
|
||||
* deps: safe-buffer@5.2.1
|
||||
|
||||
1.7.4 / 2019-03-18
|
||||
==================
|
||||
|
||||
* deps: compressible@~2.0.16
|
||||
- Mark `text/less` as compressible
|
||||
- deps: mime-db@'>= 1.38.0 < 2'
|
||||
* deps: on-headers@~1.0.2
|
||||
- Fix `res.writeHead` patch missing return value
|
||||
* perf: prevent unnecessary buffer copy
|
||||
|
||||
1.7.3 / 2018-07-15
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.3.5
|
||||
- deps: mime-types@~2.1.18
|
||||
* deps: compressible@~2.0.14
|
||||
- Mark all XML-derived types as compressible
|
||||
- deps: mime-db@'>= 1.34.0 < 2'
|
||||
* deps: safe-buffer@5.1.2
|
||||
|
||||
1.7.2 / 2018-02-18
|
||||
==================
|
||||
|
||||
* deps: compressible@~2.0.13
|
||||
- deps: mime-db@'>= 1.33.0 < 2'
|
||||
|
||||
1.7.1 / 2017-09-26
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.3.4
|
||||
- deps: mime-types@~2.1.16
|
||||
* deps: bytes@3.0.0
|
||||
* deps: compressible@~2.0.11
|
||||
- deps: mime-db@'>= 1.29.0 < 2'
|
||||
* deps: debug@2.6.9
|
||||
* deps: vary@~1.1.2
|
||||
- perf: improve header token parsing speed
|
||||
|
||||
1.7.0 / 2017-07-10
|
||||
==================
|
||||
|
||||
* Use `safe-buffer` for improved Buffer API
|
||||
* deps: bytes@2.5.0
|
||||
* deps: compressible@~2.0.10
|
||||
- Fix regex fallback to not override `compressible: false` in db
|
||||
- deps: mime-db@'>= 1.27.0 < 2'
|
||||
* deps: debug@2.6.8
|
||||
- Allow colors in workers
|
||||
- Deprecated `DEBUG_FD` environment variable set to `3` or higher
|
||||
- Fix error when running under React Native
|
||||
- Fix `DEBUG_MAX_ARRAY_LENGTH`
|
||||
- Use same color for same namespace
|
||||
- deps: ms@2.0.0
|
||||
* deps: vary@~1.1.1
|
||||
- perf: hoist regular expression
|
||||
|
||||
1.6.2 / 2016-05-12
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.3.3
|
||||
- deps: mime-types@~2.1.11
|
||||
- deps: negotiator@0.6.1
|
||||
* deps: bytes@2.3.0
|
||||
- Drop partial bytes on all parsed units
|
||||
- Fix parsing byte string that looks like hex
|
||||
- perf: hoist regular expressions
|
||||
* deps: compressible@~2.0.8
|
||||
- deps: mime-db@'>= 1.23.0 < 2'
|
||||
|
||||
1.6.1 / 2016-01-19
|
||||
==================
|
||||
|
||||
* deps: bytes@2.2.0
|
||||
* deps: compressible@~2.0.7
|
||||
- deps: mime-db@'>= 1.21.0 < 2'
|
||||
* deps: accepts@~1.3.1
|
||||
- deps: mime-types@~2.1.9
|
||||
|
||||
1.6.0 / 2015-09-29
|
||||
==================
|
||||
|
||||
* Skip compression when response has `Cache-Control: no-transform`
|
||||
* deps: accepts@~1.3.0
|
||||
- deps: mime-types@~2.1.7
|
||||
- deps: negotiator@0.6.0
|
||||
* deps: compressible@~2.0.6
|
||||
- deps: mime-db@'>= 1.19.0 < 2'
|
||||
* deps: on-headers@~1.0.1
|
||||
- perf: enable strict mode
|
||||
* deps: vary@~1.1.0
|
||||
- Only accept valid field names in the `field` argument
|
||||
|
||||
1.5.2 / 2015-07-30
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.2.12
|
||||
- deps: mime-types@~2.1.4
|
||||
* deps: compressible@~2.0.5
|
||||
- deps: mime-db@'>= 1.16.0 < 2'
|
||||
* deps: vary@~1.0.1
|
||||
- Fix setting empty header from empty `field`
|
||||
- perf: enable strict mode
|
||||
- perf: remove argument reassignments
|
||||
|
||||
1.5.1 / 2015-07-05
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.2.10
|
||||
- deps: mime-types@~2.1.2
|
||||
* deps: compressible@~2.0.4
|
||||
- deps: mime-db@'>= 1.14.0 < 2'
|
||||
- perf: enable strict mode
|
||||
|
||||
1.5.0 / 2015-06-09
|
||||
==================
|
||||
|
||||
* Fix return value from `.end` and `.write` after end
|
||||
* Improve detection of zero-length body without `Content-Length`
|
||||
* deps: accepts@~1.2.9
|
||||
- deps: mime-types@~2.1.1
|
||||
- perf: avoid argument reassignment & argument slice
|
||||
- perf: avoid negotiator recursive construction
|
||||
- perf: enable strict mode
|
||||
- perf: remove unnecessary bitwise operator
|
||||
* deps: bytes@2.1.0
|
||||
- Slight optimizations
|
||||
- Units no longer case sensitive when parsing
|
||||
* deps: compressible@~2.0.3
|
||||
- Fix regex fallback to work if type exists, but is undefined
|
||||
- deps: mime-db@'>= 1.13.0 < 2'
|
||||
- perf: hoist regex declaration
|
||||
- perf: use regex to extract mime
|
||||
* perf: enable strict mode
|
||||
* perf: remove flush reassignment
|
||||
* perf: simplify threshold detection
|
||||
|
||||
1.4.4 / 2015-05-11
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.2.7
|
||||
- deps: mime-types@~2.0.11
|
||||
- deps: negotiator@0.5.3
|
||||
* deps: debug@~2.2.0
|
||||
- deps: ms@0.7.1
|
||||
|
||||
1.4.3 / 2015-03-14
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.2.5
|
||||
- deps: mime-types@~2.0.10
|
||||
* deps: debug@~2.1.3
|
||||
- Fix high intensity foreground color for bold
|
||||
- deps: ms@0.7.0
|
||||
|
||||
1.4.2 / 2015-03-11
|
||||
==================
|
||||
|
||||
* Fix error when code calls `res.end(str, encoding)`
|
||||
- Specific to Node.js 0.8
|
||||
* deps: debug@~2.1.2
|
||||
- deps: ms@0.7.0
|
||||
|
||||
1.4.1 / 2015-02-15
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.2.4
|
||||
- deps: mime-types@~2.0.9
|
||||
- deps: negotiator@0.5.1
|
||||
|
||||
1.4.0 / 2015-02-01
|
||||
==================
|
||||
|
||||
* Prefer `gzip` over `deflate` on the server
|
||||
- Not all clients agree on what "deflate" coding means
|
||||
|
||||
1.3.1 / 2015-01-31
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.2.3
|
||||
- deps: mime-types@~2.0.8
|
||||
* deps: compressible@~2.0.2
|
||||
- deps: mime-db@'>= 1.1.2 < 2'
|
||||
|
||||
1.3.0 / 2014-12-30
|
||||
==================
|
||||
|
||||
* Export the default `filter` function for wrapping
|
||||
* deps: accepts@~1.2.2
|
||||
- deps: mime-types@~2.0.7
|
||||
- deps: negotiator@0.5.0
|
||||
* deps: debug@~2.1.1
|
||||
|
||||
1.2.2 / 2014-12-10
|
||||
==================
|
||||
|
||||
* Fix `.end` to only proxy to `.end`
|
||||
- Fixes an issue with Node.js 0.11.14
|
||||
* deps: accepts@~1.1.4
|
||||
- deps: mime-types@~2.0.4
|
||||
|
||||
1.2.1 / 2014-11-23
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.1.3
|
||||
- deps: mime-types@~2.0.3
|
||||
|
||||
1.2.0 / 2014-10-16
|
||||
==================
|
||||
|
||||
* deps: debug@~2.1.0
|
||||
- Implement `DEBUG_FD` env variable support
|
||||
|
||||
1.1.2 / 2014-10-15
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.1.2
|
||||
- Fix error when media type has invalid parameter
|
||||
- deps: negotiator@0.4.9
|
||||
|
||||
1.1.1 / 2014-10-12
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.1.1
|
||||
- deps: mime-types@~2.0.2
|
||||
- deps: negotiator@0.4.8
|
||||
* deps: compressible@~2.0.1
|
||||
- deps: mime-db@1.x
|
||||
|
||||
1.1.0 / 2014-09-07
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.1.0
|
||||
* deps: compressible@~2.0.0
|
||||
* deps: debug@~2.0.0
|
||||
|
||||
1.0.11 / 2014-08-10
|
||||
===================
|
||||
|
||||
* deps: on-headers@~1.0.0
|
||||
* deps: vary@~1.0.0
|
||||
|
||||
1.0.10 / 2014-08-05
|
||||
===================
|
||||
|
||||
* deps: compressible@~1.1.1
|
||||
- Fix upper-case Content-Type characters prevent compression
|
||||
|
||||
1.0.9 / 2014-07-20
|
||||
==================
|
||||
|
||||
* Add `debug` messages
|
||||
* deps: accepts@~1.0.7
|
||||
- deps: negotiator@0.4.7
|
||||
|
||||
1.0.8 / 2014-06-20
|
||||
==================
|
||||
|
||||
* deps: accepts@~1.0.5
|
||||
- use `mime-types`
|
||||
|
||||
1.0.7 / 2014-06-11
|
||||
==================
|
||||
|
||||
* use vary module for better `Vary` behavior
|
||||
* deps: accepts@1.0.3
|
||||
* deps: compressible@1.1.0
|
||||
|
||||
1.0.6 / 2014-06-03
|
||||
==================
|
||||
|
||||
* fix regression when negotiation fails
|
||||
|
||||
1.0.5 / 2014-06-03
|
||||
==================
|
||||
|
||||
* fix listeners for delayed stream creation
|
||||
- fixes regression for certain `stream.pipe(res)` situations
|
||||
|
||||
1.0.4 / 2014-06-03
|
||||
==================
|
||||
|
||||
* fix adding `Vary` when value stored as array
|
||||
* fix back-pressure behavior
|
||||
* fix length check for `res.end`
|
||||
|
||||
1.0.3 / 2014-05-29
|
||||
==================
|
||||
|
||||
* use `accepts` for negotiation
|
||||
* use `on-headers` to handle header checking
|
||||
* deps: bytes@1.0.0
|
||||
|
||||
1.0.2 / 2014-04-29
|
||||
==================
|
||||
|
||||
* only version compatible with node.js 0.8
|
||||
* support headers given to `res.writeHead`
|
||||
* deps: bytes@0.3.0
|
||||
* deps: negotiator@0.4.3
|
||||
|
||||
1.0.1 / 2014-03-08
|
||||
==================
|
||||
|
||||
* bump negotiator
|
||||
* use compressible
|
||||
* use .headersSent (drops 0.8 support)
|
||||
* handle identity;q=0 case
|
||||
23
node_modules/compression/LICENSE
generated
vendored
Normal file
23
node_modules/compression/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
311
node_modules/compression/README.md
generated
vendored
Normal file
311
node_modules/compression/README.md
generated
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
# compression
|
||||
|
||||
[![NPM Version][npm-image]][npm-url]
|
||||
[![NPM Downloads][downloads-image]][downloads-url]
|
||||
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||
[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
|
||||
[![Funding][funding-image]][funding-url]
|
||||
|
||||
|
||||
Node.js compression middleware.
|
||||
|
||||
The following compression codings are supported:
|
||||
|
||||
- deflate
|
||||
- gzip
|
||||
- br (brotli)
|
||||
|
||||
**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
|
||||
|
||||
## Install
|
||||
|
||||
This is a [Node.js](https://nodejs.org/en/) module available through the
|
||||
[npm registry](https://www.npmjs.com/). Installation is done using the
|
||||
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
||||
|
||||
```bash
|
||||
$ npm install compression
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var compression = require('compression')
|
||||
```
|
||||
|
||||
### compression([options])
|
||||
|
||||
Returns the compression middleware using the given `options`. The middleware
|
||||
will attempt to compress response bodies for all requests that traverse through
|
||||
the middleware, based on the given `options`.
|
||||
|
||||
This middleware will never compress responses that include a `Cache-Control`
|
||||
header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
|
||||
as compressing will transform the body.
|
||||
|
||||
#### Options
|
||||
|
||||
`compression()` accepts these properties in the options object. In addition to
|
||||
those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
|
||||
passed in to the options object or
|
||||
[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
|
||||
|
||||
##### chunkSize
|
||||
|
||||
Type: `Number`<br>
|
||||
Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
|
||||
|
||||
See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
|
||||
regarding the usage.
|
||||
|
||||
##### filter
|
||||
|
||||
Type: `Function`
|
||||
|
||||
A function to decide if the response should be considered for compression.
|
||||
This function is called as `filter(req, res)` and is expected to return
|
||||
`true` to consider the response for compression, or `false` to not compress
|
||||
the response.
|
||||
|
||||
The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
|
||||
module to determine if `res.getHeader('Content-Type')` is compressible.
|
||||
|
||||
##### level
|
||||
|
||||
Type: `Number`<br>
|
||||
Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
|
||||
|
||||
The level of zlib compression to apply to responses. A higher level will result
|
||||
in better compression, but will take longer to complete. A lower level will
|
||||
result in less compression, but will be much faster.
|
||||
|
||||
This is an integer in the range of `0` (no compression) to `9` (maximum
|
||||
compression). The special value `-1` can be used to mean the "default
|
||||
compression level", which is a default compromise between speed and
|
||||
compression (currently equivalent to level 6).
|
||||
|
||||
- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
|
||||
- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
|
||||
- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
|
||||
- `2`
|
||||
- `3`
|
||||
- `4`
|
||||
- `5`
|
||||
- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
|
||||
- `7`
|
||||
- `8`
|
||||
- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
|
||||
|
||||
**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
|
||||
|
||||
##### memLevel
|
||||
|
||||
Type: `Number`<br>
|
||||
Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
|
||||
|
||||
This specifies how much memory should be allocated for the internal compression
|
||||
state and is an integer in the range of `1` (minimum level) and `9` (maximum
|
||||
level).
|
||||
|
||||
See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
|
||||
regarding the usage.
|
||||
|
||||
##### brotli
|
||||
|
||||
Type: `Object`
|
||||
|
||||
This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
|
||||
|
||||
|
||||
##### strategy
|
||||
|
||||
Type: `Number`<br>
|
||||
Default: `zlib.constants.Z_DEFAULT_STRATEGY`
|
||||
|
||||
This is used to tune the compression algorithm. This value only affects the
|
||||
compression ratio, not the correctness of the compressed output, even if it
|
||||
is not set appropriately.
|
||||
|
||||
- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
|
||||
- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
|
||||
Filtered data consists mostly of small values with a somewhat random
|
||||
distribution. In this case, the compression algorithm is tuned to
|
||||
compress them better. The effect is to force more Huffman coding and less
|
||||
string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
|
||||
and `zlib.constants.Z_HUFFMAN_ONLY`.
|
||||
- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
|
||||
for a simpler decoder for special applications.
|
||||
- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
|
||||
- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
|
||||
This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
|
||||
better compression for PNG image data.
|
||||
|
||||
**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
|
||||
|
||||
##### threshold
|
||||
|
||||
Type: `Number` or `String`<br>
|
||||
Default: `1kb`
|
||||
|
||||
The byte threshold for the response body size before compression is considered
|
||||
for the response. This is a number of bytes or any string
|
||||
accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
|
||||
|
||||
**Note** this is only an advisory setting; if the response size cannot be determined
|
||||
at the time the response headers are written, then it is assumed the response is
|
||||
_over_ the threshold. To guarantee the response size can be determined, be sure
|
||||
set a `Content-Length` response header.
|
||||
|
||||
##### windowBits
|
||||
|
||||
Type: `Number`<br>
|
||||
Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
|
||||
|
||||
See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
|
||||
regarding the usage.
|
||||
|
||||
##### enforceEncoding
|
||||
|
||||
Type: `String`<br>
|
||||
Default: `identity`
|
||||
|
||||
This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
|
||||
|
||||
#### .filter
|
||||
|
||||
The default `filter` function. This is used to construct a custom filter
|
||||
function that is an extension of the default function.
|
||||
|
||||
```js
|
||||
var compression = require('compression')
|
||||
var express = require('express')
|
||||
|
||||
var app = express()
|
||||
|
||||
app.use(compression({ filter: shouldCompress }))
|
||||
|
||||
function shouldCompress (req, res) {
|
||||
if (req.headers['x-no-compression']) {
|
||||
// don't compress responses with this request header
|
||||
return false
|
||||
}
|
||||
|
||||
// fallback to standard filter function
|
||||
return compression.filter(req, res)
|
||||
}
|
||||
```
|
||||
|
||||
### res.flush
|
||||
|
||||
This module adds a `res.flush()` method to force the partially-compressed
|
||||
response to be flushed to the client.
|
||||
|
||||
## Examples
|
||||
|
||||
### express
|
||||
|
||||
When using this module with express, simply `app.use` the module as
|
||||
high as you like. Requests that pass through the middleware will be compressed.
|
||||
|
||||
```js
|
||||
var compression = require('compression')
|
||||
var express = require('express')
|
||||
|
||||
var app = express()
|
||||
|
||||
// compress all responses
|
||||
app.use(compression())
|
||||
|
||||
// add all routes
|
||||
```
|
||||
|
||||
### Node.js HTTP server
|
||||
|
||||
```js
|
||||
var compression = require('compression')({ threshold: 0 })
|
||||
var http = require('http')
|
||||
|
||||
function createServer (fn) {
|
||||
return http.createServer(function (req, res) {
|
||||
compression(req, res, function (err) {
|
||||
if (err) {
|
||||
res.statusCode = err.status || 500
|
||||
res.end(err.message)
|
||||
return
|
||||
}
|
||||
|
||||
fn(req, res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
var server = createServer(function (req, res) {
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.end('hello world!')
|
||||
})
|
||||
|
||||
server.listen(3000, () => {
|
||||
console.log('> Listening at http://localhost:3000')
|
||||
})
|
||||
```
|
||||
|
||||
### Server-Sent Events
|
||||
|
||||
Because of the nature of compression this module does not work out of the box
|
||||
with server-sent events. To compress content, a window of the output needs to
|
||||
be buffered up in order to get good compression. Typically when using server-sent
|
||||
events, there are certain block of data that need to reach the client.
|
||||
|
||||
You can achieve this by calling `res.flush()` when you need the data written to
|
||||
actually make it to the client.
|
||||
|
||||
```js
|
||||
var compression = require('compression')
|
||||
var express = require('express')
|
||||
|
||||
var app = express()
|
||||
|
||||
// compress responses
|
||||
app.use(compression())
|
||||
|
||||
// server-sent event stream
|
||||
app.get('/events', function (req, res) {
|
||||
res.setHeader('Content-Type', 'text/event-stream')
|
||||
res.setHeader('Cache-Control', 'no-cache')
|
||||
|
||||
// send a ping approx every 2 seconds
|
||||
var timer = setInterval(function () {
|
||||
res.write('data: ping\n\n')
|
||||
|
||||
// !!! this is the important part
|
||||
res.flush()
|
||||
}, 2000)
|
||||
|
||||
res.on('close', function () {
|
||||
clearInterval(timer)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
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](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[npm-image]: https://badgen.net/npm/v/compression
|
||||
[npm-url]: https://npmjs.org/package/compression
|
||||
[downloads-image]: https://badgen.net/npm/dm/compression
|
||||
[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
|
||||
[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
|
||||
[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
|
||||
[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
|
||||
[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
|
||||
[funding-url]: https://opencollective.com/express
|
||||
[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
|
||||
325
node_modules/compression/index.js
generated
vendored
Normal file
325
node_modules/compression/index.js
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
/*!
|
||||
* compression
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var Negotiator = require('negotiator')
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
var bytes = require('bytes')
|
||||
var compressible = require('compressible')
|
||||
var debug = require('debug')('compression')
|
||||
var onHeaders = require('on-headers')
|
||||
var vary = require('vary')
|
||||
var zlib = require('zlib')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = compression
|
||||
module.exports.filter = shouldCompress
|
||||
|
||||
/**
|
||||
* @const
|
||||
* whether current node version has brotli support
|
||||
*/
|
||||
var hasBrotliSupport = 'createBrotliCompress' in zlib
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
* @private
|
||||
*/
|
||||
var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/
|
||||
var SUPPORTED_ENCODING = hasBrotliSupport ? ['br', 'gzip', 'deflate', 'identity'] : ['gzip', 'deflate', 'identity']
|
||||
var PREFERRED_ENCODING = hasBrotliSupport ? ['br', 'gzip'] : ['gzip']
|
||||
|
||||
var encodingSupported = ['gzip', 'deflate', 'identity', 'br']
|
||||
|
||||
/**
|
||||
* Compress response data with gzip / deflate.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @return {Function} middleware
|
||||
* @public
|
||||
*/
|
||||
|
||||
function compression (options) {
|
||||
var opts = options || {}
|
||||
var optsBrotli = {}
|
||||
|
||||
if (hasBrotliSupport) {
|
||||
Object.assign(optsBrotli, opts.brotli)
|
||||
|
||||
var brotliParams = {}
|
||||
brotliParams[zlib.constants.BROTLI_PARAM_QUALITY] = 4
|
||||
|
||||
// set the default level to a reasonable value with balanced speed/ratio
|
||||
optsBrotli.params = Object.assign(brotliParams, optsBrotli.params)
|
||||
}
|
||||
|
||||
// options
|
||||
var filter = opts.filter || shouldCompress
|
||||
var threshold = bytes.parse(opts.threshold)
|
||||
var enforceEncoding = opts.enforceEncoding || 'identity'
|
||||
|
||||
if (threshold == null) {
|
||||
threshold = 1024
|
||||
}
|
||||
|
||||
return function compression (req, res, next) {
|
||||
var ended = false
|
||||
var length
|
||||
var listeners = []
|
||||
var stream
|
||||
|
||||
var _end = res.end
|
||||
var _on = res.on
|
||||
var _write = res.write
|
||||
|
||||
// flush
|
||||
res.flush = function flush () {
|
||||
if (stream) {
|
||||
stream.flush()
|
||||
}
|
||||
}
|
||||
|
||||
// proxy
|
||||
|
||||
res.write = function write (chunk, encoding) {
|
||||
if (ended) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!headersSent(res)) {
|
||||
this.writeHead(this.statusCode)
|
||||
}
|
||||
|
||||
return stream
|
||||
? stream.write(toBuffer(chunk, encoding))
|
||||
: _write.call(this, chunk, encoding)
|
||||
}
|
||||
|
||||
res.end = function end (chunk, encoding) {
|
||||
if (ended) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!headersSent(res)) {
|
||||
// estimate the length
|
||||
if (!this.getHeader('Content-Length')) {
|
||||
length = chunkLength(chunk, encoding)
|
||||
}
|
||||
|
||||
this.writeHead(this.statusCode)
|
||||
}
|
||||
|
||||
if (!stream) {
|
||||
return _end.call(this, chunk, encoding)
|
||||
}
|
||||
|
||||
// mark ended
|
||||
ended = true
|
||||
|
||||
// write Buffer for Node.js 0.8
|
||||
return chunk
|
||||
? stream.end(toBuffer(chunk, encoding))
|
||||
: stream.end()
|
||||
}
|
||||
|
||||
res.on = function on (type, listener) {
|
||||
if (!listeners || type !== 'drain') {
|
||||
return _on.call(this, type, listener)
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
return stream.on(type, listener)
|
||||
}
|
||||
|
||||
// buffer listeners for future stream
|
||||
listeners.push([type, listener])
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
function nocompress (msg) {
|
||||
debug('no compression: %s', msg)
|
||||
addListeners(res, _on, listeners)
|
||||
listeners = null
|
||||
}
|
||||
|
||||
onHeaders(res, function onResponseHeaders () {
|
||||
// determine if request is filtered
|
||||
if (!filter(req, res)) {
|
||||
nocompress('filtered')
|
||||
return
|
||||
}
|
||||
|
||||
// determine if the entity should be transformed
|
||||
if (!shouldTransform(req, res)) {
|
||||
nocompress('no transform')
|
||||
return
|
||||
}
|
||||
|
||||
// vary
|
||||
vary(res, 'Accept-Encoding')
|
||||
|
||||
// content-length below threshold
|
||||
if (Number(res.getHeader('Content-Length')) < threshold || length < threshold) {
|
||||
nocompress('size below threshold')
|
||||
return
|
||||
}
|
||||
|
||||
var encoding = res.getHeader('Content-Encoding') || 'identity'
|
||||
|
||||
// already encoded
|
||||
if (encoding !== 'identity') {
|
||||
nocompress('already encoded')
|
||||
return
|
||||
}
|
||||
|
||||
// head
|
||||
if (req.method === 'HEAD') {
|
||||
nocompress('HEAD request')
|
||||
return
|
||||
}
|
||||
|
||||
// compression method
|
||||
var negotiator = new Negotiator(req)
|
||||
var method = negotiator.encoding(SUPPORTED_ENCODING, PREFERRED_ENCODING)
|
||||
|
||||
// if no method is found, use the default encoding
|
||||
if (!req.headers['accept-encoding'] && encodingSupported.indexOf(enforceEncoding) !== -1) {
|
||||
method = enforceEncoding
|
||||
}
|
||||
|
||||
// negotiation failed
|
||||
if (!method || method === 'identity') {
|
||||
nocompress('not acceptable')
|
||||
return
|
||||
}
|
||||
|
||||
// compression stream
|
||||
debug('%s compression', method)
|
||||
stream = method === 'gzip'
|
||||
? zlib.createGzip(opts)
|
||||
: method === 'br'
|
||||
? zlib.createBrotliCompress(optsBrotli)
|
||||
: zlib.createDeflate(opts)
|
||||
|
||||
// add buffered listeners to stream
|
||||
addListeners(stream, stream.on, listeners)
|
||||
|
||||
// header fields
|
||||
res.setHeader('Content-Encoding', method)
|
||||
res.removeHeader('Content-Length')
|
||||
|
||||
// compression
|
||||
stream.on('data', function onStreamData (chunk) {
|
||||
if (_write.call(res, chunk) === false) {
|
||||
stream.pause()
|
||||
}
|
||||
})
|
||||
|
||||
stream.on('end', function onStreamEnd () {
|
||||
_end.call(res)
|
||||
})
|
||||
|
||||
_on.call(res, 'drain', function onResponseDrain () {
|
||||
stream.resume()
|
||||
})
|
||||
})
|
||||
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add bufferred listeners to stream
|
||||
* @private
|
||||
*/
|
||||
|
||||
function addListeners (stream, on, listeners) {
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
on.apply(stream, listeners[i])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of a given chunk
|
||||
*/
|
||||
|
||||
function chunkLength (chunk, encoding) {
|
||||
if (!chunk) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Buffer.isBuffer(chunk)
|
||||
? chunk.length
|
||||
: Buffer.byteLength(chunk, encoding)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default filter function.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function shouldCompress (req, res) {
|
||||
var type = res.getHeader('Content-Type')
|
||||
|
||||
if (type === undefined || !compressible(type)) {
|
||||
debug('%s not compressible', type)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the entity should be transformed.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function shouldTransform (req, res) {
|
||||
var cacheControl = res.getHeader('Cache-Control')
|
||||
|
||||
// Don't compress for Cache-Control: no-transform
|
||||
// https://tools.ietf.org/html/rfc7234#section-5.2.2.4
|
||||
return !cacheControl ||
|
||||
!cacheControlNoTransformRegExp.test(cacheControl)
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce arguments to Buffer
|
||||
* @private
|
||||
*/
|
||||
|
||||
function toBuffer (chunk, encoding) {
|
||||
return Buffer.isBuffer(chunk)
|
||||
? chunk
|
||||
: Buffer.from(chunk, encoding)
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the response headers have been sent.
|
||||
*
|
||||
* @param {object} res
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function headersSent (res) {
|
||||
return typeof res.headersSent !== 'boolean'
|
||||
? Boolean(res._header)
|
||||
: res.headersSent
|
||||
}
|
||||
113
node_modules/compression/node_modules/negotiator/HISTORY.md
generated
vendored
Normal file
113
node_modules/compression/node_modules/negotiator/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
unreleased
|
||||
==================
|
||||
|
||||
* Added an option preferred encodings array #59
|
||||
|
||||
0.6.3 / 2022-01-22
|
||||
==================
|
||||
|
||||
* Revert "Lazy-load modules from main entry point"
|
||||
|
||||
0.6.2 / 2019-04-29
|
||||
==================
|
||||
|
||||
* Fix sorting charset, encoding, and language with extra parameters
|
||||
|
||||
0.6.1 / 2016-05-02
|
||||
==================
|
||||
|
||||
* perf: improve `Accept` parsing speed
|
||||
* perf: improve `Accept-Charset` parsing speed
|
||||
* perf: improve `Accept-Encoding` parsing speed
|
||||
* perf: improve `Accept-Language` parsing speed
|
||||
|
||||
0.6.0 / 2015-09-29
|
||||
==================
|
||||
|
||||
* Fix including type extensions in parameters in `Accept` parsing
|
||||
* Fix parsing `Accept` parameters with quoted equals
|
||||
* Fix parsing `Accept` parameters with quoted semicolons
|
||||
* Lazy-load modules from main entry point
|
||||
* perf: delay type concatenation until needed
|
||||
* perf: enable strict mode
|
||||
* perf: hoist regular expressions
|
||||
* perf: remove closures getting spec properties
|
||||
* perf: remove a closure from media type parsing
|
||||
* perf: remove property delete from media type parsing
|
||||
|
||||
0.5.3 / 2015-05-10
|
||||
==================
|
||||
|
||||
* Fix media type parameter matching to be case-insensitive
|
||||
|
||||
0.5.2 / 2015-05-06
|
||||
==================
|
||||
|
||||
* Fix comparing media types with quoted values
|
||||
* Fix splitting media types with quoted commas
|
||||
|
||||
0.5.1 / 2015-02-14
|
||||
==================
|
||||
|
||||
* Fix preference sorting to be stable for long acceptable lists
|
||||
|
||||
0.5.0 / 2014-12-18
|
||||
==================
|
||||
|
||||
* Fix list return order when large accepted list
|
||||
* Fix missing identity encoding when q=0 exists
|
||||
* Remove dynamic building of Negotiator class
|
||||
|
||||
0.4.9 / 2014-10-14
|
||||
==================
|
||||
|
||||
* Fix error when media type has invalid parameter
|
||||
|
||||
0.4.8 / 2014-09-28
|
||||
==================
|
||||
|
||||
* Fix all negotiations to be case-insensitive
|
||||
* Stable sort preferences of same quality according to client order
|
||||
* Support Node.js 0.6
|
||||
|
||||
0.4.7 / 2014-06-24
|
||||
==================
|
||||
|
||||
* Handle invalid provided languages
|
||||
* Handle invalid provided media types
|
||||
|
||||
0.4.6 / 2014-06-11
|
||||
==================
|
||||
|
||||
* Order by specificity when quality is the same
|
||||
|
||||
0.4.5 / 2014-05-29
|
||||
==================
|
||||
|
||||
* Fix regression in empty header handling
|
||||
|
||||
0.4.4 / 2014-05-29
|
||||
==================
|
||||
|
||||
* Fix behaviors when headers are not present
|
||||
|
||||
0.4.3 / 2014-04-16
|
||||
==================
|
||||
|
||||
* Handle slashes on media params correctly
|
||||
|
||||
0.4.2 / 2014-02-28
|
||||
==================
|
||||
|
||||
* Fix media type sorting
|
||||
* Handle media types params strictly
|
||||
|
||||
0.4.1 / 2014-01-16
|
||||
==================
|
||||
|
||||
* Use most specific matches
|
||||
|
||||
0.4.0 / 2014-01-09
|
||||
==================
|
||||
|
||||
* Remove preferred prefix from methods
|
||||
24
node_modules/compression/node_modules/negotiator/LICENSE
generated
vendored
Normal file
24
node_modules/compression/node_modules/negotiator/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2012-2014 Federico Romero
|
||||
Copyright (c) 2012-2014 Isaac Z. Schlueter
|
||||
Copyright (c) 2014-2015 Douglas Christopher Wilson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
212
node_modules/compression/node_modules/negotiator/README.md
generated
vendored
Normal file
212
node_modules/compression/node_modules/negotiator/README.md
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
# negotiator
|
||||
|
||||
[![NPM Version][npm-image]][npm-url]
|
||||
[![NPM Downloads][downloads-image]][downloads-url]
|
||||
[![Node.js Version][node-version-image]][node-version-url]
|
||||
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
An HTTP content negotiator for Node.js
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ npm install negotiator
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var Negotiator = require('negotiator')
|
||||
```
|
||||
|
||||
### Accept Negotiation
|
||||
|
||||
```js
|
||||
availableMediaTypes = ['text/html', 'text/plain', 'application/json']
|
||||
|
||||
// The negotiator constructor receives a request object
|
||||
negotiator = new Negotiator(request)
|
||||
|
||||
// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'
|
||||
|
||||
negotiator.mediaTypes()
|
||||
// -> ['text/html', 'image/jpeg', 'application/*']
|
||||
|
||||
negotiator.mediaTypes(availableMediaTypes)
|
||||
// -> ['text/html', 'application/json']
|
||||
|
||||
negotiator.mediaType(availableMediaTypes)
|
||||
// -> 'text/html'
|
||||
```
|
||||
|
||||
You can check a working example at `examples/accept.js`.
|
||||
|
||||
#### Methods
|
||||
|
||||
##### mediaType()
|
||||
|
||||
Returns the most preferred media type from the client.
|
||||
|
||||
##### mediaType(availableMediaType)
|
||||
|
||||
Returns the most preferred media type from a list of available media types.
|
||||
|
||||
##### mediaTypes()
|
||||
|
||||
Returns an array of preferred media types ordered by the client preference.
|
||||
|
||||
##### mediaTypes(availableMediaTypes)
|
||||
|
||||
Returns an array of preferred media types ordered by priority from a list of
|
||||
available media types.
|
||||
|
||||
### Accept-Language Negotiation
|
||||
|
||||
```js
|
||||
negotiator = new Negotiator(request)
|
||||
|
||||
availableLanguages = ['en', 'es', 'fr']
|
||||
|
||||
// Let's say Accept-Language header is 'en;q=0.8, es, pt'
|
||||
|
||||
negotiator.languages()
|
||||
// -> ['es', 'pt', 'en']
|
||||
|
||||
negotiator.languages(availableLanguages)
|
||||
// -> ['es', 'en']
|
||||
|
||||
language = negotiator.language(availableLanguages)
|
||||
// -> 'es'
|
||||
```
|
||||
|
||||
You can check a working example at `examples/language.js`.
|
||||
|
||||
#### Methods
|
||||
|
||||
##### language()
|
||||
|
||||
Returns the most preferred language from the client.
|
||||
|
||||
##### language(availableLanguages)
|
||||
|
||||
Returns the most preferred language from a list of available languages.
|
||||
|
||||
##### languages()
|
||||
|
||||
Returns an array of preferred languages ordered by the client preference.
|
||||
|
||||
##### languages(availableLanguages)
|
||||
|
||||
Returns an array of preferred languages ordered by priority from a list of
|
||||
available languages.
|
||||
|
||||
### Accept-Charset Negotiation
|
||||
|
||||
```js
|
||||
availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']
|
||||
|
||||
negotiator = new Negotiator(request)
|
||||
|
||||
// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'
|
||||
|
||||
negotiator.charsets()
|
||||
// -> ['utf-8', 'iso-8859-1', 'utf-7']
|
||||
|
||||
negotiator.charsets(availableCharsets)
|
||||
// -> ['utf-8', 'iso-8859-1']
|
||||
|
||||
negotiator.charset(availableCharsets)
|
||||
// -> 'utf-8'
|
||||
```
|
||||
|
||||
You can check a working example at `examples/charset.js`.
|
||||
|
||||
#### Methods
|
||||
|
||||
##### charset()
|
||||
|
||||
Returns the most preferred charset from the client.
|
||||
|
||||
##### charset(availableCharsets)
|
||||
|
||||
Returns the most preferred charset from a list of available charsets.
|
||||
|
||||
##### charsets()
|
||||
|
||||
Returns an array of preferred charsets ordered by the client preference.
|
||||
|
||||
##### charsets(availableCharsets)
|
||||
|
||||
Returns an array of preferred charsets ordered by priority from a list of
|
||||
available charsets.
|
||||
|
||||
### Accept-Encoding Negotiation
|
||||
|
||||
```js
|
||||
availableEncodings = ['identity', 'gzip']
|
||||
|
||||
negotiator = new Negotiator(request)
|
||||
|
||||
// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'
|
||||
|
||||
negotiator.encodings()
|
||||
// -> ['gzip', 'identity', 'compress']
|
||||
|
||||
negotiator.encodings(availableEncodings)
|
||||
// -> ['gzip', 'identity']
|
||||
|
||||
negotiator.encoding(availableEncodings)
|
||||
// -> 'gzip'
|
||||
```
|
||||
|
||||
You can check a working example at `examples/encoding.js`.
|
||||
|
||||
#### Methods
|
||||
|
||||
##### encoding()
|
||||
|
||||
Returns the most preferred encoding from the client.
|
||||
|
||||
##### encoding(availableEncodings)
|
||||
|
||||
Returns the most preferred encoding from a list of available encodings.
|
||||
|
||||
##### encoding(availableEncodings, preferred)
|
||||
|
||||
Returns the most preferred encoding from a list of available encodings, while prioritizing based on `preferred` array between same-quality encodings.
|
||||
|
||||
##### encodings()
|
||||
|
||||
Returns an array of preferred encodings ordered by the client preference.
|
||||
|
||||
##### encodings(availableEncodings)
|
||||
|
||||
Returns an array of preferred encodings ordered by priority from a list of
|
||||
available encodings.
|
||||
|
||||
##### encodings(availableEncodings, preferred)
|
||||
|
||||
Returns an array of preferred encodings ordered by priority from a list of
|
||||
available encodings, while prioritizing based on `preferred` array between same-quality encodings.
|
||||
|
||||
## See Also
|
||||
|
||||
The [accepts](https://npmjs.org/package/accepts#readme) module builds on
|
||||
this module and provides an alternative interface, mime type validation,
|
||||
and more.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/negotiator.svg
|
||||
[npm-url]: https://npmjs.org/package/negotiator
|
||||
[node-version-image]: https://img.shields.io/node/v/negotiator.svg
|
||||
[node-version-url]: https://nodejs.org/en/download/
|
||||
[coveralls-image]: https://img.shields.io/coveralls/jshttp/negotiator/master.svg
|
||||
[coveralls-url]: https://coveralls.io/r/jshttp/negotiator?branch=master
|
||||
[downloads-image]: https://img.shields.io/npm/dm/negotiator.svg
|
||||
[downloads-url]: https://npmjs.org/package/negotiator
|
||||
[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/negotiator/ci/master?label=ci
|
||||
[github-actions-ci-url]: https://github.com/jshttp/negotiator/actions/workflows/ci.yml
|
||||
82
node_modules/compression/node_modules/negotiator/index.js
generated
vendored
Normal file
82
node_modules/compression/node_modules/negotiator/index.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* negotiator
|
||||
* Copyright(c) 2012 Federico Romero
|
||||
* Copyright(c) 2012-2014 Isaac Z. Schlueter
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var preferredCharsets = require('./lib/charset')
|
||||
var preferredEncodings = require('./lib/encoding')
|
||||
var preferredLanguages = require('./lib/language')
|
||||
var preferredMediaTypes = require('./lib/mediaType')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = Negotiator;
|
||||
module.exports.Negotiator = Negotiator;
|
||||
|
||||
/**
|
||||
* Create a Negotiator instance from a request.
|
||||
* @param {object} request
|
||||
* @public
|
||||
*/
|
||||
|
||||
function Negotiator(request) {
|
||||
if (!(this instanceof Negotiator)) {
|
||||
return new Negotiator(request);
|
||||
}
|
||||
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
Negotiator.prototype.charset = function charset(available) {
|
||||
var set = this.charsets(available);
|
||||
return set && set[0];
|
||||
};
|
||||
|
||||
Negotiator.prototype.charsets = function charsets(available) {
|
||||
return preferredCharsets(this.request.headers['accept-charset'], available);
|
||||
};
|
||||
|
||||
Negotiator.prototype.encoding = function encoding(available, preferred) {
|
||||
var set = this.encodings(available, preferred);
|
||||
return set && set[0];
|
||||
};
|
||||
|
||||
Negotiator.prototype.encodings = function encodings(available, preferred) {
|
||||
return preferredEncodings(this.request.headers['accept-encoding'], available, preferred);
|
||||
};
|
||||
|
||||
Negotiator.prototype.language = function language(available) {
|
||||
var set = this.languages(available);
|
||||
return set && set[0];
|
||||
};
|
||||
|
||||
Negotiator.prototype.languages = function languages(available) {
|
||||
return preferredLanguages(this.request.headers['accept-language'], available);
|
||||
};
|
||||
|
||||
Negotiator.prototype.mediaType = function mediaType(available) {
|
||||
var set = this.mediaTypes(available);
|
||||
return set && set[0];
|
||||
};
|
||||
|
||||
Negotiator.prototype.mediaTypes = function mediaTypes(available) {
|
||||
return preferredMediaTypes(this.request.headers.accept, available);
|
||||
};
|
||||
|
||||
// Backwards compatibility
|
||||
Negotiator.prototype.preferredCharset = Negotiator.prototype.charset;
|
||||
Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets;
|
||||
Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding;
|
||||
Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings;
|
||||
Negotiator.prototype.preferredLanguage = Negotiator.prototype.language;
|
||||
Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages;
|
||||
Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType;
|
||||
Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes;
|
||||
169
node_modules/compression/node_modules/negotiator/lib/charset.js
generated
vendored
Normal file
169
node_modules/compression/node_modules/negotiator/lib/charset.js
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* negotiator
|
||||
* Copyright(c) 2012 Isaac Z. Schlueter
|
||||
* Copyright(c) 2014 Federico Romero
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = preferredCharsets;
|
||||
module.exports.preferredCharsets = preferredCharsets;
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
|
||||
|
||||
/**
|
||||
* Parse the Accept-Charset header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseAcceptCharset(accept) {
|
||||
var accepts = accept.split(',');
|
||||
|
||||
for (var i = 0, j = 0; i < accepts.length; i++) {
|
||||
var charset = parseCharset(accepts[i].trim(), i);
|
||||
|
||||
if (charset) {
|
||||
accepts[j++] = charset;
|
||||
}
|
||||
}
|
||||
|
||||
// trim accepts
|
||||
accepts.length = j;
|
||||
|
||||
return accepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a charset from the Accept-Charset header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseCharset(str, i) {
|
||||
var match = simpleCharsetRegExp.exec(str);
|
||||
if (!match) return null;
|
||||
|
||||
var charset = match[1];
|
||||
var q = 1;
|
||||
if (match[2]) {
|
||||
var params = match[2].split(';')
|
||||
for (var j = 0; j < params.length; j++) {
|
||||
var p = params[j].trim().split('=');
|
||||
if (p[0] === 'q') {
|
||||
q = parseFloat(p[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
charset: charset,
|
||||
q: q,
|
||||
i: i
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the priority of a charset.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getCharsetPriority(charset, accepted, index) {
|
||||
var priority = {o: -1, q: 0, s: 0};
|
||||
|
||||
for (var i = 0; i < accepted.length; i++) {
|
||||
var spec = specify(charset, accepted[i], index);
|
||||
|
||||
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
|
||||
priority = spec;
|
||||
}
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specificity of the charset.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function specify(charset, spec, index) {
|
||||
var s = 0;
|
||||
if(spec.charset.toLowerCase() === charset.toLowerCase()){
|
||||
s |= 1;
|
||||
} else if (spec.charset !== '*' ) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
i: index,
|
||||
o: spec.i,
|
||||
q: spec.q,
|
||||
s: s
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred charsets from an Accept-Charset header.
|
||||
* @public
|
||||
*/
|
||||
|
||||
function preferredCharsets(accept, provided) {
|
||||
// RFC 2616 sec 14.2: no header = *
|
||||
var accepts = parseAcceptCharset(accept === undefined ? '*' : accept || '');
|
||||
|
||||
if (!provided) {
|
||||
// sorted list of all charsets
|
||||
return accepts
|
||||
.filter(isQuality)
|
||||
.sort(compareSpecs)
|
||||
.map(getFullCharset);
|
||||
}
|
||||
|
||||
var priorities = provided.map(function getPriority(type, index) {
|
||||
return getCharsetPriority(type, accepts, index);
|
||||
});
|
||||
|
||||
// sorted list of accepted charsets
|
||||
return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) {
|
||||
return provided[priorities.indexOf(priority)];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two specs.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function compareSpecs(a, b) {
|
||||
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full charset string.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getFullCharset(spec) {
|
||||
return spec.charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a spec has any quality.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function isQuality(spec) {
|
||||
return spec.q > 0;
|
||||
}
|
||||
205
node_modules/compression/node_modules/negotiator/lib/encoding.js
generated
vendored
Normal file
205
node_modules/compression/node_modules/negotiator/lib/encoding.js
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* negotiator
|
||||
* Copyright(c) 2012 Isaac Z. Schlueter
|
||||
* Copyright(c) 2014 Federico Romero
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = preferredEncodings;
|
||||
module.exports.preferredEncodings = preferredEncodings;
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
|
||||
|
||||
/**
|
||||
* Parse the Accept-Encoding header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseAcceptEncoding(accept) {
|
||||
var accepts = accept.split(',');
|
||||
var hasIdentity = false;
|
||||
var minQuality = 1;
|
||||
|
||||
for (var i = 0, j = 0; i < accepts.length; i++) {
|
||||
var encoding = parseEncoding(accepts[i].trim(), i);
|
||||
|
||||
if (encoding) {
|
||||
accepts[j++] = encoding;
|
||||
hasIdentity = hasIdentity || specify('identity', encoding);
|
||||
minQuality = Math.min(minQuality, encoding.q || 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasIdentity) {
|
||||
/*
|
||||
* If identity doesn't explicitly appear in the accept-encoding header,
|
||||
* it's added to the list of acceptable encoding with the lowest q
|
||||
*/
|
||||
accepts[j++] = {
|
||||
encoding: 'identity',
|
||||
q: minQuality,
|
||||
i: i
|
||||
};
|
||||
}
|
||||
|
||||
// trim accepts
|
||||
accepts.length = j;
|
||||
|
||||
return accepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an encoding from the Accept-Encoding header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseEncoding(str, i) {
|
||||
var match = simpleEncodingRegExp.exec(str);
|
||||
if (!match) return null;
|
||||
|
||||
var encoding = match[1];
|
||||
var q = 1;
|
||||
if (match[2]) {
|
||||
var params = match[2].split(';');
|
||||
for (var j = 0; j < params.length; j++) {
|
||||
var p = params[j].trim().split('=');
|
||||
if (p[0] === 'q') {
|
||||
q = parseFloat(p[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
encoding: encoding,
|
||||
q: q,
|
||||
i: i
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the priority of an encoding.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getEncodingPriority(encoding, accepted, index) {
|
||||
var priority = {encoding: encoding, o: -1, q: 0, s: 0};
|
||||
|
||||
for (var i = 0; i < accepted.length; i++) {
|
||||
var spec = specify(encoding, accepted[i], index);
|
||||
|
||||
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
|
||||
priority = spec;
|
||||
}
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specificity of the encoding.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function specify(encoding, spec, index) {
|
||||
var s = 0;
|
||||
if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
|
||||
s |= 1;
|
||||
} else if (spec.encoding !== '*' ) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
encoding: encoding,
|
||||
i: index,
|
||||
o: spec.i,
|
||||
q: spec.q,
|
||||
s: s
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the preferred encodings from an Accept-Encoding header.
|
||||
* @public
|
||||
*/
|
||||
|
||||
function preferredEncodings(accept, provided, preferred) {
|
||||
var accepts = parseAcceptEncoding(accept || '');
|
||||
|
||||
var comparator = preferred ? function comparator (a, b) {
|
||||
if (a.q !== b.q) {
|
||||
return b.q - a.q // higher quality first
|
||||
}
|
||||
|
||||
var aPreferred = preferred.indexOf(a.encoding)
|
||||
var bPreferred = preferred.indexOf(b.encoding)
|
||||
|
||||
if (aPreferred === -1 && bPreferred === -1) {
|
||||
// consider the original specifity/order
|
||||
return (b.s - a.s) || (a.o - b.o) || (a.i - b.i)
|
||||
}
|
||||
|
||||
if (aPreferred !== -1 && bPreferred !== -1) {
|
||||
return aPreferred - bPreferred // consider the preferred order
|
||||
}
|
||||
|
||||
return aPreferred === -1 ? 1 : -1 // preferred first
|
||||
} : compareSpecs;
|
||||
|
||||
if (!provided) {
|
||||
// sorted list of all encodings
|
||||
return accepts
|
||||
.filter(isQuality)
|
||||
.sort(comparator)
|
||||
.map(getFullEncoding);
|
||||
}
|
||||
|
||||
var priorities = provided.map(function getPriority(type, index) {
|
||||
return getEncodingPriority(type, accepts, index);
|
||||
});
|
||||
|
||||
// sorted list of accepted encodings
|
||||
return priorities.filter(isQuality).sort(comparator).map(function getEncoding(priority) {
|
||||
return provided[priorities.indexOf(priority)];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two specs.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function compareSpecs(a, b) {
|
||||
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full encoding string.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getFullEncoding(spec) {
|
||||
return spec.encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a spec has any quality.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function isQuality(spec) {
|
||||
return spec.q > 0;
|
||||
}
|
||||
179
node_modules/compression/node_modules/negotiator/lib/language.js
generated
vendored
Normal file
179
node_modules/compression/node_modules/negotiator/lib/language.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* negotiator
|
||||
* Copyright(c) 2012 Isaac Z. Schlueter
|
||||
* Copyright(c) 2014 Federico Romero
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = preferredLanguages;
|
||||
module.exports.preferredLanguages = preferredLanguages;
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/;
|
||||
|
||||
/**
|
||||
* Parse the Accept-Language header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseAcceptLanguage(accept) {
|
||||
var accepts = accept.split(',');
|
||||
|
||||
for (var i = 0, j = 0; i < accepts.length; i++) {
|
||||
var language = parseLanguage(accepts[i].trim(), i);
|
||||
|
||||
if (language) {
|
||||
accepts[j++] = language;
|
||||
}
|
||||
}
|
||||
|
||||
// trim accepts
|
||||
accepts.length = j;
|
||||
|
||||
return accepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a language from the Accept-Language header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseLanguage(str, i) {
|
||||
var match = simpleLanguageRegExp.exec(str);
|
||||
if (!match) return null;
|
||||
|
||||
var prefix = match[1]
|
||||
var suffix = match[2]
|
||||
var full = prefix
|
||||
|
||||
if (suffix) full += "-" + suffix;
|
||||
|
||||
var q = 1;
|
||||
if (match[3]) {
|
||||
var params = match[3].split(';')
|
||||
for (var j = 0; j < params.length; j++) {
|
||||
var p = params[j].split('=');
|
||||
if (p[0] === 'q') q = parseFloat(p[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
prefix: prefix,
|
||||
suffix: suffix,
|
||||
q: q,
|
||||
i: i,
|
||||
full: full
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the priority of a language.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getLanguagePriority(language, accepted, index) {
|
||||
var priority = {o: -1, q: 0, s: 0};
|
||||
|
||||
for (var i = 0; i < accepted.length; i++) {
|
||||
var spec = specify(language, accepted[i], index);
|
||||
|
||||
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
|
||||
priority = spec;
|
||||
}
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specificity of the language.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function specify(language, spec, index) {
|
||||
var p = parseLanguage(language)
|
||||
if (!p) return null;
|
||||
var s = 0;
|
||||
if(spec.full.toLowerCase() === p.full.toLowerCase()){
|
||||
s |= 4;
|
||||
} else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) {
|
||||
s |= 2;
|
||||
} else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) {
|
||||
s |= 1;
|
||||
} else if (spec.full !== '*' ) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
i: index,
|
||||
o: spec.i,
|
||||
q: spec.q,
|
||||
s: s
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the preferred languages from an Accept-Language header.
|
||||
* @public
|
||||
*/
|
||||
|
||||
function preferredLanguages(accept, provided) {
|
||||
// RFC 2616 sec 14.4: no header = *
|
||||
var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || '');
|
||||
|
||||
if (!provided) {
|
||||
// sorted list of all languages
|
||||
return accepts
|
||||
.filter(isQuality)
|
||||
.sort(compareSpecs)
|
||||
.map(getFullLanguage);
|
||||
}
|
||||
|
||||
var priorities = provided.map(function getPriority(type, index) {
|
||||
return getLanguagePriority(type, accepts, index);
|
||||
});
|
||||
|
||||
// sorted list of accepted languages
|
||||
return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) {
|
||||
return provided[priorities.indexOf(priority)];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two specs.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function compareSpecs(a, b) {
|
||||
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full language string.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getFullLanguage(spec) {
|
||||
return spec.full;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a spec has any quality.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function isQuality(spec) {
|
||||
return spec.q > 0;
|
||||
}
|
||||
294
node_modules/compression/node_modules/negotiator/lib/mediaType.js
generated
vendored
Normal file
294
node_modules/compression/node_modules/negotiator/lib/mediaType.js
generated
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* negotiator
|
||||
* Copyright(c) 2012 Isaac Z. Schlueter
|
||||
* Copyright(c) 2014 Federico Romero
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = preferredMediaTypes;
|
||||
module.exports.preferredMediaTypes = preferredMediaTypes;
|
||||
|
||||
/**
|
||||
* Module variables.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/;
|
||||
|
||||
/**
|
||||
* Parse the Accept header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseAccept(accept) {
|
||||
var accepts = splitMediaTypes(accept);
|
||||
|
||||
for (var i = 0, j = 0; i < accepts.length; i++) {
|
||||
var mediaType = parseMediaType(accepts[i].trim(), i);
|
||||
|
||||
if (mediaType) {
|
||||
accepts[j++] = mediaType;
|
||||
}
|
||||
}
|
||||
|
||||
// trim accepts
|
||||
accepts.length = j;
|
||||
|
||||
return accepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a media type from the Accept header.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function parseMediaType(str, i) {
|
||||
var match = simpleMediaTypeRegExp.exec(str);
|
||||
if (!match) return null;
|
||||
|
||||
var params = Object.create(null);
|
||||
var q = 1;
|
||||
var subtype = match[2];
|
||||
var type = match[1];
|
||||
|
||||
if (match[3]) {
|
||||
var kvps = splitParameters(match[3]).map(splitKeyValuePair);
|
||||
|
||||
for (var j = 0; j < kvps.length; j++) {
|
||||
var pair = kvps[j];
|
||||
var key = pair[0].toLowerCase();
|
||||
var val = pair[1];
|
||||
|
||||
// get the value, unwrapping quotes
|
||||
var value = val && val[0] === '"' && val[val.length - 1] === '"'
|
||||
? val.slice(1, -1)
|
||||
: val;
|
||||
|
||||
if (key === 'q') {
|
||||
q = parseFloat(value);
|
||||
break;
|
||||
}
|
||||
|
||||
// store parameter
|
||||
params[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: type,
|
||||
subtype: subtype,
|
||||
params: params,
|
||||
q: q,
|
||||
i: i
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the priority of a media type.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getMediaTypePriority(type, accepted, index) {
|
||||
var priority = {o: -1, q: 0, s: 0};
|
||||
|
||||
for (var i = 0; i < accepted.length; i++) {
|
||||
var spec = specify(type, accepted[i], index);
|
||||
|
||||
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
|
||||
priority = spec;
|
||||
}
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specificity of the media type.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function specify(type, spec, index) {
|
||||
var p = parseMediaType(type);
|
||||
var s = 0;
|
||||
|
||||
if (!p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(spec.type.toLowerCase() == p.type.toLowerCase()) {
|
||||
s |= 4
|
||||
} else if(spec.type != '*') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
|
||||
s |= 2
|
||||
} else if(spec.subtype != '*') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var keys = Object.keys(spec.params);
|
||||
if (keys.length > 0) {
|
||||
if (keys.every(function (k) {
|
||||
return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
|
||||
})) {
|
||||
s |= 1
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
i: index,
|
||||
o: spec.i,
|
||||
q: spec.q,
|
||||
s: s,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred media types from an Accept header.
|
||||
* @public
|
||||
*/
|
||||
|
||||
function preferredMediaTypes(accept, provided) {
|
||||
// RFC 2616 sec 14.2: no header = */*
|
||||
var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');
|
||||
|
||||
if (!provided) {
|
||||
// sorted list of all types
|
||||
return accepts
|
||||
.filter(isQuality)
|
||||
.sort(compareSpecs)
|
||||
.map(getFullType);
|
||||
}
|
||||
|
||||
var priorities = provided.map(function getPriority(type, index) {
|
||||
return getMediaTypePriority(type, accepts, index);
|
||||
});
|
||||
|
||||
// sorted list of accepted types
|
||||
return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
|
||||
return provided[priorities.indexOf(priority)];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two specs.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function compareSpecs(a, b) {
|
||||
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full type string.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function getFullType(spec) {
|
||||
return spec.type + '/' + spec.subtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a spec has any quality.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function isQuality(spec) {
|
||||
return spec.q > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of quotes in a string.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function quoteCount(string) {
|
||||
var count = 0;
|
||||
var index = 0;
|
||||
|
||||
while ((index = string.indexOf('"', index)) !== -1) {
|
||||
count++;
|
||||
index++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a key value pair.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function splitKeyValuePair(str) {
|
||||
var index = str.indexOf('=');
|
||||
var key;
|
||||
var val;
|
||||
|
||||
if (index === -1) {
|
||||
key = str;
|
||||
} else {
|
||||
key = str.slice(0, index);
|
||||
val = str.slice(index + 1);
|
||||
}
|
||||
|
||||
return [key, val];
|
||||
}
|
||||
|
||||
/**
|
||||
* Split an Accept header into media types.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function splitMediaTypes(accept) {
|
||||
var accepts = accept.split(',');
|
||||
|
||||
for (var i = 1, j = 0; i < accepts.length; i++) {
|
||||
if (quoteCount(accepts[j]) % 2 == 0) {
|
||||
accepts[++j] = accepts[i];
|
||||
} else {
|
||||
accepts[j] += ',' + accepts[i];
|
||||
}
|
||||
}
|
||||
|
||||
// trim accepts
|
||||
accepts.length = j + 1;
|
||||
|
||||
return accepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a string of parameters.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function splitParameters(str) {
|
||||
var parameters = str.split(';');
|
||||
|
||||
for (var i = 1, j = 0; i < parameters.length; i++) {
|
||||
if (quoteCount(parameters[j]) % 2 == 0) {
|
||||
parameters[++j] = parameters[i];
|
||||
} else {
|
||||
parameters[j] += ';' + parameters[i];
|
||||
}
|
||||
}
|
||||
|
||||
// trim parameters
|
||||
parameters.length = j + 1;
|
||||
|
||||
for (var i = 0; i < parameters.length; i++) {
|
||||
parameters[i] = parameters[i].trim();
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
42
node_modules/compression/node_modules/negotiator/package.json
generated
vendored
Normal file
42
node_modules/compression/node_modules/negotiator/package.json
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "negotiator",
|
||||
"description": "HTTP content negotiation",
|
||||
"version": "0.6.4",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Federico Romero <federico.romero@outboxlabs.com>",
|
||||
"Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"http",
|
||||
"content negotiation",
|
||||
"accept",
|
||||
"accept-language",
|
||||
"accept-encoding",
|
||||
"accept-charset"
|
||||
],
|
||||
"repository": "jshttp/negotiator",
|
||||
"devDependencies": {
|
||||
"eslint": "7.32.0",
|
||||
"eslint-plugin-markdown": "2.2.1",
|
||||
"mocha": "9.1.3",
|
||||
"nyc": "15.1.0"
|
||||
},
|
||||
"files": [
|
||||
"lib/",
|
||||
"HISTORY.md",
|
||||
"LICENSE",
|
||||
"index.js",
|
||||
"README.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||
}
|
||||
}
|
||||
48
node_modules/compression/package.json
generated
vendored
Normal file
48
node_modules/compression/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "compression",
|
||||
"description": "Node.js compression middleware",
|
||||
"version": "1.8.1",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "expressjs/compression",
|
||||
"keywords": ["compression", "gzip", "deflate", "middleware", "express", "brotli", "http", "stream"],
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"compressible": "~2.0.18",
|
||||
"debug": "2.6.9",
|
||||
"negotiator": "~0.6.4",
|
||||
"on-headers": "~1.1.0",
|
||||
"safe-buffer": "5.2.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"after": "0.8.2",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-standard": "14.1.1",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"eslint-plugin-markdown": "2.2.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "5.2.0",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"mocha": "9.2.2",
|
||||
"nyc": "15.1.0",
|
||||
"supertest": "6.3.4"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"HISTORY.md",
|
||||
"index.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha --check-leaks --reporter spec",
|
||||
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user