Skip to content

Commit 93edf90

Browse files
addaleaxMylesBorins
authored andcommitted
doc: add documentation for brotli support
Backport-PR-URL: #27681 PR-URL: #24938 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Jan Krems <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Ali Ijaz Sheikh <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]>
1 parent c670358 commit 93edf90

File tree

3 files changed

+211
-13
lines changed

3 files changed

+211
-13
lines changed

doc/api/errors.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -624,16 +624,16 @@ An attempt was made to register something that is not a function as an
624624
The type of an asynchronous resource was invalid. Note that users are also able
625625
to define their own types if using the public embedder API.
626626

627+
<a id="ERR_BROTLI_COMPRESSION_FAILED"></a>
628+
### ERR_BROTLI_COMPRESSION_FAILED
629+
630+
Data passed to a Brotli stream was not successfully compressed.
631+
627632
<a id="ERR_BROTLI_INVALID_PARAM"></a>
628633
### ERR_BROTLI_INVALID_PARAM
629634

630635
An invalid parameter key was passed during construction of a Brotli stream.
631636

632-
<a id="ERR_BROTLI_COMPRESSION_FAILED">
633-
### ERR_BROTLI_COMPRESSION_FAILED
634-
635-
Data passed to a Brotli stream was not successfully compressed.
636-
637637
<a id="ERR_BUFFER_OUT_OF_BOUNDS"></a>
638638
### ERR_BUFFER_OUT_OF_BOUNDS
639639

doc/api/zlib.md

+204-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
> Stability: 2 - Stable
66
77
The `zlib` module provides compression functionality implemented using Gzip and
8-
Deflate/Inflate. It can be accessed using:
8+
Deflate/Inflate, as well as Brotli. It can be accessed using:
99

1010
```js
1111
const zlib = require('zlib');
@@ -54,8 +54,8 @@ and/or unrecoverable and catastrophic memory fragmentation.
5454

5555
## Compressing HTTP requests and responses
5656

57-
The `zlib` module can be used to implement support for the `gzip` and `deflate`
58-
content-encoding mechanisms defined by
57+
The `zlib` module can be used to implement support for the `gzip`, `deflate`
58+
and `br` content-encoding mechanisms defined by
5959
[HTTP](https://tools.ietf.org/html/rfc7230#section-4.2).
6060

6161
The HTTP [`Accept-Encoding`][] header is used within an http request to identify
@@ -76,12 +76,15 @@ const fs = require('fs');
7676
const request = http.get({ host: 'example.com',
7777
path: '/',
7878
port: 80,
79-
headers: { 'Accept-Encoding': 'gzip,deflate' } });
79+
headers: { 'Accept-Encoding': 'br,gzip,deflate' } });
8080
request.on('response', (response) => {
8181
const output = fs.createWriteStream('example.com_index.html');
8282

8383
switch (response.headers['content-encoding']) {
84-
// or, just use zlib.createUnzip() to handle both cases
84+
case 'br':
85+
response.pipe(zlib.createBrotliDecompress()).pipe(output);
86+
break;
87+
// Or, just use zlib.createUnzip() to handle both of the following cases:
8588
case 'gzip':
8689
response.pipe(zlib.createGunzip()).pipe(output);
8790
break;
@@ -117,6 +120,9 @@ http.createServer((request, response) => {
117120
} else if (/\bgzip\b/.test(acceptEncoding)) {
118121
response.writeHead(200, { 'Content-Encoding': 'gzip' });
119122
raw.pipe(zlib.createGzip()).pipe(response);
123+
} else if (/\bbr\b/.test(acceptEncoding)) {
124+
response.writeHead(200, { 'Content-Encoding': 'br' });
125+
raw.pipe(zlib.createBrotliCompress()).pipe(response);
120126
} else {
121127
response.writeHead(200, {});
122128
raw.pipe(response);
@@ -136,6 +142,7 @@ const buffer = Buffer.from('eJzT0yMA', 'base64');
136142

137143
zlib.unzip(
138144
buffer,
145+
// For Brotli, the equivalent is zlib.constants.BROTLI_OPERATION_FLUSH.
139146
{ finishFlush: zlib.constants.Z_SYNC_FLUSH },
140147
(err, buffer) => {
141148
if (!err) {
@@ -156,6 +163,8 @@ decompressed result is valid.
156163

157164
<!--type=misc-->
158165

166+
### For zlib-based streams
167+
159168
From `zlib/zconf.h`, modified to Node.js's usage:
160169

161170
The memory requirements for deflate are (in bytes):
@@ -194,6 +203,16 @@ fewer calls to `zlib` because it will be able to process more data on
194203
each `write` operation. So, this is another factor that affects the
195204
speed, at the cost of memory usage.
196205

206+
### For Brotli-based streams
207+
208+
There are equivalents to the zlib options for Brotli-based streams, although
209+
these options have different ranges than the zlib ones:
210+
211+
- zlib’s `level` option matches Brotli’s `BROTLI_PARAM_QUALITY` option.
212+
- zlib’s `windowBits` option matches Brotli’s `BROTLI_PARAM_LGWIN` option.
213+
214+
See [below][Brotli parameters] for more details on Brotli-specific options.
215+
197216
## Flushing
198217

199218
Calling [`.flush()`][] on a compression stream will make `zlib` return as much
@@ -231,6 +250,8 @@ added: v0.5.8
231250

232251
<!--type=misc-->
233252

253+
### zlib constants
254+
234255
All of the constants defined in `zlib.h` are also defined on
235256
`require('zlib').constants`. In the normal course of operations, it will not be
236257
necessary to use these constants. They are documented so that their presence is
@@ -281,6 +302,77 @@ Compression strategy.
281302
* `zlib.constants.Z_FIXED`
282303
* `zlib.constants.Z_DEFAULT_STRATEGY`
283304

305+
### Brotli constants
306+
<!-- YAML
307+
added: REPLACEME
308+
-->
309+
310+
There are several options and other constants available for Brotli-based
311+
streams:
312+
313+
#### Flush operations
314+
315+
The following values are valid flush operations for Brotli-based streams:
316+
317+
* `zlib.constants.BROTLI_OPERATION_PROCESS` (default for all operations)
318+
* `zlib.constants.BROTLI_OPERATION_FLUSH` (default when calling `.flush()`)
319+
* `zlib.constants.BROTLI_OPERATION_FINISH` (default for the last chunk)
320+
* `zlib.constants.BROTLI_OPERATION_EMIT_METADATA`
321+
* This particular operation may be hard to use in a Node.js context,
322+
as the streaming layer makes it hard to know which data will end up
323+
in this frame. Also, there is currently no way to consume this data through
324+
the Node.js API.
325+
326+
#### Compressor options
327+
328+
There are several options that can be set on Brotli encoders, affecting
329+
compression efficiency and speed. Both the keys and the values can be accessed
330+
as properties of the `zlib.constants` object.
331+
332+
The most important options are:
333+
334+
* `BROTLI_PARAM_MODE`
335+
* `BROTLI_MODE_GENERIC` (default)
336+
* `BROTLI_MODE_TEXT`, adjusted for UTF-8 text
337+
* `BROTLI_MODE_FONT`, adjusted for WOFF 2.0 fonts
338+
* `BROTLI_PARAM_QUALITY`
339+
* Ranges from `BROTLI_MIN_QUALITY` to `BROTLI_MAX_QUALITY`,
340+
with a default of `BROTLI_DEFAULT_QUALITY`.
341+
* `BROTLI_PARAM_SIZE_HINT`
342+
* Integer value representing the expected input size;
343+
defaults to `0` for an unknown input size.
344+
345+
The following flags can be set for advanced control over the compression
346+
algorithm and memory usage tuning:
347+
348+
* `BROTLI_PARAM_LGWIN`
349+
* Ranges from `BROTLI_MIN_WINDOW_BITS` to `BROTLI_MAX_WINDOW_BITS`,
350+
with a default of `BROTLI_DEFAULT_WINDOW`, or up to
351+
`BROTLI_LARGE_MAX_WINDOW_BITS` if the `BROTLI_PARAM_LARGE_WINDOW` flag
352+
is set.
353+
* `BROTLI_PARAM_LGBLOCK`
354+
* Ranges from `BROTLI_MIN_INPUT_BLOCK_BITS` to `BROTLI_MAX_INPUT_BLOCK_BITS`.
355+
* `BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING`
356+
* Boolean flag that decreases compression ratio in favour of
357+
decompression speed.
358+
* `BROTLI_PARAM_LARGE_WINDOW`
359+
* Boolean flag enabling “Large Window Brotli” mode (not compatible with the
360+
Brotli format as standardized in [RFC 7932][]).
361+
* `BROTLI_PARAM_NPOSTFIX`
362+
* Ranges from `0` to `BROTLI_MAX_NPOSTFIX`.
363+
* `BROTLI_PARAM_NDIRECT`
364+
* Ranges from `0` to `15 << NPOSTFIX` in steps of `1 << NPOSTFIX`.
365+
366+
#### Decompressor options
367+
368+
These advanced options are available for controlling decompression:
369+
370+
* `BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION`
371+
* Boolean flag that affects internal memory allocation patterns.
372+
* `BROTLI_DECODER_PARAM_LARGE_WINDOW`
373+
* Boolean flag enabling “Large Window Brotli” mode (not compatible with the
374+
Brotli format as standardized in [RFC 7932][]).
375+
284376
## Class: Options
285377
<!-- YAML
286378
added: v0.11.1
@@ -298,7 +390,7 @@ changes:
298390

299391
<!--type=misc-->
300392

301-
Each class takes an `options` object. All options are optional.
393+
Each zlib-based class takes an `options` object. All options are optional.
302394

303395
Note that some options are only relevant when compressing, and are
304396
ignored by the decompression classes.
@@ -317,6 +409,47 @@ ignored by the decompression classes.
317409
See the description of `deflateInit2` and `inflateInit2` at
318410
<https://zlib.net/manual.html#Advanced> for more information on these.
319411

412+
## Class: BrotliOptions
413+
<!-- YAML
414+
added: REPLACEME
415+
-->
416+
417+
<!--type=misc-->
418+
419+
Each Brotli-based class takes an `options` object. All options are optional.
420+
421+
* `flush` {integer} **Default:** `zlib.constants.BROTLI_OPERATION_PROCESS`
422+
* `finishFlush` {integer} **Default:** `zlib.constants.BROTLI_OPERATION_FINISH`
423+
* `chunkSize` {integer} **Default:** `16 * 1024`
424+
* `params` {Object} Key-value object containing indexed [Brotli parameters][].
425+
426+
For example:
427+
428+
```js
429+
const stream = zlib.createBrotliCompress({
430+
chunkSize: 32 * 1024,
431+
params: {
432+
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,
433+
[zlib.constants.BROTLI_PARAM_QUALITY]: 4,
434+
[zlib.constants.BROTLI_PARAM_SIZE_HINT]: fs.statSync(inputFile).size
435+
}
436+
});
437+
```
438+
439+
## Class: zlib.BrotliCompress
440+
<!-- YAML
441+
added: REPLACEME
442+
-->
443+
444+
Compress data using the Brotli algorithm.
445+
446+
## Class: zlib.BrotliDecompress
447+
<!-- YAML
448+
added: REPLACEME
449+
-->
450+
451+
Decompress data using the Brotli algorithm.
452+
320453
## Class: zlib.Deflate
321454
<!-- YAML
322455
added: v0.5.8
@@ -389,9 +522,13 @@ added: v0.5.8
389522
Decompress either a Gzip- or Deflate-compressed stream by auto-detecting
390523
the header.
391524

392-
## Class: zlib.Zlib
525+
## Class: zlib.ZlibBase
393526
<!-- YAML
394527
added: v0.5.8
528+
changes:
529+
- version: REPLACEME
530+
pr-url: https://github.com/nodejs/node/pull/24939
531+
description: This class was renamed from `Zlib` to `ZlibBase`.
395532
-->
396533

397534
Not exported by the `zlib` module. It is documented here because it is the base
@@ -440,7 +577,8 @@ Close the underlying handle.
440577
added: v0.5.8
441578
-->
442579

443-
* `kind` **Default:** `zlib.constants.Z_FULL_FLUSH`
580+
* `kind` **Default:** `zlib.constants.Z_FULL_FLUSH` for zlib-based streams,
581+
`zlib.constants.BROTLI_OPERATION_FLUSH` for Brotli-based streams.
444582
* `callback` {Function}
445583

446584
Flush pending data. Don't call this frivolously, premature flushes negatively
@@ -460,6 +598,8 @@ added: v0.11.4
460598
* `strategy` {integer}
461599
* `callback` {Function}
462600

601+
This function is only available for zlib-based streams, i.e. not Brotli.
602+
463603
Dynamically update the compression level and compression strategy.
464604
Only applicable to deflate algorithm.
465605

@@ -478,6 +618,24 @@ added: v7.0.0
478618

479619
Provides an object enumerating Zlib-related constants.
480620

621+
## zlib.createBrotliCompress([options])
622+
<!-- YAML
623+
added: REPLACEME
624+
-->
625+
626+
* `options` {brotli options}
627+
628+
Creates and returns a new [`BrotliCompress`][] object.
629+
630+
## zlib.createBrotliDecompress([options])
631+
<!-- YAML
632+
added: REPLACEME
633+
-->
634+
635+
* `options` {brotli options}
636+
637+
Creates and returns a new [`BrotliDecompress`][] object.
638+
481639
## zlib.createDeflate([options])
482640
<!-- YAML
483641
added: v0.5.8
@@ -560,6 +718,40 @@ with `callback(error, result)`.
560718
Every method has a `*Sync` counterpart, which accept the same arguments, but
561719
without a callback.
562720

721+
### zlib.brotliCompress(buffer[, options], callback)
722+
<!-- YAML
723+
added: REPLACEME
724+
-->
725+
* `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string}
726+
* `options` {brotli options}
727+
* `callback` {Function}
728+
729+
### zlib.brotliCompressSync(buffer[, options])
730+
<!-- YAML
731+
added: REPLACEME
732+
-->
733+
* `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string}
734+
* `options` {brotli options}
735+
736+
Compress a chunk of data with [`BrotliCompress`][].
737+
738+
### zlib.brotliDecompress(buffer[, options], callback)
739+
<!-- YAML
740+
added: REPLACEME
741+
-->
742+
* `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string}
743+
* `options` {brotli options}
744+
* `callback` {Function}
745+
746+
### zlib.brotliDecompressSync(buffer[, options])
747+
<!-- YAML
748+
added: REPLACEME
749+
-->
750+
* `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string}
751+
* `options` {brotli options}
752+
753+
Decompress a chunk of data with [`BrotliDecompress`][].
754+
563755
### zlib.deflate(buffer[, options], callback)
564756
<!-- YAML
565757
added: v0.6.0
@@ -832,6 +1024,8 @@ Decompress a chunk of data with [`Unzip`][].
8321024
[`.flush()`]: #zlib_zlib_flush_kind_callback
8331025
[`Accept-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
8341026
[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
1027+
[`BrotliCompress`]: #zlib_class_zlib_brotlicompress
1028+
[`BrotliDecompress`]: #zlib_class_zlib_brotlidecompress
8351029
[`Buffer`]: buffer.html#buffer_class_buffer
8361030
[`Content-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11
8371031
[`DataView`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
@@ -845,6 +1039,8 @@ Decompress a chunk of data with [`Unzip`][].
8451039
[`Unzip`]: #zlib_class_zlib_unzip
8461040
[`stream.Transform`]: stream.html#stream_class_stream_transform
8471041
[`zlib.bytesWritten`]: #zlib_zlib_byteswritten
1042+
[Brotli parameters]: #zlib_brotli_constants
8481043
[Memory Usage Tuning]: #zlib_memory_usage_tuning
1044+
[RFC 7932]: https://www.rfc-editor.org/rfc/rfc7932.txt
8491045
[pool size]: cli.html#cli_uv_threadpool_size_size
8501046
[zlib documentation]: https://zlib.net/manual.html#Constants

tools/doc/type-parser.js

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const customTypesMap = {
3838
'AsyncHook': 'async_hooks.html#async_hooks_async_hooks_createhook_callbacks',
3939
'AsyncResource': 'async_hooks.html#async_hooks_class_asyncresource',
4040

41+
'brotli options': 'zlib.html#zlib_class_brotlioptions',
42+
4143
'Buffer': 'buffer.html#buffer_class_buffer',
4244

4345
'ChildProcess': 'child_process.html#child_process_class_childprocess',

0 commit comments

Comments
 (0)