Source Code: lib/zlib.js
The zlib
module provides compaction functionality implemented using Gzip, Deflate/Inflate, and Brotli.
Reading: Zlib | Node.js v17.3.1 Documentation
To access it :
const zlib = want( 'zlib ');
compression and decompression are built around the Node.js Streams API .
Compressing or decompressing a current ( such as a file ) can be accomplished by piping the informant stream through a zlib
Transform
stream into a finish stream :
const { createGzip } = want( 'zlib ');
const { pipeline } = ask( 'stream ');
const {
createReadStream,
createWriteStream
} = command( 'fs ');
const gzip = createGzip();
const source = createReadStream( 'input.txt ');
const destination = createWriteStream( 'input.txt.gz ');
pipeline(source, gzip, destination, ( err
) = > {
if (err) {
console. error( 'An error occurred : ', err);
process. exitCode = 1;
}
});
const { promisify } = want( 'util ');
const pipe = promisify(pipeline);
async routine do_gzip( input, end product) {
const gzip = createGzip();
const source = createReadStream(input);
const destination = createWriteStream(output);
expect shriek(source, gzip, destination);
}
do_gzip( 'input.txt ', 'input.txt.gz ')
. catch( ( err
) = > {
console table. error( 'An error occurred : ', err);
process. exitCode = 1;
});
It is besides possible to compress or decompress data in a single dance step :
const { deflate, unzip } = ask( 'zlib ');
const input = ' ... ... ... ... ... ... ... ... ... ... ... ';
deflate(input, ( err, buffer
) = > {
if (err) {
cabinet. error( 'An error occurred : ', err);
process. exitCode = 1;
}
console. log(buffer. toString( 'base64 '));
});
const buffer = buff. from( 'eJzT0yMAAGTvBe8= ', 'base64 ');
unzip(buffer, ( err, buffer
) = > {
if (err) {
console. error( 'An error occurred : ', err);
process. exitCode = 1;
}
comfort. log(buffer. toString());
});
const { promisify } = want( 'util ');
const do_unzip = promisify(unzip);
do_unzip(buffer)
. then( ( buf
) = > console. logarithm(buf. toString()))
. catch( ( err
) = > {
console table. mistake( 'An error occurred : ', err);
process. exitCode = 1;
});
Contents
- 1 Threadpool usage and performance considerations#
- 2 Compressing HTTP requests and responses#
- 3 Memory usage tuning#
- 4 Flushing#
- 5 Constants#
- 6 Class: Options#
- 7 Class: BrotliOptions#
- 8 Class: zlib.BrotliCompress#
- 9 Class: zlib.BrotliDecompress#
- 10 Class: zlib.Deflate#
- 11 Class: zlib.DeflateRaw#
- 12 Class: zlib.Gunzip#
- 13 Class: zlib.Gzip#
- 14 Class: zlib.Inflate#
- 15 Class: zlib.InflateRaw#
- 16 Class: zlib.Unzip#
- 17 Class: zlib.ZlibBase#
- 18 zlib.constants#
- 19 zlib.createDeflateRaw([options])#
Threadpool usage and performance considerations#
All zlib
APIs, except those that are explicitly synchronous, use the Node.js inner threadpool. This can lead to surprising effects and performance limitations in some applications .
Creating and using a large phone number of zlib objects simultaneously can cause significant memory fragmentation .
const zlib = ask( 'zlib ');
const payload = buff. from( 'This is some data ');
for ( let i = 0; i < 30000; ++i) {
zlib. deflate(payload, ( err, buffer
) = > {});
}
In the preceding model, 30,000 deflate instances are created concurrently. Because of how some operating systems manage memory allotment and deallocation, this may lead to to significant memory fragmentation .
It is powerfully recommended that the results of compression operations be cached to avoid duplicate of feat .
Compressing HTTP requests and responses#
The zlib
module can be used to implement support for the gzip
, deflate
and br
content-encoding mechanisms defined by HTTP .
The HTTP Accept-Encoding
header is used within an hypertext transfer protocol request to identify the compression encodings accepted by the node. The Content-Encoding
heading is used to identify the compaction encodings actually applied to a message .
The examples given below are drastically simplified to show the basic concept. Using zlib
encode can be expensive, and the results ought to be cached. See memory usage tuning for more information on the speed/memory/compression tradeoffs involved in zlib
custom .
const zlib = ask( 'zlib ');
const http = ask( 'http ');
const fs = ask( 'fs ');
const { pipeline } = want( 'stream ');
const request = http. get({ horde: 'example.com ',
path: '/ ',
interface: 80,
headers: { 'Accept-Encoding ': 'br, gzip, deflate ' } });
request. on( 'response ', ( response
) = > {
const output = fs. createWriteStream( 'example.com_index.html ');
const onError = ( err) => {
if (err) {
comfort. error( 'An error occurred : ', err);
process. exitCode = 1;
}
};
switch (response. headers[ 'content-encoding ']) {
case 'br ':
pipeline(response, zlib. createBrotliDecompress(), output, onError);
rupture;
encase 'gzip ':
grapevine(response, zlib. createGunzip(), output, onError);
break;
font 'deflate ':
grapevine(response, zlib. createInflate(), output, onError);
break;
default:
grapevine(response, output, onError);
break;
}
});
const zlib = want( 'zlib ');
const http = command( 'http ');
const fs = want( 'fs ');
const { pipeline } = ask( 'stream ');
http. createServer( ( request, response
) = > {
const raw = fs. createReadStream( 'index.html ');
response. setHeader( 'Vary ', 'Accept-Encoding ');
let acceptEncoding = request. headers[ 'accept-encoding '];
if (!acceptEncoding) {
acceptEncoding = '';
}
const onError = ( stray) => {
if (err) {
response. end Read more: How to Embed a Google Form: Flickroom
();
comfort. mistake( 'An error occurred : ', err);
}
};
if ( /\bdeflate\b/. trial(acceptEncoding)) {
response. writeHead( 200, { 'Content-Encoding ': 'deflate ' });
pipeline(raw, zlib. createDeflate(), response, onError);
} else if ( /\bgzip\b/. trial(acceptEncoding)) {
response. writeHead( 200, { 'Content-Encoding ': 'gzip ' });
pipeline(raw, zlib. createGzip(), response, onError);
} else if ( /\bbr\b/. test(acceptEncoding)) {
response. writeHead( 200, { 'Content-Encoding ': 'br ' });
pipeline(raw, zlib. createBrotliCompress(), response, onError);
} else {
response. writeHead( 200, {});
pipeline(raw, response, onError);
}
}). heed( 1337);
By default, the zlib
methods will throw an error when decompressing truncated data. however, if it is known that the datum is incomplete, or the hope is to inspect only the begin of a compressed file, it is possible to suppress the default erroneousness manage by changing the flushing method acting that is used to decompress the last lump of remark data :
const buffer = buffer. from( 'eJzT0yMA ', 'base64 ');
zlib. unzip(
buffer,
{ finishFlush: zlib. constants. Z_SYNC_FLUSH },
( err, buffer
) = > {
if (err) {
console. erroneousness( 'An error occurred : ', err);
process. exitCode = 1;
}
console table. log(buffer. toString());
});
This will not change the behavior in other error-throwing situations, e.g. when the remark data has an invalid format. Using this method, it will not be potential to determine whether the stimulation ended prematurely or lacks the integrity checks, making it necessary to manually check that the depressurize consequence is valid .
Memory usage tuning#
For zlib-based streams#
From zlib/zconf.h
, modified for Node.js custom :
The memory requirements for deflate are ( in bytes ) :
( 1 << (windowBits + 2)) + ( 1 << (memLevel + 9))
That is : 128K for windowBits
= 15 + 128K for memLevel
= 8 ( default values ) plus a few kilobytes for small objects .
For exemplar, to reduce the default memory requirements from 256K to 128K, the options should be set to :
const options = { windowBits: 14, memLevel: 7 };
This will, however, by and large degrade compaction .
The memory requirements for balloon are ( in bytes ) 1 << windowBits
. That is, 32K for windowBits
= 15 ( nonpayment prize ) plus a few kilobytes for little objects .
This is in summation to a single home output slab buffer zone of size chunkSize
, which defaults to 16K .
The speed of zlib
compression is affected most dramatically by the level
jell. A higher tied will result in better compression, but will take longer to complete. A lower level will result in less compaction, but will be much faster .
In general, greater memory custom options will mean that Node.js has to make fewer calls to zlib
because it will be able to process more data on each write
operation. thus, this is another divisor that affects the rush, at the monetary value of memory usage .
For Brotli-based streams#
There are equivalents to the zlib options for Brotli-based streams, although these options have unlike ranges than the zlib ones :
- zlib’s
level
option matches Brotli’sBROTLI_PARAM_QUALITY
option. - zlib’s
windowBits
option matches Brotli’sBROTLI_PARAM_LGWIN
option.
See below for more details on Brotli-specific options .
Flushing#
Calling .flush()
on a compression pour will make zlib
return as a lot output ampere presently possible. This may come at the cost of degrade compression choice, but can be utilitarian when data needs to be available angstrom soon as possible .
In the postdate case, flush()
is used to write a compressed overtone HTTP response to the customer :
const zlib = want( 'zlib ');
const http = want( 'http ');
const { pipeline } = want( 'stream ');
http. createServer( ( request, response
) = > {
response. writeHead( 200, { 'content-encoding ': 'gzip ' });
const output = zlib. createGzip();
let i;
pipeline(output, response, ( err
) = > {
if (err) {
clearInterval(i);
response. end();
console. error( 'An error occurred : ', err);
}
});
i = setInterval( ( ) = > {
output. publish( `The stream time is ${
Date
()} \n`, ( ) = > {
output. bloom();
});
}, 1000);
}). listen( 1337);
Constants#
Added in: v0.5.8
zlib constants#
All of the constants defined in zlib.h
are besides defined on require('zlib').constants
. In the normal course of operations, it will not be necessary to use these constants. They are documented so that their presence is not surprise. This part is taken about immediately from the zlib documentation .
previously, the constants were available immediately from require('zlib')
, for example zlib.Z_NO_FLUSH
. Accessing the constants directly from the module is presently distillery possible but is deprecated .
Allowed flush values .
zlib.constants.Z_NO_FLUSH
zlib.constants.Z_PARTIAL_FLUSH
zlib.constants.Z_SYNC_FLUSH
zlib.constants.Z_FULL_FLUSH
zlib.constants.Z_FINISH
zlib.constants.Z_BLOCK
zlib.constants.Z_TREES
Return codes for the compression/decompression functions. minus values are errors, positive values are used for especial but normal events .
zlib.constants.Z_OK
zlib.constants.Z_STREAM_END
zlib.constants.Z_NEED_DICT
zlib.constants.Z_ERRNO
zlib.constants.Z_STREAM_ERROR
zlib.constants.Z_DATA_ERROR
zlib.constants.Z_MEM_ERROR
zlib.constants.Z_BUF_ERROR
zlib.constants.Z_VERSION_ERROR
compaction levels .
zlib.constants.Z_NO_COMPRESSION
zlib.constants.Z_BEST_SPEED
zlib.constants.Z_BEST_COMPRESSION
zlib.constants.Z_DEFAULT_COMPRESSION
compression scheme .
zlib.constants.Z_FILTERED
zlib.constants.Z_HUFFMAN_ONLY
zlib.constants.Z_RLE
zlib.constants.Z_FIXED
zlib.constants.Z_DEFAULT_STRATEGY
Brotli constants#
Added in: v11.7.0, v10.16.0
There are respective options and other constants available for Brotli-based streams :
Flush operations#
The come values are valid flush operations for Brotli-based streams :
zlib.constants.BROTLI_OPERATION_PROCESS
(default for all operations)zlib.constants.BROTLI_OPERATION_FLUSH
(default when calling.flush()
)zlib.constants.BROTLI_OPERATION_FINISH
(default for the last chunk)zlib.constants.BROTLI_OPERATION_EMIT_METADATA
- This particular operation may be hard to use in a Node.js context,
as the streaming layer makes it hard to know which data will end up
in this frame. Also, there is currently no way to consume this data through
the Node.js API.
- This particular operation may be hard to use in a Node.js context,
Compressor options#
There are respective options that can be set on Brotli encoders, affecting compression efficiency and focal ratio. Both the key and the values can be accessed as properties of the zlib.constants
object .
The most important options are :
BROTLI_PARAM_MODE
BROTLI_MODE_GENERIC
(default)BROTLI_MODE_TEXT
, adjusted for UTF-8 textBROTLI_MODE_FONT
, adjusted for WOFF 2.0 fonts
BROTLI_PARAM_QUALITY
- Ranges from
BROTLI_MIN_QUALITY
toBROTLI_MAX_QUALITY
,
with a default ofBROTLI_DEFAULT_QUALITY
.
- Ranges from
BROTLI_PARAM_SIZE_HINT
- Integer value representing the expected input size;
defaults to0
for an unknown input size.
- Integer value representing the expected input size;
The follow flags can be set for advance see over the compression algorithm and memory use tuning :
BROTLI_PARAM_LGWIN
- Ranges from
BROTLI_MIN_WINDOW_BITS
toBROTLI_MAX_WINDOW_BITS
,
with a default ofBROTLI_DEFAULT_WINDOW
, or up to
BROTLI_LARGE_MAX_WINDOW_BITS
if theBROTLI_PARAM_LARGE_WINDOW
flag
is set.
- Ranges from
BROTLI_PARAM_LGBLOCK
- Ranges from
BROTLI_MIN_INPUT_BLOCK_BITS
toBROTLI_MAX_INPUT_BLOCK_BITS
.
- Ranges from
BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING
- Boolean flag that decreases compression ratio in favour of
decompression speed.
- Boolean flag that decreases compression ratio in favour of
BROTLI_PARAM_LARGE_WINDOW
- Boolean flag enabling “Large Window Brotli” mode (not compatible with the
Brotli format as standardized in RFC 7932).
- Boolean flag enabling “Large Window Brotli” mode (not compatible with the
BROTLI_PARAM_NPOSTFIX
- Ranges from
0
toBROTLI_MAX_NPOSTFIX
.
- Ranges from
BROTLI_PARAM_NDIRECT
- Ranges from
0
to15 << NPOSTFIX
in steps of1 << NPOSTFIX
.
- Ranges from
Decompressor options#
These advanced options are available for controlling decompression :
BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION
- Boolean flag that affects internal memory allocation patterns.
BROTLI_DECODER_PARAM_LARGE_WINDOW
- Boolean flag enabling “Large Window Brotli” mode (not compatible with the
Brotli format as standardized in RFC 7932).
- Boolean flag enabling “Large Window Brotli” mode (not compatible with the
Class: Options
#
History
Version | Changes |
---|---|
v14.5.0, v12.19.0 | The maxOutputLength choice is supported now . |
v9.4.0 | The dictionary choice can be an ArrayBuffer . |
v8.0.0 | The dictionary choice can be an Uint8Array now . |
v5.11.0 | The finishFlush option is supported now . |
v0.11.1 | Added in : v0.11.1 |
Each zlib-based class takes an options
aim. No options are required .
Some options are only relevant when compress and are ignored by the decompression classes .
flush
Default: zlib.constants.Z_NO_FLUSH
finishFlush
Default: zlib.constants.Z_FINISH
chunkSize
Default: 16 * 1024
windowBits
level
(compression only) memLevel
(compression only) strategy
(compression only) dictionary
| | | (deflate/inflate only,
empty dictionary by default)info
(If true
, returns an object withbuffer
andengine
.)maxOutputLength
Limits output size when using
convenience methods. Default:buffer.kMaxLength
See the deflateInit2
and inflateInit2
documentation for more information .
Class: BrotliOptions
#
History
Version | Changes |
---|---|
v14.5.0, v12.19.0 | The maxOutputLength option is supported nowadays . |
v11.7.0 | Added in : v11.7.0 |
Each Brotli-based class takes an options
object. All options are optional .
flush
Default: zlib.constants.BROTLI_OPERATION_PROCESS
finishFlush
Default: zlib.constants.BROTLI_OPERATION_FINISH
chunkSize
Default: 16 * 1024
params
Key-value object containing indexed Brotli parameters.maxOutputLength
Limits output size when using
convenience methods. Default:buffer.kMaxLength
For exercise :
const stream = zlib. createBrotliCompress({
chunkSize: 32 * 1024,
params: {
[zlib. constants. BROTLI_PARAM_MODE]: zlib. constants. BROTLI_MODE_TEXT,
[zlib. constants. BROTLI_PARAM_QUALITY]: 4,
[zlib. constants. BROTLI_PARAM_SIZE_HINT]: fs. statSync(inputFile). size
}
});
Class: zlib.BrotliCompress
#
Added in: v11.7.0, v10.16.0
Compress data using the Brotli algorithm .
Class: zlib.BrotliDecompress
#
Added in: v11.7.0, v10.16.0
Decompress data using the Brotli algorithm .
Class: zlib.Deflate
#
Added in: v0.5.8
Compress data using deflate .
Class: zlib.DeflateRaw
#
Added in: v0.5.8
Compress data using deflate, and do not append a zlib
header .
Class: zlib.Gunzip
#
History
Version | Changes |
---|---|
v6.0.0 | Trailing drivel at the end of the input pour will now result in an 'error' event . |
v5.9.0 | Multiple concatenated gzip file members are supported now . |
v5.0.0 | A truncate input flow will nowadays result in an 'error' event . |
v0.5.8 | Added in : v0.5.8 |
Decompress a gzip stream .
Class: zlib.Gzip
#
Added in: v0.5.8
Compress data using gzip .
Class: zlib.Inflate
#
History
Version | Changes |
---|---|
v5.0.0 | A truncate input stream will immediately result in an 'error' event . |
v0.5.8 | Added in : v0.5.8 |
Decompress a deflate pour .
Class: zlib.InflateRaw
#
History
Version | Changes |
---|---|
v6.8.0 | Custom dictionaries are now supported by InflateRaw . |
v5.0.0 | A truncate remark stream will now result in an 'error' event . |
v0.5.8 | Added in : v0.5.8 |
Decompress a raw deflate pour .
Class: zlib.Unzip
#
Added in: v0.5.8
Decompress either a Gzip- or Deflate-compressed stream by auto-detecting the header .
Class: zlib.ZlibBase
#
History
Version | Changes |
---|---|
v11.7.0, v10.16.0 | This class was renamed from Zlib to ZlibBase . |
v0.5.8 | Added in : v0.5.8 |
not exported by the zlib
module. It is documented here because it is the base classify of the compressor/decompressor classes .
This class inherits from stream.Transform
, allowing zlib
objects to be used in pipes and alike flow operations .
zlib.bytesRead
#
Added in: v8.1.0
Deprecated since: v10.0.0
Stability: 0 - Deprecated: Use zlib.bytesWritten
instead.
Deprecated alias for zlib.bytesWritten
. This original name was chosen because it besides made sense to interpret the respect as the number of bytes read by the locomotive, but is discrepant with other streams in Node.js that debunk values under these names .
zlib.bytesWritten
#
Added in: v10.0.0
The zlib.bytesWritten
property specifies the issue of bytes written to the engine, before the bytes are processed ( compressed or decompressed, as allow for the derive course ) .
zlib.close([callback])
#
Added in: v0.9.4
callback
close the underlying manage .
zlib.flush([kind, ]callback)
#
Added in: v0.5.8
kind
Default:zlib.constants.Z_FULL_FLUSH
for zlib-based streams,
zlib.constants.BROTLI_OPERATION_FLUSH
for Brotli-based streams.callback
blush pending data. Do n't call this frivolously, previous flushes negatively impact the effectiveness of the compaction algorithm .
Calling this only flushes data from the home zlib
state, and does not perform blush of any kind on the stream degree. quite, it behaves like a convention margin call to .write()
, i.e. it will be queued up behind other pending writes and will only produce output signal when datum is being read from the stream .
zlib.params(level, strategy, callback)
#
Added in: v0.11.4
level
strategy
callback
This function is only available for zlib-based streams, i.e. not Brotli .
dynamically update the compaction level and compression strategy. only applicable to deflate algorithm .
zlib.reset()
#
Added in: v0.7.0
Reset the compressor/decompressor to factory defaults. entirely applicable to the inflate and deflate algorithms .
zlib.constants
#
Added in: v7.0.0
Provides an object enumerating Zlib-related constants .
zlib.createDeflateRaw([options])
#
Added in: v0.5.8
options
Creates and returns a new DeflateRaw
object .
An upgrade of zlib from 1.2.8 to 1.2.11 changed behavior when windowBits
is set to 8 for crude deflate streams. zlib would automatically set windowBits
to 9 if was initially set to 8. Newer versions of zlib will throw an exception, so Node.js restored the original demeanor of upgrading a rate of 8 to 9, since passing windowBits = 9
to zlib actually results in a compress stream that efficaciously uses an 8-bit windowpane only .