update
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
"use strict";
|
||||
var Buffer = require("safer-buffer").Buffer;
|
||||
|
||||
// Export Node.js internal encodings.
|
||||
|
||||
module.exports = {
|
||||
// Encodings
|
||||
utf8: { type: "_internal", bomAware: true},
|
||||
cesu8: { type: "_internal", bomAware: true},
|
||||
unicode11utf8: "utf8",
|
||||
|
||||
ucs2: { type: "_internal", bomAware: true},
|
||||
utf16le: "ucs2",
|
||||
|
||||
binary: { type: "_internal" },
|
||||
base64: { type: "_internal" },
|
||||
hex: { type: "_internal" },
|
||||
|
||||
// Codec.
|
||||
_internal: InternalCodec,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
function InternalCodec(codecOptions, iconv) {
|
||||
this.enc = codecOptions.encodingName;
|
||||
this.bomAware = codecOptions.bomAware;
|
||||
|
||||
if (this.enc === "base64")
|
||||
this.encoder = InternalEncoderBase64;
|
||||
else if (this.enc === "cesu8") {
|
||||
this.enc = "utf8"; // Use utf8 for decoding.
|
||||
this.encoder = InternalEncoderCesu8;
|
||||
|
||||
// Add decoder for versions of Node not supporting CESU-8
|
||||
if (Buffer.from('eda0bdedb2a9', 'hex').toString() !== '💩') {
|
||||
this.decoder = InternalDecoderCesu8;
|
||||
this.defaultCharUnicode = iconv.defaultCharUnicode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InternalCodec.prototype.encoder = InternalEncoder;
|
||||
InternalCodec.prototype.decoder = InternalDecoder;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// We use node.js internal decoder. Its signature is the same as ours.
|
||||
var StringDecoder = require('string_decoder').StringDecoder;
|
||||
|
||||
if (!StringDecoder.prototype.end) // Node v0.8 doesn't have this method.
|
||||
StringDecoder.prototype.end = function() {};
|
||||
|
||||
|
||||
function InternalDecoder(options, codec) {
|
||||
this.decoder = new StringDecoder(codec.enc);
|
||||
}
|
||||
|
||||
InternalDecoder.prototype.write = function(buf) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
buf = Buffer.from(buf);
|
||||
}
|
||||
|
||||
return this.decoder.write(buf);
|
||||
}
|
||||
|
||||
InternalDecoder.prototype.end = function() {
|
||||
return this.decoder.end();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Encoder is mostly trivial
|
||||
|
||||
function InternalEncoder(options, codec) {
|
||||
this.enc = codec.enc;
|
||||
}
|
||||
|
||||
InternalEncoder.prototype.write = function(str) {
|
||||
return Buffer.from(str, this.enc);
|
||||
}
|
||||
|
||||
InternalEncoder.prototype.end = function() {
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Except base64 encoder, which must keep its state.
|
||||
|
||||
function InternalEncoderBase64(options, codec) {
|
||||
this.prevStr = '';
|
||||
}
|
||||
|
||||
InternalEncoderBase64.prototype.write = function(str) {
|
||||
str = this.prevStr + str;
|
||||
var completeQuads = str.length - (str.length % 4);
|
||||
this.prevStr = str.slice(completeQuads);
|
||||
str = str.slice(0, completeQuads);
|
||||
|
||||
return Buffer.from(str, "base64");
|
||||
}
|
||||
|
||||
InternalEncoderBase64.prototype.end = function() {
|
||||
return Buffer.from(this.prevStr, "base64");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CESU-8 encoder is also special.
|
||||
|
||||
function InternalEncoderCesu8(options, codec) {
|
||||
}
|
||||
|
||||
InternalEncoderCesu8.prototype.write = function(str) {
|
||||
var buf = Buffer.alloc(str.length * 3), bufIdx = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var charCode = str.charCodeAt(i);
|
||||
// Naive implementation, but it works because CESU-8 is especially easy
|
||||
// to convert from UTF-16 (which all JS strings are encoded in).
|
||||
if (charCode < 0x80)
|
||||
buf[bufIdx++] = charCode;
|
||||
else if (charCode < 0x800) {
|
||||
buf[bufIdx++] = 0xC0 + (charCode >>> 6);
|
||||
buf[bufIdx++] = 0x80 + (charCode & 0x3f);
|
||||
}
|
||||
else { // charCode will always be < 0x10000 in javascript.
|
||||
buf[bufIdx++] = 0xE0 + (charCode >>> 12);
|
||||
buf[bufIdx++] = 0x80 + ((charCode >>> 6) & 0x3f);
|
||||
buf[bufIdx++] = 0x80 + (charCode & 0x3f);
|
||||
}
|
||||
}
|
||||
return buf.slice(0, bufIdx);
|
||||
}
|
||||
|
||||
InternalEncoderCesu8.prototype.end = function() {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CESU-8 decoder is not implemented in Node v4.0+
|
||||
|
||||
function InternalDecoderCesu8(options, codec) {
|
||||
this.acc = 0;
|
||||
this.contBytes = 0;
|
||||
this.accBytes = 0;
|
||||
this.defaultCharUnicode = codec.defaultCharUnicode;
|
||||
}
|
||||
|
||||
InternalDecoderCesu8.prototype.write = function(buf) {
|
||||
var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes,
|
||||
res = '';
|
||||
for (var i = 0; i < buf.length; i++) {
|
||||
var curByte = buf[i];
|
||||
if ((curByte & 0xC0) !== 0x80) { // Leading byte
|
||||
if (contBytes > 0) { // Previous code is invalid
|
||||
res += this.defaultCharUnicode;
|
||||
contBytes = 0;
|
||||
}
|
||||
|
||||
if (curByte < 0x80) { // Single-byte code
|
||||
res += String.fromCharCode(curByte);
|
||||
} else if (curByte < 0xE0) { // Two-byte code
|
||||
acc = curByte & 0x1F;
|
||||
contBytes = 1; accBytes = 1;
|
||||
} else if (curByte < 0xF0) { // Three-byte code
|
||||
acc = curByte & 0x0F;
|
||||
contBytes = 2; accBytes = 1;
|
||||
} else { // Four or more are not supported for CESU-8.
|
||||
res += this.defaultCharUnicode;
|
||||
}
|
||||
} else { // Continuation byte
|
||||
if (contBytes > 0) { // We're waiting for it.
|
||||
acc = (acc << 6) | (curByte & 0x3f);
|
||||
contBytes--; accBytes++;
|
||||
if (contBytes === 0) {
|
||||
// Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80)
|
||||
if (accBytes === 2 && acc < 0x80 && acc > 0)
|
||||
res += this.defaultCharUnicode;
|
||||
else if (accBytes === 3 && acc < 0x800)
|
||||
res += this.defaultCharUnicode;
|
||||
else
|
||||
// Actually add character.
|
||||
res += String.fromCharCode(acc);
|
||||
}
|
||||
} else { // Unexpected continuation byte
|
||||
res += this.defaultCharUnicode;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.acc = acc; this.contBytes = contBytes; this.accBytes = accBytes;
|
||||
return res;
|
||||
}
|
||||
|
||||
InternalDecoderCesu8.prototype.end = function() {
|
||||
var res = 0;
|
||||
if (this.contBytes > 0)
|
||||
res += this.defaultCharUnicode;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
# Porting to the Buffer.from/Buffer.alloc API
|
||||
|
||||
<a id="overview"></a>
|
||||
## Overview
|
||||
|
||||
- [Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x.](#variant-1) (*recommended*)
|
||||
- [Variant 2: Use a polyfill](#variant-2)
|
||||
- [Variant 3: manual detection, with safeguards](#variant-3)
|
||||
|
||||
### Finding problematic bits of code using grep
|
||||
|
||||
Just run `grep -nrE '[^a-zA-Z](Slow)?Buffer\s*\(' --exclude-dir node_modules`.
|
||||
|
||||
It will find all the potentially unsafe places in your own code (with some considerably unlikely
|
||||
exceptions).
|
||||
|
||||
### Finding problematic bits of code using Node.js 8
|
||||
|
||||
If you’re using Node.js ≥ 8.0.0 (which is recommended), Node.js exposes multiple options that help with finding the relevant pieces of code:
|
||||
|
||||
- `--trace-warnings` will make Node.js show a stack trace for this warning and other warnings that are printed by Node.js.
|
||||
- `--trace-deprecation` does the same thing, but only for deprecation warnings.
|
||||
- `--pending-deprecation` will show more types of deprecation warnings. In particular, it will show the `Buffer()` deprecation warning, even on Node.js 8.
|
||||
|
||||
You can set these flags using an environment variable:
|
||||
|
||||
```console
|
||||
$ export NODE_OPTIONS='--trace-warnings --pending-deprecation'
|
||||
$ cat example.js
|
||||
'use strict';
|
||||
const foo = new Buffer('foo');
|
||||
$ node example.js
|
||||
(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead.
|
||||
at showFlaggedDeprecation (buffer.js:127:13)
|
||||
at new Buffer (buffer.js:148:3)
|
||||
at Object.<anonymous> (/path/to/example.js:2:13)
|
||||
[... more stack trace lines ...]
|
||||
```
|
||||
|
||||
### Finding problematic bits of code using linters
|
||||
|
||||
Eslint rules [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
||||
or
|
||||
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
||||
also find calls to deprecated `Buffer()` API. Those rules are included in some pre-sets.
|
||||
|
||||
There is a drawback, though, that it doesn't always
|
||||
[work correctly](https://github.com/chalker/safer-buffer#why-not-safe-buffer) when `Buffer` is
|
||||
overriden e.g. with a polyfill, so recommended is a combination of this and some other method
|
||||
described above.
|
||||
|
||||
<a id="variant-1"></a>
|
||||
## Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x.
|
||||
|
||||
This is the recommended solution nowadays that would imply only minimal overhead.
|
||||
|
||||
The Node.js 5.x release line has been unsupported since July 2016, and the Node.js 4.x release line reaches its End of Life in April 2018 (→ [Schedule](https://github.com/nodejs/Release#release-schedule)). This means that these versions of Node.js will *not* receive any updates, even in case of security issues, so using these release lines should be avoided, if at all possible.
|
||||
|
||||
What you would do in this case is to convert all `new Buffer()` or `Buffer()` calls to use `Buffer.alloc()` or `Buffer.from()`, in the following way:
|
||||
|
||||
- For `new Buffer(number)`, replace it with `Buffer.alloc(number)`.
|
||||
- For `new Buffer(string)` (or `new Buffer(string, encoding)`), replace it with `Buffer.from(string)` (or `Buffer.from(string, encoding)`).
|
||||
- For all other combinations of arguments (these are much rarer), also replace `new Buffer(...arguments)` with `Buffer.from(...arguments)`.
|
||||
|
||||
Note that `Buffer.alloc()` is also _faster_ on the current Node.js versions than
|
||||
`new Buffer(size).fill(0)`, which is what you would otherwise need to ensure zero-filling.
|
||||
|
||||
Enabling eslint rule [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
||||
or
|
||||
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
||||
is recommended to avoid accidential unsafe Buffer API usage.
|
||||
|
||||
There is also a [JSCodeshift codemod](https://github.com/joyeecheung/node-dep-codemod#dep005)
|
||||
for automatically migrating Buffer constructors to `Buffer.alloc()` or `Buffer.from()`.
|
||||
Note that it currently only works with cases where the arguments are literals or where the
|
||||
constructor is invoked with two arguments.
|
||||
|
||||
_If you currently support those older Node.js versions and dropping them would be a semver-major change
|
||||
for you, or if you support older branches of your packages, consider using [Variant 2](#variant-2)
|
||||
or [Variant 3](#variant-3) on older branches, so people using those older branches will also receive
|
||||
the fix. That way, you will eradicate potential issues caused by unguarded Buffer API usage and
|
||||
your users will not observe a runtime deprecation warning when running your code on Node.js 10._
|
||||
|
||||
<a id="variant-2"></a>
|
||||
## Variant 2: Use a polyfill
|
||||
|
||||
Utilize [safer-buffer](https://www.npmjs.com/package/safer-buffer) as a polyfill to support older
|
||||
Node.js versions.
|
||||
|
||||
You would take exacly the same steps as in [Variant 1](#variant-1), but with a polyfill
|
||||
`const Buffer = require('safer-buffer').Buffer` in all files where you use the new `Buffer` api.
|
||||
|
||||
Make sure that you do not use old `new Buffer` API — in any files where the line above is added,
|
||||
using old `new Buffer()` API will _throw_. It will be easy to notice that in CI, though.
|
||||
|
||||
Alternatively, you could use [buffer-from](https://www.npmjs.com/package/buffer-from) and/or
|
||||
[buffer-alloc](https://www.npmjs.com/package/buffer-alloc) [ponyfills](https://ponyfill.com/) —
|
||||
those are great, the only downsides being 4 deps in the tree and slightly more code changes to
|
||||
migrate off them (as you would be using e.g. `Buffer.from` under a different name). If you need only
|
||||
`Buffer.from` polyfilled — `buffer-from` alone which comes with no extra dependencies.
|
||||
|
||||
_Alternatively, you could use [safe-buffer](https://www.npmjs.com/package/safe-buffer) — it also
|
||||
provides a polyfill, but takes a different approach which has
|
||||
[it's drawbacks](https://github.com/chalker/safer-buffer#why-not-safe-buffer). It will allow you
|
||||
to also use the older `new Buffer()` API in your code, though — but that's arguably a benefit, as
|
||||
it is problematic, can cause issues in your code, and will start emitting runtime deprecation
|
||||
warnings starting with Node.js 10._
|
||||
|
||||
Note that in either case, it is important that you also remove all calls to the old Buffer
|
||||
API manually — just throwing in `safe-buffer` doesn't fix the problem by itself, it just provides
|
||||
a polyfill for the new API. I have seen people doing that mistake.
|
||||
|
||||
Enabling eslint rule [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
||||
or
|
||||
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
||||
is recommended.
|
||||
|
||||
_Don't forget to drop the polyfill usage once you drop support for Node.js < 4.5.0._
|
||||
|
||||
<a id="variant-3"></a>
|
||||
## Variant 3 — manual detection, with safeguards
|
||||
|
||||
This is useful if you create Buffer instances in only a few places (e.g. one), or you have your own
|
||||
wrapper around them.
|
||||
|
||||
### Buffer(0)
|
||||
|
||||
This special case for creating empty buffers can be safely replaced with `Buffer.concat([])`, which
|
||||
returns the same result all the way down to Node.js 0.8.x.
|
||||
|
||||
### Buffer(notNumber)
|
||||
|
||||
Before:
|
||||
|
||||
```js
|
||||
var buf = new Buffer(notNumber, encoding);
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```js
|
||||
var buf;
|
||||
if (Buffer.from && Buffer.from !== Uint8Array.from) {
|
||||
buf = Buffer.from(notNumber, encoding);
|
||||
} else {
|
||||
if (typeof notNumber === 'number')
|
||||
throw new Error('The "size" argument must be of type number.');
|
||||
buf = new Buffer(notNumber, encoding);
|
||||
}
|
||||
```
|
||||
|
||||
`encoding` is optional.
|
||||
|
||||
Note that the `typeof notNumber` before `new Buffer` is required (for cases when `notNumber` argument is not
|
||||
hard-coded) and _is not caused by the deprecation of Buffer constructor_ — it's exactly _why_ the
|
||||
Buffer constructor is deprecated. Ecosystem packages lacking this type-check caused numereous
|
||||
security issues — situations when unsanitized user input could end up in the `Buffer(arg)` create
|
||||
problems ranging from DoS to leaking sensitive information to the attacker from the process memory.
|
||||
|
||||
When `notNumber` argument is hardcoded (e.g. literal `"abc"` or `[0,1,2]`), the `typeof` check can
|
||||
be omitted.
|
||||
|
||||
Also note that using TypeScript does not fix this problem for you — when libs written in
|
||||
`TypeScript` are used from JS, or when user input ends up there — it behaves exactly as pure JS, as
|
||||
all type checks are translation-time only and are not present in the actual JS code which TS
|
||||
compiles to.
|
||||
|
||||
### Buffer(number)
|
||||
|
||||
For Node.js 0.10.x (and below) support:
|
||||
|
||||
```js
|
||||
var buf;
|
||||
if (Buffer.alloc) {
|
||||
buf = Buffer.alloc(number);
|
||||
} else {
|
||||
buf = new Buffer(number);
|
||||
buf.fill(0);
|
||||
}
|
||||
```
|
||||
|
||||
Otherwise (Node.js ≥ 0.12.x):
|
||||
|
||||
```js
|
||||
const buf = Buffer.alloc ? Buffer.alloc(number) : new Buffer(number).fill(0);
|
||||
```
|
||||
|
||||
## Regarding Buffer.allocUnsafe
|
||||
|
||||
Be extra cautious when using `Buffer.allocUnsafe`:
|
||||
* Don't use it if you don't have a good reason to
|
||||
* e.g. you probably won't ever see a performance difference for small buffers, in fact, those
|
||||
might be even faster with `Buffer.alloc()`,
|
||||
* if your code is not in the hot code path — you also probably won't notice a difference,
|
||||
* keep in mind that zero-filling minimizes the potential risks.
|
||||
* If you use it, make sure that you never return the buffer in a partially-filled state,
|
||||
* if you are writing to it sequentially — always truncate it to the actuall written length
|
||||
|
||||
Errors in handling buffers allocated with `Buffer.allocUnsafe` could result in various issues,
|
||||
ranged from undefined behaviour of your code to sensitive data (user input, passwords, certs)
|
||||
leaking to the remote attacker.
|
||||
|
||||
_Note that the same applies to `new Buffer` usage without zero-filling, depending on the Node.js
|
||||
version (and lacking type checks also adds DoS to the list of potential problems)._
|
||||
|
||||
<a id="faq"></a>
|
||||
## FAQ
|
||||
|
||||
<a id="design-flaws"></a>
|
||||
### What is wrong with the `Buffer` constructor?
|
||||
|
||||
The `Buffer` constructor could be used to create a buffer in many different ways:
|
||||
|
||||
- `new Buffer(42)` creates a `Buffer` of 42 bytes. Before Node.js 8, this buffer contained
|
||||
*arbitrary memory* for performance reasons, which could include anything ranging from
|
||||
program source code to passwords and encryption keys.
|
||||
- `new Buffer('abc')` creates a `Buffer` that contains the UTF-8-encoded version of
|
||||
the string `'abc'`. A second argument could specify another encoding: For example,
|
||||
`new Buffer(string, 'base64')` could be used to convert a Base64 string into the original
|
||||
sequence of bytes that it represents.
|
||||
- There are several other combinations of arguments.
|
||||
|
||||
This meant that, in code like `var buffer = new Buffer(foo);`, *it is not possible to tell
|
||||
what exactly the contents of the generated buffer are* without knowing the type of `foo`.
|
||||
|
||||
Sometimes, the value of `foo` comes from an external source. For example, this function
|
||||
could be exposed as a service on a web server, converting a UTF-8 string into its Base64 form:
|
||||
|
||||
```
|
||||
function stringToBase64(req, res) {
|
||||
// The request body should have the format of `{ string: 'foobar' }`
|
||||
const rawBytes = new Buffer(req.body.string)
|
||||
const encoded = rawBytes.toString('base64')
|
||||
res.end({ encoded: encoded })
|
||||
}
|
||||
```
|
||||
|
||||
Note that this code does *not* validate the type of `req.body.string`:
|
||||
|
||||
- `req.body.string` is expected to be a string. If this is the case, all goes well.
|
||||
- `req.body.string` is controlled by the client that sends the request.
|
||||
- If `req.body.string` is the *number* `50`, the `rawBytes` would be 50 bytes:
|
||||
- Before Node.js 8, the content would be uninitialized
|
||||
- After Node.js 8, the content would be `50` bytes with the value `0`
|
||||
|
||||
Because of the missing type check, an attacker could intentionally send a number
|
||||
as part of the request. Using this, they can either:
|
||||
|
||||
- Read uninitialized memory. This **will** leak passwords, encryption keys and other
|
||||
kinds of sensitive information. (Information leak)
|
||||
- Force the program to allocate a large amount of memory. For example, when specifying
|
||||
`500000000` as the input value, each request will allocate 500MB of memory.
|
||||
This can be used to either exhaust the memory available of a program completely
|
||||
and make it crash, or slow it down significantly. (Denial of Service)
|
||||
|
||||
Both of these scenarios are considered serious security issues in a real-world
|
||||
web server context.
|
||||
|
||||
when using `Buffer.from(req.body.string)` instead, passing a number will always
|
||||
throw an exception instead, giving a controlled behaviour that can always be
|
||||
handled by the program.
|
||||
|
||||
<a id="ecosystem-usage"></a>
|
||||
### The `Buffer()` constructor has been deprecated for a while. Is this really an issue?
|
||||
|
||||
Surveys of code in the `npm` ecosystem have shown that the `Buffer()` constructor is still
|
||||
widely used. This includes new code, and overall usage of such code has actually been
|
||||
*increasing*.
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
declare const MAX_ARRAY_LENGTH: 4294967295;
|
||||
|
||||
export = MAX_ARRAY_LENGTH;
|
||||
Reference in New Issue
Block a user