Assert
const assert = require('assert');
assert(1 > 2, 'Wrong');
assert.deepEqual({a: {b: 1}}, {a: {b: 2}}, 'Wrong');
assert.deepStrictEqual({a: 1}, {a: '1'}, 'Wrong');
assert.doesNotThrow(function () {throw new TypeError('Wrong value');}, TypeError, 'Wrong');
assert.equal(1, 2, 'Wrong'); // 1 == 2
assert.fail(1, 2, 'Wrong', '>');
assert.ifError(0); // - OK
assert.ifError(1); // - Throws 1
assert.notDeepEqual({a: { b: 1}}, {a: { b: 1}}, 'Wrong');
assert.notDeepStrictEqual({a: 1}, {a: '1'}, 'Wrong');
assert.notEqual(1, '1', 'Wrong');
assert.notStrictEqual(1, 1, 'Wrong');
assert.ok(0, 'Wrong');
assert.strictEqual(1, 2, 'Wrong'); // 1 === 2
assert.throws(
function () {throw new Error('Wrong value');}
, function (error) {
if ((error instanceof Error) && /value/.test(error)) {return true;}
}
, 'Wrong'
);
Buffer
const MAX_BYTES = buffer.INSPECT_MAX_BYTES; // 50
const MAX_BUFFER_LENGTH = buffer.kMaxLength; // ~ 1GB
let buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); // deprecated
let buf = new Buffer(new Buffer('buffer')); // deprecated
let buf = new Buffer(new Uint16Array(2), 0 , 2); // deprecated
let buf = new Buffer(10); // deprecated
let buf = new Buffer('text', 'utf8'); // deprecated
let buf = new SlowBuffer(size); // deprecated
let buf = Buffer.alloc(10, 'a', 'utf8');
let buf = Buffer.allocUnsafe(10);
let buf = Buffer.allocUnsafeSlow(10);
let byteLength = Buffer.byteLength('text', 'utf8');
let isEqual = Buffer.compare(Buffer.from('1234'), Buffer.from('0123'));
let buf = Buffer.concat([buf1, buf2, buf3], buf1.length + buf2.length + buf3.length);
let buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
let buf = Buffer.from(new Uint16Array(2), 0, 2);
let buf = Buffer.from(new Buffer('buffer'));
let buf = Buffer.from('text', 'utf8');
let isBuffer = Buffer.isBuffer(new Buffer('buffer'));
let isBufferEncodingUTF8 = Buffer.isEncoding('utf8');
let poolSize = Buffer.poolSize; // 8192
for (let index = 0; index < str.length ; index++) {
buf[index] = str.charCodeAt(index);
}
let result = buf1.compare(buf2, targetStart, targetEnd, sourceStart, sourceEnd);
buf1.copy(buf2, targetStart, sourceStart, sourceEnd);
const buf = Buffer.from('buffer');
for (let pair of buf.entries()) {
console.log(pair);
}
// Prints:
// [0, 98]
// [1, 117]
// [2, 102]
// [3, 102]
// [4, 101]
// [5, 114]
let result = buf.equals(otherBuffer);
buf.fill('a', offset, end, 'utf8');
let index = buf.indexOf('abc', byteOffset, 'utf8');
let result = buf.includes('abc', byteOffset, 'utf8');
const buf = Buffer.from('buffer');
for (let key of buf.keys()) {
console.log(key);
}
// Prints:
// 0
// 1
// 2
// 3
// 4
// 5
let index = buf.lastIndexOf('abc', byteOffset, 'utf8');
const buf = Buffer.alloc(5);
let length = buf.length; // 5
let result = buf.readDoubleBE(offset, false);
let result = buf.readDoubleLE(offset, false);
let result = buf.readFloatBE(offset, false);
let result = buf.readFloatLE(offset, false);
let result = buf.readInt8(offset, false);
let result = buf.readInt16BE(offset, false);
let result = buf.readInt16LE(offset, false);
let result = buf.readInt32BE(offset, false);
let result = buf.readInt32LE(offset, false);
let result = buf.readIntBE(offset, byteLength, false);
let result = buf.readIntLE(offset, byteLength, false);
let result = buf.readUInt8(offset, false);
let result = buf.readUInt16BE(offset, false);
let result = buf.readUInt16LE(offset, false);
let result = buf.readUInt32BE(offset, false);
let result = buf.readUInt32LE(offset, false);
let result = buf.readUIntBE(offset, byteLength, false);
let result = buf.readUIntLE(offset, byteLength, false);
let buf2 = buf1.slice(0, 3);
let buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
console.log(buf); // Prints: <Buffer 01 02 03 04 05 06 07 08>
buf.swap16();
console.log(buf); // Prints: <Buffer 02 01 04 03 06 05 08 07>
buf.swap16();
buf.swap32();
buf.swap64();
let result = buf.toString('base64', start, end);
let result = buf.toJSON();
let buf = Buffer.from('buffer');
for (let value of buf.values()) {
console.log(value);
}
// Prints:
// 98
// 117
// 102
// 102
// 101
// 114
buf.write('string', offset, length, 'utf8');
buf.writeDoubleBE(0xdeadbeefcafebabe, offset, false);
buf.writeDoubleLE(0xdeadbeefcafebabe, offset, false);
buf.writeFloatBE(0xcafebabe, offset, false);
buf.writeFloatLE(0xcafebabe, offset, false);
buf.writeInt8(2, offset, false);
buf.writeInt16BE(0x0102, offset, false);
buf.writeInt16LE(0x0304, offset, false);
buf.writeInt32BE(0x01020304, offset, false);
buf.writeInt32LE(0x05060708, offset, false);
buf.writeIntBE(0x1234567890ab, offset, byteLength, false);
buf.writeIntLE(0x1234567890ab, offset, byteLength, false);
buf.writeUInt8(0x3, offset, false);
buf.writeUInt16BE(0xdead, offset, false);
buf.writeUInt16LE(0xdead, offset, false);
buf.writeUInt32BE(0xfeedface, offset, false);
buf.writeUInt32LE(0xfeedface, offset, false);
buf.writeUIntBE(0x1234567890ab, offset, byteLength, false);
buf.writeUIntLE(0x1234567890ab, offset, byteLength, false);
Child Process
const child_process = require('child_process');
// Выполнить файл и вернуть результат выполнения в callback-функцию
const execFileProcess = child_process.execFile(
'node.exe'
, ['--version']
, {
encoding: 'utf8'
, timeout: 0
, maxBuffer: 200*1024
, killSignal: 'SIGTERM'
, cwd: null
, env: process.env
}
, function (error, stdout, stderr) {
if (error) {
console.error('exec error: ' + error);
return;
}
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
}
);
// Выполнить долгий процесс и обработать результат выполнения в потоке
const spawnProcess = child_process.spawn('ls', ['-la', '/work/project'], {shell: true, detached: true, stdio: 'ignore'});
spawnProcess.stdout.on('data', function (data) {console.log('stdout: ' + data);});
spawnProcess.stderr.on('data', function (data) {console.log('stderr: ' + data);});
spawnProcess.on('close', function (code) {console.log('spawn process exited with code ' + code);});
spawnProcess.on('error', function (error) {console.log('Failed to start spawn process.');});
// Выполнить команду в окне командной строки и вернуть результат выполнения в callback-функцию
child_process.exec(
'file.bat'
, {
encoding: 'utf8'
, timeout: 0
, maxBuffer: 200*1024
, killSignal: 'SIGTERM'
, cwd: null
, env: process.env
}
, function (error, stdout, stderr) {
if (error) {
console.error('exec error: ' + error);
return;
}
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
}
);
// Выполнить код из файла JavaScript в отдельном процессе Node.js
const forkProcess = child_process.fork('./work/server.js', ['127.0.0.1', '80'], {cwd: null, env: process.env});
// Sync child process
child_process.execFileSync('file', [args], {options});
child_process.spawnSync('command', [args], {options});
child_process.execSync('command', {options});
// Child process Events
childProcess.on('close', function (code, signale) {
console.log('child process closed with code: ' + code + ' and signal: ' + signal);
});
childProcess.disconnect();
childProcess.on('disconnect', function () {
console.log('child process disconnected');
});
childProcess.kill('SIGHUP');
childProcess.on('error', function (error) {
console.log('child process could not be spawned or could not be killed');
});
childProcess.on('exit', function (code, signal) {
console.log('child process exit with code: ' + code + ' and signal: ' + signal);
});
child.send({hello: 'world'}, require('net').createServer(), {keepOpen: true}, function (error) {
if (error) {throw error;}
console.log('Message sent');
});
childProcess.on('message', function (message, sendHandler) {
console.log('child process got message: ' + message);
sendHandler(); // <Handle> a net.Socket or net.Server object, or undefined
});
if (childProcess.connected) { // Set to false after child.disconnect() is called
childProcess.send('message');
}
// PID
const childProcess = child_process.spawn('grep', ['ssh']);
console.log('Spawned child pid: ' + childProcess.pid);
// STDIN, STDOUT, STDERR
childProcess.stderr.on('data', function () {});
childProcess.stdin.on('data', function () {});
childProcess.stdio.on('data', function () {});
childProcess.stdout.on('data', function () {});
Cluster
const cluster = require('cluster');
const createServer = require('./server.js');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
let worker;
for (let i = 0; i < numCPUs; i++) {
worker = cluster.fork();
worker.send('hi');
}
// Навешиваем события на воркеры
var numReqs = 0;
Object.keys(cluster.workers).forEach(function (id) {
cluster.workers[id].on('message', function (message) {
if (message.cmd && message.cmd == 'notifyRequest') {
numReqs++;
}
});
});
cluster.on('exit', function (worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
console.log('starting new worker');
cluster.fork();
});
let timeout;
Object.keys(cluster.workers).forEach(function (id) {
const worker = cluster.workers[id];
worker.on('listening', function (address) {
worker.send('shutdown');
worker.disconnect();
timeout = setTimeout(function () {
worker.kill();
}, 2000);
});
worker.on('disconnect', function () {
clearTimeout(timeout);
});
});
} else if (cluster.isWorker) {
createServer(function (request, response) {
response.writeHead(200);
response.end('hello world\n');
// notify master about the request
process.send({cmd: 'notifyRequest'});
});
process.on('message', function (message) {
if (message === 'shutdown') {
// initiate graceful close of any connections to server
}
if (message === 'hi') {
process.send('bye');
}
});
}
cluster.on('exit', function (worker, code, signal) {
if (worker.exitedAfterDisconnect === true) { // Set by calling .kill() or .disconnect(). Until then, it is undefined.
console.log('Oh, it was just voluntary – no need to worry');
}
});
// Worker events
const worker = cluster.fork();
worker.disconnect();
worker.on('disconnect', function () {console.log('Worker has disconnected');});
worker.on('error', function () {console.log('Error in worker process');});
worker.on('exit', function (code, signal) {
if (signal) {
console.log('worker was killed by signal: ' + signal);
} else if (code !== 0) {
console.log('worker exited with error code: ' + code);
} else {
console.log('worker success!');
}
});
worker.on('listening', function (address) {
console.log('Worker is listening');
});
let requestNumber = 0;
process.send({cmd: 'notifyRequest'});
worker.on('message', function (message) {
if (message.cmd && message.cmd === 'notifyRequest') {
requestNumber += 1;
}
});
worker.on('online', function () {
console.log('Worker is online');
});
// Worker status and methods
worker.exitedAfterDisconnect
worker.id
worker.isConnected();
worker.isDead();
worker.kill('SIGTERM');
worker.process
worker.send(message, sendHandle, callback);
worker.suicide // deprecated
// kill worker
worker.kill();
cluster.on('exit', function (worker, code, signal) {
if (worker.suicide === true) {
console.log('Oh, it was just voluntary – no need to worry');
}
});
// Cluster events
cluster.on('disconnect', function (worker) {
console.log('The worker #' + worker.id + ' has disconnected');
});
cluster.on('exit', function (worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died ' + (signal || code) + '. Restarting...');
cluster.fork();
});
var timeouts = [];
function errorMsg () {console.error('Something must be wrong with the connection ...');}
cluster.on('fork', function (worker) {timeouts[worker.id] = setTimeout(errorMsg, 2000);});
cluster.on('listening', function (worker, address) {clearTimeout(timeouts[worker.id]);});
cluster.on('exit', function (worker, code, signal) {clearTimeout(timeouts[worker.id]);
errorMsg();
});
cluster.on('listening', function (worker, address) {
console.log('A worker is now connected to ' + address.address + ':' + address.port);
});
cluster.on('message', function (worker, message, handle) {
if (arguments.length === 2) {
handle = message;
message = worker;
worker = undefined;
}
// ...
});
cluster.on('online', function (worker) {
console.log('Yay, the worker responded after it was forked');
});
cluster.on('setup', function () {});
// Cluster status and methods
cluster.disconnect(function () {});
let worker = cluster.fork({env});
if (cluster.isMaster) {}
if (cluster.isWorker) {}
cluster.schedulingPolicy;
let settings = cluster.settings;
const cluster = require('cluster');
cluster.setupMaster({
exec: 'worker.js'
, args: ['--use', 'https']
, silent: true
});
cluster.fork(); // https worker
cluster.setupMaster({
exec: 'worker.js'
, args: ['--use', 'http']
});
cluster.fork(); // http worker
const cluster = require('cluster');
if (cluster.isMaster) {
console.log('I am master');
cluster.fork();
cluster.fork();
} else if (cluster.isWorker) {
console.log('I am worker #' + cluster.worker.id);
}
// Go through all workers
function eachWorker (callback) {
for (let id in cluster.workers) {
callback(cluster.workers[id]);
}
}
eachWorker(function (worker) {
worker.send('big announcement to all workers');
});
socket.on('data', function (id) {
let worker = cluster.workers[id];
});
Console
const logger = new console.new Console(process.stdout, process.stderr);
const logger = new console.Console(fs.createWriteStream('./stdout.log'), fs.createWriteStream('./stderr.log'));
logger.log('ok');
logger.error('bad');
logger.warn('danger');
console.assert(false, 'Whoops %s', 'didn\'t work');
// Creates a simple extension of console with a
// new implementation for assert without monkey-patching.
const myConsole = Object.setPrototypeOf({
assert(assertion, message, ...args) {
try {
console.assert(assertion, message, ...args);
} catch (error) {
console.error(error.stack);
}
}
}, console);
module.exports = myConsole;
const console = require('./myConsole');
console.assert(false, 'this message will print, but no error thrown');
console.log('this will also print');
console.dir({a: 1, b: 2, c: 3}, {
showHidden: true
, depth: 3
, colors: true
});
const code = 5;
console.error('error #%d', code);
console.info('one', 'two', 'three');
console.log('hello %s', 'world');
console.time('100-elements');
for (let i = 0; i < 100; i++) {
// some code
}
console.timeEnd('100-elements');
// prints 100-elements: 225.438ms
console.trace('Show me my stack trace');
// Prints: (stack trace will vary based on where trace is called)
// Trace: Show me my stack trace
// at repl:2:9
// at REPLServer.defaultEval (repl.js:248:27)
// at bound (domain.js:287:14)
// at REPLServer.runBound [as eval] (domain.js:300:12)
// at REPLServer.<anonymous> (repl.js:412:12)
// at emitOne (events.js:82:20)
// at REPLServer.emit (events.js:169:7)
// at REPLServer.Interface._onLine (readline.js:210:10)
// at REPLServer.Interface._line (readline.js:549:8)
// at REPLServer.Interface._ttyWrite (readline.js:826:14)
console.warn('Danger!', 'Danger!', 'Danger!');
Crypto
// Determining if crypto support is unavailable
var crypto;
try {
crypto = require('crypto');
} catch (error) {
console.log('crypto support is disabled!');
}
if (crypto) {
const secret = 'abcdefg';
const hash = crypto.createHmac('sha256', secret)
.update('I love cupcakes')
.digest('hex');
console.log(hash);
// Prints:
// c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
}
// Certificate
const crypto = require('crypto');
const cert1 = new crypto.Certificate();
const cert2 = crypto.Certificate();
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Prints the challenge as a UTF8 string
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// Prints the public key as <Buffer ...>
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
// Prints true or false
// Cipher
const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');
var encrypted = '';
cipher.on('readable', () => {
var data = cipher.read();
if (data) {
encrypted += data.toString('hex');
}
});
cipher.on('end', () => {
console.log(encrypted);
// Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504
});
cipher.write('some clear text data');
cipher.end();
const crypto = require('crypto');
const fs = require('fs');
const cipher = crypto.createCipher('aes192', 'a password');
const input = fs.createReadStream('test.js');
const output = fs.createWriteStream('test.enc');
input.pipe(cipher).pipe(output);
const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');
var encrypted = cipher.update('some clear text data', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504
cipher.final('base64');
cipher.setAAD(buffer);
cipher.getAuthTag();
cipher.setAutoPadding(false);
cipher.update('some text', 'ascii', 'utf8');
// Decipher
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
var decrypted = '';
decipher.on('readable', () => {
var data = decipher.read();
if (data)
decrypted += data.toString('utf8');
});
decipher.on('end', () => {
console.log(decrypted);
// Prints: some clear text data
});
var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
decipher.write(encrypted, 'hex');
decipher.end();
const crypto = require('crypto');
const fs = require('fs');
const decipher = crypto.createDecipher('aes192', 'a password');
const input = fs.createReadStream('test.enc');
const output = fs.createWriteStream('test.js');
input.pipe(decipher).pipe(output);
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
var decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data
decipher.final('base64');
decipher.setAAD(buffer);
decipher.setAuthTag(buffer);
decipher.setAutoPadding(false);
decipher.update('some text', 'base64', 'utf8');
// DiffieHellman
const crypto = require('crypto');
const assert = require('assert');
// Generate Alice's keys...
const alice = crypto.createDiffieHellman(2048);
const alice_key = alice.generateKeys();
// Generate Bob's keys...
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bob_key = bob.generateKeys();
// Exchange and generate the secret...
const alice_secret = alice.computeSecret(bob_key);
const bob_secret = bob.computeSecret(alice_key);
// OK
assert.equal(alice_secret.toString('hex'), bob_secret.toString('hex'));
diffieHellman.computeSecret(other_public_key, 'hex', 'base64');
diffieHellman.generateKeys('base64');
diffieHellman.getGenerator('base64');
diffieHellman.getPrime('base64');
diffieHellman.getPrivateKey('base64');
diffieHellman.getPublicKey('base64');
diffieHellman.setPrivateKey('some key', 'base64');
diffieHellman.setPublicKey('some key', 'base64');
diffieHellman.verifyError = DH_CHECK_P_NOT_SAFE_PRIME';
// ECDH
const crypto = require('crypto');
const assert = require('assert');
// Generate Alice's keys...
const alice = crypto.createECDH('secp521r1');
const alice_key = alice.generateKeys();
// Generate Bob's keys...
const bob = crypto.createECDH('secp521r1');
const bob_key = bob.generateKeys();
// Exchange and generate the secret...
const alice_secret = alice.computeSecret(bob_key);
const bob_secret = bob.computeSecret(alice_key);
assert(alice_secret, bob_secret);
// OK
ecdh.computeSecret(other_public_key, 'hex', 'base64');
ecdh.generateKeys('base64', 'compressed');
ecdh.getPrivateKey('base64');
ecdh.getPublicKey('base64', 'compressed');
ecdh.setPrivateKey('some key', 'base64');
ecdh.setPublicKey('some key', 'base64'); // deprecated
const crypto = require('crypto');
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');
// Note: This is a shortcut way to specify one of Alice's previous private
// keys. It would be unwise to use such a predictable private key in a real
// application.
alice.setPrivateKey(
crypto.createHash('sha256').update('alice', 'utf8').digest()
);
// Bob uses a newly generated cryptographically strong
// pseudorandom key pair bob.generateKeys();
const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
// alice_secret and bob_secret should be the same shared secret value
console.log(alice_secret === bob_secret);
// Hash
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.on('readable', () => {
var data = hash.read();
if (data)
console.log(data.toString('hex'));
// Prints:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
});
hash.write('some data to hash');
hash.end();
const crypto = require('crypto');
const fs = require('fs');
const hash = crypto.createHash('sha256');
const input = fs.createReadStream('test.js');
input.pipe(hash).pipe(process.stdout);
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('some data to hash');
console.log(hash.digest('hex'));
// Prints:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
hash.digest('base64');
hash.update('some text', 'utf8');
// Hmac
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'a secret');
hmac.on('readable', () => {
var data = hmac.read();
if (data)
console.log(data.toString('hex'));
// Prints:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
});
hmac.write('some data to hash');
hmac.end();
const crypto = require('crypto');
const fs = require('fs');
const hmac = crypto.createHmac('sha256', 'a secret');
const input = fs.createReadStream('test.js');
input.pipe(hmac).pipe(process.stdout);
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'a secret');
hmac.update('some data to hash');
console.log(hmac.digest('hex'));
// Prints:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
hmac.digest('base64');
hmac.update('some text', 'utf8');
// Sign
const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');
sign.write('some data to sign');
sign.end();
const private_key = getPrivateKeySomehow();
console.log(sign.sign(private_key, 'hex'));
// Prints the calculated signature
const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');
sign.update('some data to sign');
const private_key = getPrivateKeySomehow();
console.log(sign.sign(private_key, 'hex'));
// Prints the calculated signature
const crypto = require('crypto');
const sign = crypto.createSign('sha256');
sign.update('some data to sign');
const private_key = '-----BEGIN EC PRIVATE KEY-----\n' +
'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' +
'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' +
'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END EC PRIVATE KEY-----\n';
console.log(sign.sign(private_key).toString('hex'));
sign.sign('some key', 'base64');
sign.update('some text', 'utf8');
// Verify
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA256');
verify.write('some data to sign');
verify.end();
const public_key = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(public_key, signature));
// Prints true or false
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA256');
verify.update('some data to sign');
const public_key = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(public_key, signature));
// Prints true or false
verifier.update('some text', 'utf8');
verifier.verify({object}, 'hex', signature_format);
// Crypto module methods and properties
let constants = crypto.constants;
crypto.constants.ENGINE_METHOD_RSA
crypto.constants.ENGINE_METHOD_DSA
crypto.constants.ENGINE_METHOD_DH
crypto.constants.ENGINE_METHOD_RAND
crypto.constants.ENGINE_METHOD_ECDH
crypto.constants.ENGINE_METHOD_ECDSA
crypto.constants.ENGINE_METHOD_CIPHERS
crypto.constants.ENGINE_METHOD_DIGESTS
crypto.constants.ENGINE_METHOD_STORE
crypto.constants.ENGINE_METHOD_PKEY_METHS
crypto.constants.ENGINE_METHOD_PKEY_ASN1_METHS
crypto.constants.ENGINE_METHOD_ALL
crypto.constants.ENGINE_METHOD_NONE
let encoding = crypto.DEFAULT_ENCODING;
if (crypto.fips) {}
crypto.createCipher(algorithm, password);
crypto.createCipheriv(algorithm, key, iv);
crypto.createCredentials(details); // deprecated
crypto.createDecipher(algorithm, password);
crypto.createDecipheriv(algorithm, key, iv);
crypto.createDiffieHellman(prime, prime_encoding, generator, generator_encoding);
crypto.createDiffieHellman(prime_length, generator);
crypto.createECDH(curve_name);
crypto.createHash(algorithm);
onst filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');
const hash = crypto.createHash('sha256');
const input = fs.createReadStream(filename);
input.on('readable', () => {
var data = input.read();
if (data) {
hash.update(data);
} else {
console.log(`${hash.digest('hex')} ${filename}`);
}
});
crypto.createHmac(algorithm, key);
const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');
const hmac = crypto.createHmac('sha256', 'a secret');
const input = fs.createReadStream(filename);
input.on('readable', () => {
var data = input.read();
if (data)
hmac.update(data);
else {
console.log(`${hmac.digest('hex')} ${filename}`);
}
});
crypto.createSign(algorithm);
crypto.createVerify(algorithm);
crypto.getCiphers();
const ciphers = crypto.getCiphers();
console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]
crypto.getCurves();
const curves = crypto.getCurves();
console.log(curves); // ['secp256k1', 'secp384r1', ...]
crypto.getDiffieHellman(group_name);
const crypto = require('crypto');
const alice = crypto.getDiffieHellman('modp14');
const bob = crypto.getDiffieHellman('modp14');
alice.generateKeys();
bob.generateKeys();
const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
crypto.getHashes();
const hashes = crypto.getHashes();
console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
crypto.pbkdf2(password, salt, iterations, keylen, digest, callback);
const crypto = require('crypto');
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => {
if (err) throw err;
console.log(key.toString('hex')); // 'c5e478d...1469e50'
});
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest);
const crypto = require('crypto');
const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512');
console.log(key.toString('hex')); // 'c5e478d...1469e50'
crypto.privateDecrypt(private_key, buffer);
crypto.timingSafeEqual(a, b);
crypto.privateEncrypt(private_key, buffer);
crypto.publicDecrypt(public_key, buffer);
crypto.publicEncrypt(public_key, buffer);
crypto.randomBytes(size, callback);
// Asynchronous
const crypto = require('crypto');
crypto.randomBytes(256, (err, buf) => {
if (err) throw err;
console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
});
// Synchronous
const buf = crypto.randomBytes(256);
console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
crypto.setEngine(engine, flags);
Debugger
debugger;
Stepping:
cont, c - Continue execution
next, n - Step next
step, s - Step in
out, o - Step out
pause - Pause running code (like pause button in Developer Tools)
Breakpoints:
setBreakpoint(), sb() - Set breakpoint on current line
setBreakpoint(line), sb(line) - Set breakpoint on specific line
setBreakpoint('fn()'), sb(...) - Set breakpoint on a first statement in functions body
setBreakpoint('script.js', 1), sb(...) - Set breakpoint on first line of script.js
clearBreakpoint('script.js', 1), cb(...) - Clear breakpoint in script.js on line 1
Information:
backtrace, bt - Print backtrace of current execution frame
list(5) - List scripts source code with 5 line context (5 lines before and after)
watch(expr) - Add expression to watch list
unwatch(expr) - Remove expression from watch list
watchers - List all watchers and their values (automatically listed on each breakpoint)
repl - Open debugger's repl for evaluation in debugging script's context
exec expr - Execute an expression in debugging script's context
Execution control:
run - Run script (automatically runs on debugger's start)
restart - Restart script
kill - Kill script
Various:
scripts - List all loaded scripts
version - Display V8's version
// myscript.js
x = 5;
setTimeout(() => {
debugger;
console.log('world');
}, 1000);
console.log('hello');
$ node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
1 x = 5;
2 setTimeout(() => {
3 debugger;
< hello
break in /home/indutny/Code/git/indutny/myscript.js:3
1 x = 5;
2 setTimeout(() => {
3 debugger;
4 console.log('world');
5 }, 1000);
debug> next
break in /home/indutny/Code/git/indutny/myscript.js:4
2 setTimeout(() => {
3 debugger;
4 console.log('world');
5 }, 1000);
6 console.log('hello');
debug> repl
Press Ctrl + C to leave debug repl
> x
5
> 2+2
4
debug> next
< world
break in /home/indutny/Code/git/indutny/myscript.js:5
3 debugger;
4 console.log('world');
5 }, 1000);
6 console.log('hello');
7
debug> quit
DNS
const dns = require('dns');
dns.lookup('google.com', function (error, addresses, family) {
console.log('addresses:', addresses);
});
const dns = require('dns');
dns.resolve4('nodejs.org', function (err, addresses) {
if (err) {throw err;}
console.log(`addresses: ${JSON.stringify(addresses)}`);
addresses.forEach(function (a) {
dns.reverse(a, function (err, hostnames) {
if (err) {throw err;}
console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
});
});
});
let serversIPaddressesArray = dns.getServers();
dns.lookup(
'google.com'
, {
family: 4
, hints: dns.ADDRCONFIG | dns.V4MAPPED
, all: false
}
, function (error, address, family) {}
);
dns.lookupService('127.0.0.1', 22, function (error, hostname, service) {
console.log(hostname, service);
// Prints: localhost ssh
});
dns.resolve('google.com', 'TXT', function (err, addresses) {});
dns.resolve4('google.com', function (err, addresses) {});
dns.resolve6('google.com', function (err, addresses) {});
dns.resolveCname('google.com', function (err, addresses) {});
dns.resolveMx('google.com', function (err, addresses) {});
dns.resolveNaptr('google.com', function (err, addresses) {});
dns.resolveNs('google.com', function (err, addresses) {});
dns.resolveSoa('google.com', function (err, addresses) {});
dns.resolveSrv('google.com', function (err, addresses) {});
dns.resolvePtr('google.com', function (err, addresses) {});
dns.resolveTxt('google.com', function (err, addresses) {});
dns.reverse(ip, function (err, hostnames) {});
dns.setServers(servers);
Error codes:
dns.NODATA: DNS server returned answer with no data.
dns.FORMERR: DNS server claims query was misformatted.
dns.SERVFAIL: DNS server returned general failure.
dns.NOTFOUND: Domain name not found.
dns.NOTIMP: DNS server does not implement requested operation.
dns.REFUSED: DNS server refused query.
dns.BADQUERY: Misformatted DNS query.
dns.BADNAME: Misformatted hostname.
dns.BADFAMILY: Unsupported address family.
dns.BADRESP: Misformatted DNS reply.
dns.CONNREFUSED: Could not contact DNS servers.
dns.TIMEOUT: Timeout while contacting DNS servers.
dns.EOF: End of file.
dns.FILE: Error reading file.
dns.NOMEM: Out of memory.
dns.DESTRUCTION: Channel is being destroyed.
dns.BADSTR: Misformatted string.
dns.BADFLAGS: Illegal flags specified.
dns.NONAME: Given hostname is not numeric.
dns.BADHINTS: Illegal hints flags specified.
dns.NOTINITIALIZED: c-ares library initialization not yet performed.
dns.LOADIPHLPAPI: Error loading iphlpapi.dll.
dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
dns.CANCELLED: DNS query cancelled.
Domain // deprecated
// Warning: Don't Ignore Errors!
// XXX WARNING! BAD IDEA!
var d = require('domain').create();
d.on('error', function (er) {
// The error won't crash the process, but what it does is worse!
// Though we've prevented abrupt process restarting, we are leaking
// resources like crazy if this ever happens.
// This is no better than process.on('uncaughtException')!
console.log('error, but oh well', er.message);
});
d.run(function () {
require('http').createServer(function (req, res) {
handleRequest(req, res);
}).listen(PORT);
});
// Much better!
const cluster = require('cluster');
const PORT = +process.env.PORT || 1337;
if (cluster.isMaster) {
// In real life, you'd probably use more than just 2 workers,
// and perhaps not put the master and worker in the same file.
//
// You can also of course get a bit fancier about logging, and
// implement whatever custom logic you need to prevent DoS
// attacks and other bad behavior.
//
// See the options in the cluster documentation.
//
// The important thing is that the master does very little,
// increasing our resilience to unexpected errors.
cluster.fork();
cluster.fork();
cluster.on('disconnect', (worker) => {
console.error('disconnect!');
cluster.fork();
});
} else {
// the worker
//
// This is where we put our bugs!
const domain = require('domain');
// See the cluster documentation for more details about using
// worker processes to serve requests. How it works, caveats, etc.
const server = require('http').createServer((req, res) => {
var d = domain.create();
d.on('error', (er) => {
console.error('error', er.stack);
// Note: we're in dangerous territory!
// By definition, something unexpected occurred,
// which we probably didn't want.
// Anything can happen now! Be very careful!
try {
// make sure we close down within 30 seconds
var killtimer = setTimeout(() => {
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
// stop taking new requests.
server.close();
// Let the master know we're dead. This will trigger a
// 'disconnect' in the cluster master, and then it will fork
// a new worker.
cluster.worker.disconnect();
// try to send an error to the request that triggered the problem
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
} catch (er2) {
// oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
// Because req and res were created before this domain existed,
// we need to explicitly add them.
// See the explanation of implicit vs explicit binding below.
d.add(req);
d.add(res);
// Now run the handler function in the domain.
d.run(() => {
handleRequest(req, res);
});
});
server.listen(PORT);
}
// This part isn't important. Just an example routing thing.
// You'd put your fancy application logic here.
function handleRequest(req, res) {
switch(req.url) {
case '/error':
// We do some async stuff, and then...
setTimeout(() => {
// Whoops!
flerb.bark();
});
break;
default:
res.end('ok');
}
}
// Explicit Binding
// create a top-level domain for the server
const domain = require('domain');
const http = require('http');
const serverDomain = domain.create();
serverDomain.run(() => {
// server is created in the scope of serverDomain
http.createServer((req, res) => {
// req and res are also created in the scope of serverDomain
// however, we'd prefer to have a separate domain for each request.
// create it first thing, and add req and res to it.
var reqd = domain.create();
reqd.add(req);
reqd.add(res);
reqd.on('error', (er) => {
console.error('Error', er, req.url);
try {
res.writeHead(500);
res.end('Error occurred, sorry.');
} catch (er) {
console.error('Error sending 500', er, req.url);
}
});
}).listen(1337);
});
domain.create();
domain.run(fn, arg, ...);
const domain = require('domain');
const fs = require('fs');
const dom = domain.create();
dom.on('error', (er) => {
console.error('Caught error!', er);
});
dom.run(() => {
process.nextTick(() => {
setTimeout(() => { // simulating some various async stuff
fs.open('non-existent file', 'r', (er, fd) => {
if (er) throw er;
// proceed...
});
}, 100);
});
});
domain.members
domain.add(emitter);
domain.remove(emitter);
domain.bind(callback);
const dom = domain.create();
function readSomeFile(filename, cb) {
fs.readFile(filename, 'utf8', dom.bind((er, data) => {
// if this throws, it will also be passed to the domain
return cb(er, data ? JSON.parse(data) : null);
}));
}
dom.on('error', (er) => {
// an error occurred somewhere.
// if we throw it now, it will crash the program
// with the normal line number and stack message.
});
domain.intercept(callback);
const dom = domain.create();
function readSomeFile(filename, cb) {
fs.readFile(filename, 'utf8', dom.intercept((data) => {
// note, the first argument is never passed to the
// callback since it is assumed to be the 'Error' argument
// and thus intercepted by the domain.
// if this throws, it will also be passed to the domain
// so the error-handling logic can be moved to the 'error'
// event on the domain instead of being repeated throughout
// the program.
return cb(null, JSON.parse(data));
}));
}
dom.on('error', (er) => {
// an error occurred somewhere.
// if we throw it now, it will crash the program
// with the normal line number and stack message.
});
domain.enter();
domain.exit();
domain.dispose(); // deprecated
Errors
Standard JavaScript errors such as:
<EvalError> : thrown when a call to eval() fails.
<SyntaxError> : thrown in response to improper JavaScript language syntax.
<RangeError> : thrown when a value is not within an expected range
<ReferenceError> : thrown when using undefined variables
<TypeError> : thrown when passing arguments of the wrong type
<URIError> : thrown when a global URI handling function is misused.
System errors triggered by underlying operating system constraints such as attempting to open a file that does not exist, attempting to send data over a closed socket, etc;
And User-specified errors triggered by application code.
Assertion Errors are a special class of error that can be triggered whenever Node.js detects an exceptional logic violation that should never occur. These are raised typically by the assert module.
// Throws with a ReferenceError because z is undefined
try {
const m = 1;
const n = m + z;
} catch (err) {
// Handle the error here.
}
const fs = require('fs');
fs.readFile('a file that does not exist', (err, data) => {
if (err) {
console.error('There was an error reading the file!', err);
return;
}
// Otherwise handle the data
});
const net = require('net');
const connection = net.connect('localhost');
// Adding an 'error' event handler to a stream:
connection.on('error', (err) => {
// If the connection is reset by the server, or if it can't
// connect at all, or on any sort of error encountered by
// the connection, the error will be sent here.
console.error(err);
});
connection.pipe(process.stdout);
const EventEmitter = require('events');
const ee = new EventEmitter();
setImmediate(() => {
// This will crash the process because no 'error' event
// handler has been added.
ee.emit('error', new Error('This will crash'));
});
const fs = require('fs');
function nodeStyleCallback(err, data) {
if (err) {
console.error('There was an error', err);
return;
}
console.log(data);
}
fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback);
fs.readFile('/some/file/that/does-exist', nodeStyleCallback)
// THIS WILL NOT WORK:
const fs = require('fs');
try {
fs.readFile('/some/file/that/does-not-exist', (err, data) => {
// mistaken assumption: throwing here...
if (err) {
throw err;
}
});
} catch(err) {
// This will not catch the throw!
console.log(err);
}
// Error
let error = new Error('message');
Error.captureStackTrace(targetObject, constructorOpt);
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack // similar to `new Error().stack`
function MyError() {
Error.captureStackTrace(this, MyError);
}
// Without passing MyError to captureStackTrace, the MyError
// frame would show up in the .stack property. By passing
// the constructor, we omit that frame and all frames above it.
new MyError().stack
Error.stackTraceLimit
error.message
const error = new Error('The message');
console.log(error.message);
// Prints: The message
error.stack
Error: Things keep happening!
at /home/gbusey/file.js:525:2
at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)
at Actor.<anonymous> (/home/gbusey/actors.js:400:8)
at increaseSynergy (/home/gbusey/actors.js:701:6)
const cheetahify = require('./native-binding.node');
function makeFaster() {
// cheetahify *synchronously* calls speedy.
cheetahify(function speedy() {
throw new Error('oh no!');
});
}
makeFaster(); // will throw:
// /home/gbusey/file.js:6
// throw new Error('oh no!');
// ^
// Error: oh no!
// at speedy (/home/gbusey/file.js:6:11)
// at makeFaster (/home/gbusey/file.js:5:3)
// at Object.<anonymous> (/home/gbusey/file.js:10:1)
// at Module._compile (module.js:456:26)
// at Object.Module._extensions..js (module.js:474:10)
// at Module.load (module.js:356:32)
// at Function.Module._load (module.js:312:12)
// at Function.Module.runMain (module.js:497:10)
// at startup (node.js:119:16)
// at node.js:906:3
// RangeError
require('net').connect(-1);
// throws RangeError, port should be > 0 && < 65536
// ReferenceError
doesNotExist;
// throws ReferenceError, doesNotExist is not a variable in this program.
const assert = require('assert');
try {
doesNotExist;
} catch(err) {
assert(err.arguments[0], 'doesNotExist');
}
// SyntaxError
try {
require('vm').runInThisContext('binary ! isNotOk');
} catch(err) {
// err will be a SyntaxError
}
// TypeError
require('url').parse(() => { });
// throws TypeError, since it expected a string
// System Error
error.code
error.errno
error.syscall
// Common System Errors
- EACCES (Permission denied): An attempt was made to access a file in a way forbidden by its file access permissions.
- EADDRINUSE (Address already in use): An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.
- ECONNREFUSED (Connection refused): No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host.
- ECONNRESET (Connection reset by peer): A connection was forcibly closed by a peer. This normally results from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered via the http and net modules.
- EEXIST (File exists): An existing file was the target of an operation that required that the target not exist.
- EISDIR (Is a directory): An operation expected a file, but the given pathname was a directory.
- EMFILE (Too many open files in system): Maximum number of file descriptors allowable on the system has been reached, and requests for another descriptor cannot be fulfilled until at least one has been closed. This is encountered when opening many files at once in parallel, especially on systems (in particular, OS X) where there is a low file descriptor limit for processes. To remedy a low limit, run ulimit -n 2048 in the same shell that will run the Node.js process.
- ENOENT (No such file or directory): Commonly raised by fs operations to indicate that a component of the specified pathname does not exist -- no entity (file or directory) could be found by the given path.
- ENOTDIR (Not a directory): A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs.readdir.
- ENOTEMPTY (Directory not empty): A directory with entries was the target of an operation that requires an empty directory -- usually fs.unlink.
- EPERM (Operation not permitted): An attempt was made to perform an operation that requires elevated privileges.
- EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no process to read the data. Commonly encountered at the net and http layers, indicative that the remote side of the stream being written to has been closed.
- ETIMEDOUT (Operation timed out): A connect or send request failed because the connected party did not properly respond after a period of time. Usually encountered by http or net -- often a sign that a socket.end() was not properly called.
Events
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', function () {
console.log('an event occurred!');
});
myEmitter.emit('event');
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this);
// Prints:
// a b MyEmitter {
// domain: null,
// _events: { event: [Function] },
// _eventsCount: 1,
// _maxListeners: undefined }
});
myEmitter.emit('event', 'a', 'b');
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');
const myEmitter = new MyEmitter();
var m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2
const myEmitter = new MyEmitter();
var m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Ignored
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Throws and crashes Node.js
const myEmitter = new MyEmitter();
process.on('uncaughtException', (err) => {
console.log('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.log('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error
// EventEmitter
const EventEmitter = require('events');
// Events
'newListener'
const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insert a new listener in front
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// A
'removeListener'
myEmitter.on('removeListener', funciton (eventName, listener) {});
EventEmitter.listenerCount(emitter, eventName); // deprecated
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(EventEmitter.listenerCount(myEmitter, 'event'));
// Prints: 2
EventEmitter.defaultMaxListeners
emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
// do stuff
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});
emitter.addListener('eventName', function () {});
emitter.emit('eventName', arg1, arg2, ...);
let eventNames = emitter.eventNames();
const EventEmitter = require('events');
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Prints [ 'foo', 'bar', Symbol(symbol) ]
let maxListeners = emitter.getMaxListeners();
emitter.listenerCount('eventName');
emitter.listeners('eventName');
server.on('connection', (stream) => {
console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
// Prints: [ [Function] ]
emitter.on('eventName', function () {});
server.on('connection', (stream) => {
console.log('someone connected!');
});
emitter.once('eventName', function () {});
server.once('connection', (stream) => {
console.log('Ah, we have our first user!');
});
emitter.prependListener('eventName', function () {});
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
emitter.prependOnceListener('eventName', function () {});
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
emitter.removeAllListeners('eventName');
emitter.removeListener('eventName', function () {});
var callback = (stream) => {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
const myEmitter = new MyEmitter();
var callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
var callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA removes listener callbackB but it will still be called.
// Internal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
// A
// B
// callbackB is now removed.
// Internal listener array [callbackA]
myEmitter.emit('event');
// Prints:
// A
emitter.setMaxListeners(15);
File System
const fs = require('fs');
fs.unlink('/tmp/hello', function (err) {
if (err) {throw err;}
console.log('successfully deleted /tmp/hello');
});
const fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
});
// fs.FSWatcher
let watcher = fs.watch();
watcher.on('change', function () {});
watcher.on('error', function () {});
// Example when handled through fs.watch listener
fs.watch('./tmp', {encoding: 'buffer'}, function (eventType, filename) {
if (filename) {
console.log(filename);
// Prints: <Buffer ...>
}
});
watcher.close();
// fs.ReadStream
let readStream = fs.readStream();
readStream.on('open', function () {});
readStream.on('close', function () {});
let bytesRead = readStream.bytesRead;
let path = readStream.path;
// fs.Stats
fs.stats('file.txt', function (error, stats) {
if (stats.isFile()) {
} else if (stats.isDirectory()) {
} else if (stats.isBlockDevice()) {
} else if (stats.isCharacterDevice()) {
} else if (stats.isSymbolicLink()) {
} else if (stats.isFIFO()) {
} else if (stats.isSocket()) {
}
console.log(stats);
/* Prints:
{
dev: 2114,
ino: 48064969,
mode: 33188,
nlink: 1,
uid: 85,
gid: 100,
rdev: 0,
size: 527,
blksize: 4096,
blocks: 8,
atime: Mon, 10 Oct 2011 23:24:11 GMT,
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
ctime: Mon, 10 Oct 2011 23:24:11 GMT,
birthtime: Mon, 10 Oct 2011 23:24:11 GMT
}
*/
});
// fs.WriteStream
let writeStream = fs.writeStream();
writeStream.on('open', function () {});
writeStream.on('close', function () {});
let bytesWritten = writeStream.bytesWritten;
let path = writeStream.path;
fs.access('path/to/file.txt', fs.constants.R_OK | fs.constants.W_OK, function (error) {
console.log(error ? 'no access!' : 'can read/write');
});
// write (NOT RECOMMENDED)
fs.access('myfile', (err) => {
if (!err) {
console.error('myfile already exists');
return;
}
fs.open('myfile', 'wx', (err, fd) => {
if (err) throw err;
writeMyData(fd);
});
});
// write (RECOMMENDED)
fs.open('myfile', 'wx', (err, fd) => {
if (err) {
if (err.code === "EEXIST") {
console.error('myfile already exists');
return;
} else {
throw err;
}
}
writeMyData(fd);
});
// read (NOT RECOMMENDED)
fs.access('myfile', (err) => {
if (err) {
if (err.code === "ENOENT") {
console.error('myfile does not exist');
return;
} else {
throw err;
}
}
fs.open('myfile', 'r', (err, fd) => {
if (err) throw err;
readMyData(fd);
});
});
// read (RECOMMENDED)
fs.open('myfile', 'r', (err, fd) => {
if (err) {
if (err.code === "ENOENT") {
console.error('myfile does not exist');
return;
} else {
throw err;
}
}
readMyData(fd);
});
fs.accessSync('path/to/file.txt', fs.constants.R_OK | fs.constants.W_OK);
fs.appendFile('message.txt', 'data to append', 'utf8', function (error) {
if (error) {throw error;}
console.log('The "data to append" was appended to file!');
});
fs.appendFileSync('message.txt', 'data to append', 'utf8');
fs.chmod('path/to/file.txt', 777, function () {});
fs.chmodSync('path/to/file.txt', 777);
fs.chown('path/to/file.txt', uid, gid, function () {});
fs.chownSync(path, uid, gid);
fs.close(openedFileId, function () {});
fs.closeSync(openedFileId);
fs.constants;
let readStream = fs.createReadStream(
'sample.txt'
, {
flags: 'r'
, encoding: null
, fd: null
, mode: 0o666
, autoClose: true
, start: 90
, end: 99
}
);
let writeStream = fs.createWriteStream(
'sample.txt'
, {
flags: 'w'
, defaultEncoding: 'utf8'
, fd: null
, mode: 0o666
, autoClose: true
, start: 15
}
);
fs.exists('/etc/passwd', function (exists) { // deprecated
console.log(exists ? 'it\'s there' : 'no passwd!');
});
// write (NOT RECOMMENDED)
fs.exists('myfile', (exists) => {
if (exists) {
console.error('myfile already exists');
} else {
fs.open('myfile', 'wx', (err, fd) => {
if (err) throw err;
writeMyData(fd);
});
}
});
// write (RECOMMENDED)
fs.open('myfile', 'wx', (err, fd) => {
if (err) {
if (err.code === "EEXIST") {
console.error('myfile already exists');
return;
} else {
throw err;
}
}
writeMyData(fd);
});
// read (NOT RECOMMENDED)
fs.exists('myfile', (exists) => {
if (exists) {
fs.open('myfile', 'r', (err, fd) => {
readMyData(fd);
});
} else {
console.error('myfile does not exist');
}
});
// read (RECOMMENDED)
fs.open('myfile', 'r', (err, fd) => {
if (err) {
if (err.code === "ENOENT") {
console.error('myfile does not exist');
return;
} else {
throw err;
}
} else {
readMyData(fd);
}
});
fs.existsSync('path/to/file.txt'); // deprecated
fs.fchmod(fileId, 777, function () {});
fs.fchmodSync(fileId, 777);
fs.fchown(fileId, uid, gid, function () {});
fs.fchownSync(fileId, uid, gid);
fs.fdatasync(fileId, function () {});
fs.fdatasyncSync(fileId);
fs.fstat(fileId, function () {});
fs.fstatSync(fileId);
fs.fsync(fileId, function () {});
fs.fsyncSync(fileId);
fs.ftruncate(fileId, 20, function () {});
console.log(fs.readFileSync('temp.txt', 'utf8'));
// prints Node.js
// get the file descriptor of the file to be truncated
const fd = fs.openSync('temp.txt', 'r+');
// truncate the file to first four bytes
fs.ftruncate(fd, 4, (err) => {
assert.ifError(err);
console.log(fs.readFileSync('temp.txt', 'utf8'));
});
// prints Node
console.log(fs.readFileSync('temp.txt', 'utf-8'));
// prints Node.js
// get the file descriptor of the file to be truncated
const fd = fs.openSync('temp.txt', 'r+');
// truncate the file to 10 bytes, whereas the actual size is 7 bytes
fs.ftruncate(fd, 10, (err) => {
assert.ifError(!err);
console.log(fs.readFileSync('temp.txt'));
});
// prints <Buffer 4e 6f 64 65 2e 6a 73 00 00 00>
// ('Node.js\0\0\0' in UTF8)
fs.ftruncateSync(fileId, 20);
fs.futimes(fileId, atime, mtime, function () {});
fs.futimesSync(fileId, atime, mtime);
fs.lchmod('path/to/file.txt', mode, function () {});
fs.lchmodSync('path/to/file.txt', mode);
fs.lchown('path/to/file.txt', uid, gid, function () {});
fs.lchownSync('path/to/file.txt', uid, gid);
fs.link('path/to/src/file.txt', 'path/to/dstfile.txt', function () {});
fs.linkSync('path/to/src/file.txt', 'path/to/dstfile.txt');
fs.lstat('path/to/file.txt', function () {});
fs.lstatSync('path/to/file.txt');
fs.mkdir('path/to/directory', 777, function () {});
fs.mkdirSync('path/to/directory', 777);
fs.mkdtemp(prefix, options, function () {});
fs.mkdtemp('/tmp/foo-', function (error, folder) {
if (error) {throw error;}
console.log(folder);
// Prints: /tmp/foo-itXde2
});
// The parent directory for the new temporary directory
const tmpDir = '/tmp';
// This method is *INCORRECT*:
fs.mkdtemp(tmpDir, (err, folder) => {
if (err) throw err;
console.log(folder);
// Will print something similar to `/tmpabc123`.
// Note that a new temporary directory is created
// at the file system root rather than *within*
// the /tmp directory.
});
// This method is *CORRECT*:
const path = require('path');
fs.mkdtemp(tmpDir + path.sep, (err, folder) => {
if (err) throw err;
console.log(folder);
// Will print something similar to `/tmp/abc123`.
// A new temporary directory is created within
// the /tmp directory.
});
fs.mkdtempSync(prefix, options);
fs.open('path/to/file.txt', 'a+', 0666, function (err, fileId) {});
// OS X and Linux
fs.open('<directory>', 'a+', function (err, fd) {
// => [Error: EISDIR: illegal operation on a directory, open <directory>]
});
// Windows and FreeBSD
fs.open('<directory>', 'a+', function (err, fd) {
// => null, <fd>
});
fs.openSync('path/to/file.txt', 'a+', 0666);
fs.read(fileId, buffer, offset, length, position, function (error, bytesRead, buffer) {});
fs.readdir('path/to/directory', {encoding: 'utf8'}, function (error, files) {});
fs.readdirSync('path/to/directory', {encoding: 'utf8'});
fs.readFile('path/to/file.txt', {encoding: 'utf8', flags: 'r'}, function (error, data) {
if (error) {throw error;}
console.log(data);
});
fs.readFileSync('path/to/file.txt', {encoding: 'utf8', flags: 'r'});
fs.readlink('path/to/file.txt', {encoding: 'utf8'}, function (error, linkString) {});
fs.readlinkSync('path/to/file.txt', {encoding: 'utf8'});
fs.readSync(fd, buffer, offset, length, position);
fs.realpath('path/to/file.txt', {encoding: 'utf8'}, function (error, resolvedPath) {});
fs.realpathSync('path/to/file.txt', {encoding: 'utf8'});
fs.rename('old/path/to/file.txt', 'new/path/to/file.txt', function (error) {});
fs.renameSync('old/path/to/file.txt', 'new/path/to/file.txt');
fs.rmdir('path/to/directory', function (error) {});
fs.rmdirSync('path/to/directory');
fs.stat('path/to/file.txt', function (error, stats) {});
fs.statSync('path/to/file.txt');
fs.symlink(target, path, type, function () {});
fs.symlink('./foo', './new-port');
fs.symlinkSync(target, path, type);
fs.truncate('path/to/file.txt', 15, function (error) {});
fs.truncateSync('path/to/file.txt', 15);
fs.unlink('path/to/file.txt', function (error) {});
fs.unlinkSync('path/to/file.txt');
fs.unwatchFile('filename', listener);
fs.utimes('path/to/file.txt', atime, mtime, function () {});
fs.utimesSync('path/to/file.txt', atime, mtime);
fs.watch(filename, {persistent: true, recursive: true, encoding: 'utf8'}, function (eventType, filename) {});
fs.watch('somedir', function (eventType, filename) {
console.log('event type is: ' + eventType);
if (filename) {
console.log('filename provided: ' + filename);
} else {
console.log('filename not provided');
}
});
fs.watchFile(filename, {persistent: true, interval: 100}, function (curr, prev) {});
fs.watchFile('message.text', function (curr, prev) {
console.log('the current mtime is: ' + curr.mtime);
console.log('the previous mtime was: ' + prev.mtime);
});
fs.write(fileId, buffer, offset, length, position, function (error, written, buffer) {});
fs.write(fileId, 'data', position, 'utf8', function (error, written, string) {});
fs.writeFile('path/to/file.txt', 'some text', {encoding: 'utf8', mode: 0o666, flag: 'w'}, function (error) {});
fs.writeFile('message.txt', 'Hello Node.js', function (error) {
if (error) {throw error;}
console.log('It\'s saved!');
});
fs.writeFileSync('message.txt', 'Hello Node.js', {encoding: 'utf8', mode: 0o666, flag: 'w'});
fs.writeSync(fileId, buffer, offset, length, position);
fs.writeSync(fileId, data, position, 'utf8');
FS Constants
F_OK - Flag indicating that the file is visible to the calling process.
R_OK - Flag indicating that the file can be read by the calling process.
W_OK - Flag indicating that the file can be written by the calling process.
X_OK - Flag indicating that the file can be executed by the calling process.
Global
global
Buffer
__dirname // console.log(__dirname); // /Users/mjr
__filename // console.log(__filename); // /Users/mjr/example.js
console.log('message');
process.nextTick(function () {});
setTimeout(function () {}, 5000, arg, ...);
clearTimeout(timeoutId);
setInterval(function () {}, 5000, arg, ...);
clearInterval(intervalId);
setImmediate(function () {}, arg, ...);
clearImmediate(immediateId);
const lib = require('./path/to/lib.js');
exports.value = value;
module.exports = function () {};
const fileName = require.resolve('./path/to/file.txt');
require.cache;
require.extensions['.sjs'] = require.extensions['.js']; // decprecated
HTTP
http.get({
hostname: 'localhost',
port: 80,
path: '/',
agent: false // create a new agent just for this one request
}, (response) => {
// Do stuff with response
}).on('socket', (socket) => {
socket.emit('agentRemove');
});
// http.Agent
const http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);
agent.createConnection(options, function (error, stream) {});
agent.destroy();
agent.freeSockets;
agent.getName(options); // returns host:port:localAddress
agent.maxFreeSockets = 256;
agent.maxSockets;
agent.requests;
agent.sockets;
// http.ClientRequest
request.on('abort', function () {});
request.on('aborted', function () {});
request.on('checkExpectation', function (request, response) {});
request.on('connect', function (response, socket, head) {});
const http = require('http');
const net = require('net');
const url = require('url');
// Create an HTTP tunneling proxy
var proxy = http.createServer( (req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('okay');
});
proxy.on('connect', (req, cltSocket, head) => {
// connect to an origin server
var srvUrl = url.parse(`http://${req.url}`);
var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node.js-Proxy\r\n' +
'\r\n');
srvSocket.write(head);
srvSocket.pipe(cltSocket);
cltSocket.pipe(srvSocket);
});
});
// now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {
// make a request to a tunneling proxy
var options = {
port: 1337,
hostname: '127.0.0.1',
method: 'CONNECT',
path: 'www.google.com:80'
};
var req = http.request(options);
req.end();
req.on('connect', (res, socket, head) => {
console.log('got connected!');
// make a request over an HTTP tunnel
socket.write('GET / HTTP/1.1\r\n' +
'Host: www.google.com:80\r\n' +
'Connection: close\r\n' +
'\r\n');
socket.on('data', (chunk) => {
console.log(chunk.toString());
});
socket.on('end', () => {
proxy.close();
});
});
});
request.on('continue', function () {});
request.on('response', function (response) {});
request.on('socket', function (socket) {});
request.on('upgrade', function (response, socket, head) {});
const http = require('http');
// Create an HTTP server
var srv = http.createServer( (req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('okay');
});
srv.on('upgrade', (req, socket, head) => {
socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
socket.pipe(socket); // echo back
});
// now that server is running
srv.listen(1337, '127.0.0.1', () => {
// make a request
var options = {
port: 1337,
hostname: '127.0.0.1',
headers: {
'Connection': 'Upgrade',
'Upgrade': 'websocket'
}
};
var req = http.request(options);
req.end();
req.on('upgrade', (res, socket, upgradeHead) => {
console.log('got upgraded!');
socket.end();
process.exit(0);
});
});
request.abort();
request.end('some text', 'utf8', function () {});
request.flushHeaders();
request.setNoDelay(noDelay);
request.setSocketKeepAlive(enable, initialDelay);
request.setTimeout(1500, function () {});
request.write('some text', 'utf8', function () {});
// http.Server
Events
server.on('checkContinue', function (request, responset) {});
server.on('clientError', function (exception, socket) {});
const http = require('http');
const server = http.createServer((req, res) => {
res.end();
});
server.on('clientError', (error, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);
server.on('close', function () {});
server.on('connect', function (request, socket, head) {});
server.on('connection', function (socket) {});
server.on('request', function (request, response) {});
server.on('upgrade', function (request, socket, head) {});
server.close(function () {});
server.listen(handle, function () {});
server.listen('127.0.0.1', function () {});
server.listen(80, '127.0.0.1', backlog, function () {});
if (server.listening) {}
server.maxHeadersCount = 1000 ;
server.setTimeout(1500, function () {});
server.timeout = 120000;
// http.ServerResponse
Events
response.on('close', function () {});
response.on('finish', function () {});
response.addTrailers(headers);
response.writeHead(200, { 'Content-Type': 'text/plain', 'Trailer': 'Content-MD5' });
response.write('fileData');
response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
response.end();
response.end('data', 'utf8', function () {});
if (response.finished) {}
var contentType = response.getHeader('content-type');
if (response.headersSent) {}
response.removeHeader('Content-Encoding');
if (response.sendDate) {}
response.setHeader('Content-Type', 'text/html');
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
// returns content-type = text/plain
const server = http.createServer(function (request, response) {
response.setHeader('Content-Type', 'text/html');
response.setHeader('X-Foo', 'bar');
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('ok');
});
response.setTimeout(1500, function () {});
response.statusCode = 404;
response.statusMessage = 'Not found';
response.write('chunk', 'utf8', function () {});
response.writeContinue(); // sends a HTTP/1.1 100 Continue message to the client
response.writeHead(200, 'OK', 'Content-Length': Buffer.byteLength('hello'), 'Content-Type': 'text/plain' });
// returns content-type = text/plain
const server = http.createServer(function (request, response) {
response.setHeader('Content-Type', 'text/html');
response.setHeader('X-Foo', 'bar');
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('ok');
});
// http.IncomingMessage
Events
message.on('aborted', function () {});
message.on('close', function () {});
message.destroy(error);
message.headers;
console.log(request.headers);
// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
message.httpVersion;
message.method;
message.rawHeaders;
console.log(request.rawHeaders);
// Prints something like:
//
// [ 'user-agent',
// 'this is invalid because there can be only one',
// 'User-Agent',
// 'curl/7.22.0',
// 'Host',
// '127.0.0.1:8000',
// 'ACCEPT',
// '*/*' ]
message.rawTrailers;
message.setTimeout(1500, function () {});
message.statusCode = 404;
message.statusMessage = 'Not found';
message.socket;
message.trailers;
message.url;
console.log(message.url);
// GET /status?name=ryan HTTP/1.1\r\n
// Accept: text/plain\r\n
// \r\n
// request.url will be:
// '/status?name=ryan'
// require('url').parse('/status?name=ryan'); // <---
// {
// href: '/status?name=ryan',
// search: '?name=ryan',
// query: 'name=ryan', // <---
// pathname: '/status'
// }
// require('url').parse('/status?name=ryan', true); // <---
// {
// href: '/status?name=ryan',
// search: '?name=ryan',
// query: {name: 'ryan'}, // <---
// pathname: '/status'
// }
http.METHODS;
http.STATUS_CODES;
http.createClient(80, '127.0.0.1'); // deprecated
http.createServer(function (request, response) {});
http.get(options, function () {});
http.get('http://www.google.com/index.html', function (response) {
console.log('Got response: ' + response.statusCode);
// consume response body
response.resume();
}).on('error', function (error) {
console.log('Got error: ' + error.message);
});
http.globalAgent
http.request(options, function (response) {});
var postData = querystring.stringify({'msg' : 'Hello World!'});
var options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
var req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
HTTPS
server.setTimeout(1500, function () {});
server.timeout
https.createServer(options, function (request, response) {});
// curl -k https://localhost:8000/
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
const https = require('https');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('server.pfx')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
server.close(function () {});
server.listen(handle, function () {});
server.listen(path, function () {});
server.listen(80, '127.0.0.1', backlog, function () {});
https.get(options, function () {});
const https = require('https');
https.get('https://encrypted.google.com/', (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (data) => {
process.stdout.write(data);
});
}).on('error', (error) => {
console.error(error);
});
https.globalAgent
https.request(options, function () {});
const https = require('https');
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET'
};
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.end();
req.on('error', (e) => {
console.error(e);
});
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
options.agent = new https.Agent(options);
var req = https.request(options, (res) => {
...
});
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
agent: false
};
var req = https.request(options, (res) => {
...
});
Modules
// Require
const lib = require('./lib.js');
lin.square(4);
exports.circle = funciton () {};
rexports.cube = function () {};
module.exports = function () {
return {
area: function () {}
}
};
Определение загружен ли модуль внутри другого модуля или его код выполняется отдельно:
if (require.main === module) {
console.log('standloane module');
} else {
console.log('this module is loaded by require('./foo');');
}
const moduleEntryPoint = require.main.filename;
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"
LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text. STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon. STOP
LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
a. LOAD_AS_FILE(DIR/X)
b. LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
a. if PARTS[I] = "node_modules" CONTINUE
c. DIR = path join(PARTS[0 .. I] + "node_modules")
b. DIRS = DIRS + DIR
c. let I = I - 1
5. return DIRS
// Module.exports
The module wrapper
(function (exports, require, module, __filename, __dirname) {
// Your module code actually lives in here
});
module = {};
module.children = [];
module.exports = {};
var exports = module.exports;
module.filename = "filename";
module.id= "id";
module.loaded = true;
module.parent = {};
var lib = module.require('id');
Net
var net = require('net');
var server = net.Server();
Events:
server.on('close', function () {});
server.on('connection', function () {});
server.on('error', function () {});
server.on('listening', function () {});
var address = server.address();
var server = net.createServer(function(socket) {
socket.end('goodbye');
}).on('error', function (error){throw error;});
// grab a random port.
server.listen(function () {
console.log('opened server on', server.address());
});
// Don't call server.address() until the 'listening' event has been emitted.
server.close(function () {});
server.connections; // deprecated
server.getConnections(function (error, count) {console.log('Connections number: ' + count);});
server.listen(handle, backlog, callback);
server.listen(options, callback);
server.listen(path, backlog, callback);
server.listen(port, hostname, backlog, callback);
server.listen({
host: 'localhost',
port: 80,
exclusive: true
});
net.createServer().listen(path.join('\\\\?\\pipe', process.cwd(), 'myctl'))
server.on('error', function (error) {
if (error.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
if (server.listening) {}
server.maxConnections;
server.ref();
server.unref();
// net.Socket
var socket = new net.Socket({
fd: null,
allowHalfOpen: false,
readable: false,
writable: false
});
Events
socket.on('close', function () {});
socket.on('connect', function () {});
socket.on('data', function (data) {});
socket.on('drain', function () {});
socket.on('end', function () {});
socket.on('error', function () {});
socket.on('lookup', function () {});
socket.on('timeout', function () {});
var address = socket.address(); // return {port: 12346, family: 'IPv4', address: '127.0.0.1'}
socket.bufferSize;
socket.bytesRead;
socket.bytesWritten;
socket.connect(options, connectListener);
socket.connect(path, connectListener);
socket.connect(port, host, connectListener);
if (socket.connecting) {}
socket.destroy(exception);
if (socket.destroyed) {}
socket.end(data, 'utf8');
socket.localAddress; // '192.168.1.1'
socket.localPort // 80
socket.pause();
socket.ref();
socket.remoteAddress // '74.125.127.100'
socket.remoteFamily // 'IPv6'
socket.remotePort // 80
socket.resume();
socket.setEncoding('utf8');
socket.setKeepAlive(enable, initialDelay);
socket.setNoDelay(noDelay);
socket.setTimeout(1500, function () {});
socket.unref();
socket.write(data, 'utf8', function () {});
net.connect(options, connectListener);
net.connect(path, connectListener);
net.connect(port, host, connectListener);
const net = require('net');
const client = net.connect({port: 8124}, () => {
// 'connect' listener
console.log('connected to server!');
client.write('world!\r\n');
});
client.on('data', (data) => {
console.log(data.toString());
client.end();
});
client.on('end', () => {
console.log('disconnected from server');
});
net.createConnection(options, connectListener);
net.createConnection(path, connectListener);
net.createConnection(port, host, connectListener);
const net = require('net');
const client = net.createConnection({port: 8124}, () => {
//'connect' listener
console.log('connected to server!');
client.write('world!\r\n');
});
client.on('data', (data) => {
console.log(data.toString());
client.end();
});
client.on('end', () => {
console.log('disconnected from server');
});
net.createServer({
allowHalfOpen: false,
pauseOnConnect: false
}, connectionListener);
const net = require('net');
const server = net.createServer((c) => {
// 'connection' listener
console.log('client connected');
c.on('end', () => {console.log('client disconnected');});
c.write('hello\r\n');
c.pipe(c);
});
server.on('error', (err) => {throw err;});
server.listen(8124, () => {console.log('server bound');});
telnet localhost 8124
if (net.isIP('input')) {}
if (net.isIPv4('input')) {}
if (net.isIPv6('input')) {}
OS
const os = require('os');
os.EOL // \n on POSIX, \r\n on Windows
os.arch(); // 'arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc'
os.constants
os.cpus();
/* Prints
[
{
model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz',
speed: 2926,
times: {
user: 252020,
nice: 0,
sys: 30340,
idle: 1070356870,
irq: 0
}
}
]
*/
os.cpus().length;
os.endianness(); // 'BE' for big endian and 'LE' for little endian.
os.freemem(); // amount of free system memory in bytes
os.homedir();
os.hostname(); // hostname of the operating system
os.loadavg(); // [0, 0, 0] - minute load averages
os.networkInterfaces();
/* Prints
{
lo: [
{
address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true
},
],
eth0: [
{
address: '192.168.1.108',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '01:02:03:0a:0b:0c',
internal: false
}
]
}
*/
os.platform(); // 'aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'
os.release();
os.tmpdir();
os.totalmem();
os.type(); // Linux' on Linux, 'Darwin' on OS X and 'Windows_NT' on Window
os.uptime();
os.userInfo({encoding: 'utf8'});
Path
const path = require('path');
path.basename(path, ext);
path.basename('/foo/bar/baz/asdf/quux.html') // returns 'quux.html'
path.basename('/foo/bar/baz/asdf/quux.html', '.html') // returns 'quux'
On POSIX: path.basename('C:\\temp\\myfile.html'); // returns 'C:\temp\myfile.html'
On Windows: path.basename('C:\\temp\\myfile.html'); // returns 'myfile.html'
On POSIX and Windows: path.win32.basename('C:\\temp\\myfile.html'); // returns 'myfile.html'
On POSIX and Windows: path.posix.basename('/tmp/myfile.html'); // returns 'myfile.html'
path.delimiter // ; for Windows and : for POSIX
For example, on POSIX: console.log(process.env.PATH) // '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'
process.env.PATH.split(path.delimiter) // returns ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']
On Windows: console.log(process.env.PATH) // 'C:\Windows\system32;C:\Windows;C:\Program Files\node\'
process.env.PATH.split(path.delimiter) // returns ['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\']
path.dirname(path);
path.dirname('/foo/bar/baz/asdf/quux') // returns '/foo/bar/baz/asdf'
path.extname(path);
path.extname('index.html') // returns '.html'
path.extname('index.coffee.md') // returns '.md'
path.extname('index.') // returns '.'
path.extname('index') // returns ''
path.extname('.index') // returns ''
path.format(pathObject);
on POSIX:
// If `dir` and `base` are provided,
// `${dir}${path.sep}${base}`
// will be returned.
path.format({dir: '/home/user/dir',base: 'file.txt'});
// returns '/home/user/dir/file.txt'
// `root` will be used if `dir` is not specified.
// If only `root` is provided or `dir` is equal to `root` then the
// platform separator will not be included.
path.format({root: '/',base: 'file.txt'});
// returns '/file.txt'
// `name` + `ext` will be used if `base` is not specified.
path.format({root: '/',name: 'file',ext: '.txt'});
// returns '/file.txt'
// `base` will be returned if `dir` or `root` are not provided.
path.format({base: 'file.txt'});
// returns 'file.txt'
On Windows:
path.format({
root : "C:\\",
dir : "C:\\path\\dir",
base : "file.txt",
ext : ".txt",
name : "file"
});
// returns 'C:\\path\\dir\\file.txt'
path.isAbsolute(path);
on POSIX:
path.isAbsolute('/foo/bar') // true
path.isAbsolute('/baz/..') // true
path.isAbsolute('qux/') // false
path.isAbsolute('.') // false
On Windows:
path.isAbsolute('//server') // true
path.isAbsolute('\\\\server') // true
path.isAbsolute('C:/foo/..') // true
path.isAbsolute('C:\\foo\\..') // true
path.isAbsolute('bar\\baz') // false
path.isAbsolute('bar/baz') // false
path.isAbsolute('.') // false
path.join(path, ...);
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..') // returns '/foo/bar/baz/asdf'
path.join('foo', {}, 'bar') // throws TypeError: Arguments to path.join must be strings
path.normalize(path);
on POSIX: path.normalize('/foo/bar//baz/asdf/quux/..') // returns '/foo/bar/baz/asdf'
On Windows: path.normalize('C:\\temp\\\\foo\\bar\\..\\'); // returns 'C:\\temp\\foo\\'
path.parse(path);
on POSIX: path.parse('/home/user/dir/file.txt')
// returns
// {
// root : "/",
// dir : "/home/user/dir",
// base : "file.txt",
// ext : ".txt",
// name : "file"
// }
┌──────────────────────┬────────────┐
│ dir │ base │
├──────┬ ├──────┬─────┤
│ root │ │ name │ ext │
" / home/user/dir / file .txt "
└──────┴──────────────┴──────┴─────┘
(all spaces in the "" line should be ignored -- they are purely for formatting)
On Windows: path.parse('C:\\path\\dir\\file.txt')
// returns
// {
// root : "C:\\",
// dir : "C:\\path\\dir",
// base : "file.txt",
// ext : ".txt",
// name : "file"
// }
┌──────────────────────┬────────────┐
│ di │ base │
├──────┬ ├──────┬─────┤
│ root │ │ name │ ext │
" C:\ path\dir \ file .txt "
└──────┴──────────────┴──────┴─────┘
(all spaces in the "" line should be ignored -- they are purely for formatting)
path.posix
path.relative(from, to);
on POSIX: path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb') // returns '../../impl/bbb'
on Windows: path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb') // returns '..\\..\\impl\\bbb'
path.resolve(path, ...);
path.resolve('/foo/bar', './baz') // returns '/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/') // returns '/tmp/file'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// if the current working directory is /home/myself/node,
// this returns '/home/myself/node/wwwroot/static_files/gif/image.gif'
path.sep // \ on Windows and / on POSIX
on POSIX: 'foo/bar/baz'.split(path.sep) // returns ['foo', 'bar', 'baz']
on Windows: 'foo\\bar\\baz'.split(path.sep) // returns ['foo', 'bar', 'baz']
path.win32 // On Windows, both the forward slash (/) and backward slash (\) characters are accepted as path delimiters;
// however, only the backward slash (\) will be used in return values.
Process
process.on('beforeExit', function () {});
process.on('disconnect', function () {});
process.on('exit', function (code) {console.log(`About to exit with code: ${code}`);});
process.on('message', function () {});
process.on('rejectionHandled', function () {});
process.on('uncaughtException', function (error) {fs.writeSync(1, `Caught exception: ${error}`);});
const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, p) => {unhandledRejections.set(p, reason);});
process.on('rejectionHandled', (p) => {unhandledRejections.delete(p);});
process.on('unhandledRejection', function (reason, p) {console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);});
process.on('warning', function (warning) {
console.warn(warning.name); // Print the warning name
console.warn(warning.message); // Print the warning message
console.warn(warning.stack); // Print the stack trace
});
Emitting custom warnings
// Emit a warning using a string...
process.emitWarning('Something happened!'); // Prints: (node 12345) Warning: Something happened!
// Emit a warning using an object...
process.emitWarning('Something Happened!', 'CustomWarning'); // Prints: (node 12345) CustomWarning: Something happened!
// Emit a warning using a custom Error object...
class CustomWarning extends Error {
constructor(message) {
super(message);
this.name = 'CustomWarning';
Error.captureStackTrace(this, CustomWarning);
}
}
const myWarning = new CustomWarning('Something happened!');
process.emitWarning(myWarning); // Prints: (node 12345) CustomWarning: Something happened!
const err = new Error('This API is deprecated');
err.name = 'DeprecationWarning';
process.emitWarning(err);
Signal Events
// Begin reading from stdin so the process does not exit.
process.stdin.resume();
process.on('SIGINT', function () {console.log('Received SIGINT. Press Control-D to exit.');});
process.abort();
process.arch
console.log(`This processor architecture is ${process.arch}`);
process.argv
// print process.argv
process.argv.forEach(function (val, index) {
console.log(`${index}: ${val}`);
});
$ node process-2.js one two=three four
// Prints
/*
0: /usr/local/bin/node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four
9*/
process.argv0 // The process.argv0 property stores a read-only copy of the original value of argv[0] passed when Node.js starts
$ bash -c 'exec -a customArgv0 ./node'
> process.argv[0]
'/Volumes/code/external/node/out/Release/node'
> process.argv0
'customArgv0'
process.chdir(directory);
console.log(`Starting directory: ${process.cwd()}`);
try {
process.chdir('/tmp');
console.log(`New directory: ${process.cwd()}`);
}
catch (err) {
console.log(`chdir: ${err}`);
}
process.config
// Prints
/*
{
target_defaults:
{ cflags: [],
default_configuration: 'Release',
defines: [],
include_dirs: [],
libraries: [] },
variables:
{
host_arch: 'x64',
node_install_npm: 'true',
node_prefix: '',
node_shared_cares: 'false',
node_shared_http_parser: 'false',
node_shared_libuv: 'false',
node_shared_zlib: 'false',
node_use_dtrace: 'false',
node_use_openssl: 'true',
node_shared_openssl: 'false',
strict_aliasing: 'true',
target_arch: 'x64',
v8_use_snapshot: 'true'
}
}
*/
if (process.connected) {}
process.cpuUsage(previousValue);
const startUsage = process.cpuUsage(); // { user: 38579, system: 6986 }
// spin the CPU for 500 milliseconds
const now = Date.now();
while (Date.now() - now < 500);
console.log(process.cpuUsage(startUsage)); // { user: 514883, system: 11226 }
process.cwd();
console.log(`Current directory: ${process.cwd()}`);
process.disconnect();
process.env
// Prints
/*
{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}
*/
$ node -e 'process.env.foo = "bar"' && echo $foo
process.env.foo = 'bar';
console.log(process.env.foo);
process.env.test = null;
console.log(process.env.test); // => 'null'
process.env.test = undefined;
console.log(process.env.test); // => 'undefined'
process.env.TEST = 1;
delete process.env.TEST;
console.log(process.env.TEST); // => undefined
process.emitWarning(warning, name, ctor);
// Emit a warning using a string...
process.emitWarning('Something happened!'); // Emits: (node: 56338) Warning: Something happened!
// Emit a warning using a string and a name...
process.emitWarning('Something Happened!', 'CustomWarning'); // Emits: (node:56338) CustomWarning: Something Happened!
process.on('warning', function (warning) {
console.warn(warning.name);
console.warn(warning.message);
console.warn(warning.stack);
});
// Emit a warning using an Error object...
const myWarning = new Error('Warning! Something happened!');
myWarning.name = 'CustomWarning';
process.emitWarning(myWarning); // Emits: (node:56338) CustomWarning: Warning! Something Happened!
Avoiding duplicate warnings
var warned = false;
function emitMyWarning() {
if (!warned) {
process.emitWarning('Only warn once!');
warned = true;
}
}
emitMyWarning(); // Emits: (node: 56339) Warning: Only warn once!
emitMyWarning(); // Emits nothing
process.execArgv
$ node --harmony script.js --version
console.log(process.execArgv); // ['--harmony']
console.log(process.argv); ['/usr/local/bin/node', 'script.js', '--version']
process.execPath; // /usr/local/bin/node
process.exit(1);
if (process.exitCode === 1) {}
if (someConditionNotMet()) {
printUsageToStdout();
process.exitCode = 1;
}
process.getegid();
if (process.getegid) {
console.log(`Current gid: ${process.getegid()}`);
}
process.geteuid();
if (process.geteuid) {
console.log(`Current uid: ${process.geteuid()}`);
}
process.getgid();
if (process.getgid) {
console.log(`Current gid: ${process.getgid()}`);
}
process.getgroups();
process.getuid();
if (process.getuid) {
console.log(`Current uid: ${process.getuid()}`);
}
process.hrtime(time);
var time = process.hrtime(); // [ 1800216, 25 ]
setTimeout(function () {
var diff = process.hrtime(time); // [ 1, 552 ]
console.log(`Benchmark took ${diff[0] * 1e9 + diff[1]} nanoseconds`); // benchmark took 1000000527 nanoseconds
}, 1000);
process.initgroups(user, extra_group);
console.log(process.getgroups()); // [ 0 ]
process.initgroups('bnoordhuis', 1000); // switch user
console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ]
process.setgid(1000); // drop root gid
console.log(process.getgroups()); // [ 27, 30, 46, 1000 ]
process.kill(pid, signal);
process.on('SIGHUP', () => {
console.log('Got SIGHUP signal.');
});
setTimeout(() => {
console.log('Exiting.');
process.exit(0);
}, 100);
process.kill(process.pid, 'SIGHUP');
if (process.mainModule) {}
process.memoryUsage();
console.log(util.inspect(process.memoryUsage()));
process.nextTick(callback, arg, ...);
console.log('start');
process.nextTick(function () {
console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback
function MyThing(options) {
this.setupOptions(options);
process.nextTick(() => {this.startDoingStuff();});
}
var thing = new MyThing();
thing.getReadyForStuff();
// thing.startDoingStuff() gets called now, not before.
process.pid
console.log(`This process is pid ${process.pid}`);
process.platform // 'darwin', 'freebsd', 'linux', 'sunos', 'win32'
console.log(`This platform is ${process.platform}`);
process.release
process.send(message, sendHandle, options, callback);
process.setegid(id);
if (process.getegid && process.setegid) {
console.log(`Current gid: ${process.getegid()}`);
try {
process.setegid(501);
console.log(`New gid: ${process.getegid()}`);
}
catch (err) {
console.log(`Failed to set gid: ${err}`);
}
}
process.seteuid(id);
if (process.geteuid && process.seteuid) {
console.log(`Current uid: ${process.geteuid()}`);
try {
process.seteuid(501);
console.log(`New uid: ${process.geteuid()}`);
}
catch (err) {
console.log(`Failed to set uid: ${err}`);
}
}
process.setgid(id);
if (process.getgid && process.setgid) {
console.log(`Current gid: ${process.getgid()}`);
try {
process.setgid(501);
console.log(`New gid: ${process.getgid()}`);
}
catch (err) {
console.log(`Failed to set gid: ${err}`);
}
}
process.setgroups(groups);
process.setuid(id);
if (process.getuid && process.setuid) {
console.log(`Current uid: ${process.getuid()}`);
try {
process.setuid(501);
console.log(`New uid: ${process.getuid()}`);
}
catch (err) {
console.log(`Failed to set uid: ${err}`);
}
}
process.stderr
process.stdin
process.stdin.setEncoding('utf8');
process.stdin.on('readable', () => {
var chunk = process.stdin.read();
if (chunk !== null) {process.stdout.write(`data: ${chunk}`);}
});
process.stdin.on('end', () => {process.stdout.write('end');});
process.stdout
console.log = function (msg) {process.stdout.write(`${msg}\n`);};
TTY Terminals and process.stdout
$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false
$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false
process.title
process.umask(mask);
const newmask = 0o022;
const oldmask = process.umask(newmask);
console.log(`Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`);
process.uptime();
process.version
console.log(`Version: ${process.version}`);
process.versions
console.log(process.versions);
// Prints
/*
{
http_parser: '2.3.0',
node: '1.1.1',
v8: '4.1.0.14',
uv: '1.3.0',
zlib: '1.2.8',
ares: '1.10.0-DEV',
modules: '43',
icu: '55.1',
openssl: '1.0.1k'
}
*/
Punycode // deprecated
const punycode = require('punycode');
punycode.decode(string);
punycode.decode('maana-pta'); // 'mañana'
punycode.decode('--dqo34k'); // '☃-⌘'
punycode.encode(string);
punycode.encode('mañana'); // 'maana-pta'
punycode.encode('☃-⌘'); // '--dqo34k'
punycode.toASCII(domain);
punycode.toASCII('mañana.com'); // 'xn--maana-pta.com'
punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com'
punycode.toASCII('example.com'); // 'example.com'
punycode.toUnicode(domain);
punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com'
punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com'
punycode.toUnicode('example.com'); // 'example.com'
punycode.ucs2
punycode.ucs2.decode(string);
punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63]
// surrogate pair for U+1D306 tetragram for centre:
punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306]
punycode.ucs2.encode(codePoints);
punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc'
punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06'
punycode.version
Query String
const querystring = require('querystring');
querystring.escape('str');
querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null, {decodeURIComponent: gbkDecodeURIComponent});
querystring.stringify({ w: '中文', foo: 'bar' }, null, null, {encodeURIComponent: gbkEncodeURIComponent});
querystring.unescape('str');
Readline - читает по строке за раз из потока чтения
const readline = require('readline');
const readLine = readline.createInterface({
input: process.stdin,
output: process.stdout
});
readLine.question('What do you think of Node.js? ', function (answer) {
// TODO: Log the answer in a database
console.log('Thank you for your valuable feedback:', answer);
readLine.close();
});
Events
readLine.on('close', function () {});
readLine.on('line', function (input) {console.log(`Received: ${input}`);});
readLine.on('pause', function () {console.log('Readline paused.');});
readLine.on('resume', function () {console.log('Readline resumed.');});
readLine.on('SIGCONT', function () {
readLine.prompt(); // `prompt` will automatically resume the stream
});
readLine.on('SIGINT', function () {
readLine.question('Are you sure you want to exit?', function (answer) {
if (answer.match(/^y(es)?$/i)) {
readLine.pause();
}
});
});
readLine.on('SIGTSTP', function () {
// This will override SIGTSTP and prevent the program from going to the background.
console.log('Caught SIGTSTP.');
});
readLine.close();
readLine.pause();
readLine.prompt(preserveCursor);
readLine.question('What is your favorite food?', function (answer) {
console.log(`Oh, so your favorite food is ${answer}`);
});
readLine.resume();
readLine.setPrompt(prompt);
readLine.write(data, key);
readLine.write('Delete this!');
readLine.write(null, {ctrl: true, name: 'u'}); // Simulate Ctrl+u to delete the line written previously
readline.clearLine(stream, dir);
readline.clearScreenDown(stream);
const readline = require('readline');
const readLine = readline.createInterface({
input: process.stdin,
output: process.stdout
});
readLine.on('line', function (line) {
console.log(`Received: ${line}`);
});
Use of the completer Function
function completer (line) {
var completions = '.help .error .exit .quit .q'.split(' ');
var hits = completions.filter(function (c) {return c.indexOf(line) == 0});
return [hits.length ? hits : completions, line]; // show all completions if none found
}
function completer (linePartial, callback) {
callback(null, [['123'], linePartial]);
}
readline.cursorTo(stream, x, y);
readline.emitKeypressEvents(stream, interface);
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY) {
process.stdin.setRawMode(true);
}
readline.moveCursor(stream, dx, dy);
Example: Tiny CLI
const readline = require('readline');
const readLine = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'OHAI> '
});
readLine.prompt();
readLine.on('line', function (line) {
switch(line.trim()) {
case 'hello': console.log('world!'); break;
default: console.log(`Say what? I might have heard '${line.trim()}'`); break;
}
readLine.prompt();
}).on('close', function () {
console.log('Have a great day!');
process.exit(0);
});
Example: Read File Stream Line-by-Line
const readline = require('readline');
const readLine = require('fs');
const readLine = readline.createInterface({
input: fs.createReadStream('sample.txt')
});
readLine.on('line', function (line) {
console.log('Line from file:', line);
});
REPL
const repl = require('repl');
Commands and Special Keys
.break - When in the process of inputting a multi-line expression, entering the .break command (or pressing the <ctrl>-C key combination) will abort further input or processing of that expression.
.clear - Resets the REPL context to an empty object and clears any multi-line expression currently being input.
.exit - Close the I/O stream, causing the REPL to exit.
.help - Show this list of special commands.
.save - Save the current REPL session to a file: > .save ./file/to/save.js
.load - Load a file into the current REPL session. > .load ./file/to/load.js
.editor - Enter editor mode (<ctrl>-D to finish, <ctrl>-C to cancel)
> .editor
// Entering editor mode (^D to finish, ^C to cancel)
function welcome(name) {
return `Hello ${name}!`;
}
welcome('Node.js User');
// ^D
'Hello Node.js User!'
>
Global and Local Scope
const repl = require('repl');
var msg = 'message';
repl.start('> ').context.m = msg;
$ node repl_test.js
> m
'message'
const repl = require('repl');
var msg = 'message';
const r = repl.start('> ');
Object.defineProperty(r.context, 'm', {
configurable: false,
enumerable: true,
value: msg
});
Accessing Core Node.js Modules
global.fs = require('fs')
> fs.createReadStream('./some/file');
Assignment of the _ (underscore); variable
> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
4
Custom Evaluation Functions
const repl = require('repl');
const Translator = require('translator').Translator;
const myTranslator = new Translator('en', 'fr');
function myEval(cmd, context, filename, callback) {
callback(null, myTranslator.translate(cmd));
}
repl.start({prompt: '> ', eval: myEval});
Recoverable Errors
function eval(cmd, context, filename, callback) {
var result;
try {
result = vm.runInThisContext(cmd);
} catch (e) {
if (isRecoverableError(e)) {
return callback(new repl.Recoverable(e));
}
}
callback(null, result);
}
function isRecoverableError(error) {
if (error.name === 'SyntaxError') {
return /^(Unexpected end of input|Unexpected token)/.test(error.message);
}
return false;
}
Customizing REPL Output
const repl = require('repl');
const r = repl.start({prompt: '>', eval: myEval, writer: myWriter});
function myEval(cmd, context, filename, callback) {
callback(null,cmd);
}
function myWriter(output) {
return output.toUpperCase();
}
// REPLServer
Events
replServer.on('exit', function () {
console.log('Received "exit" event from repl!');
process.exit();
});
replServer.on('reset', function () {});
const repl = require('repl');
function initializeContext(context) {
context.m = 'test';
}
var r = repl.start({prompt: '>'});
initializeContext(r.context);
r.on('reset', initializeContext);
$ ./node example.js
>m
'test'
>m = 1
1
>m
1
>.clear
Clearing context...
>m
'test'
>
replServer.defineCommand(keyword, cmd);
const repl = require('repl');
var replServer = repl.start({prompt: '> '});
replServer.defineCommand('sayhello', {
help: 'Say hello',
action: function(name) {
this.lineParser.reset();
this.bufferedCommand = '';
console.log(`Hello, ${name}!`);
this.displayPrompt();
}
});
replServer.defineCommand('saybye', function() {
console.log('Goodbye!');
this.close();
});
> .sayhello Node.js User
Hello, Node.js User!
> .saybye
Goodbye!
replServer.displayPrompt(preserveCursor);
repl.start(options);
Starting multiple REPL instances against a single running instance
const net = require('net');
const repl = require('repl');
var connections = 0;
repl.start({
prompt: 'Node.js via stdin> ',
input: process.stdin,
output: process.stdout
});
net.createServer(function (socket) {
connections += 1;
repl.start({
prompt: 'Node.js via Unix socket> ',
input: socket,
output: socket
}).on('exit', function () {
socket.end();
});
}).listen('/tmp/node-repl-sock');
net.createServer(function (socket) {
connections += 1;
repl.start({
prompt: 'Node.js via TCP socket> ',
input: socket,
output: socket
}).on('exit', function () {
socket.end();
});
}).listen(5001);
Stream
const stream = require('stream');
Types of Streams
- Readable - streams from which data can be read (for example fs.createReadStream()).
- Writable - streams to which data can be written (for example fs.createWriteStream()).
- Duplex - streams that are both Readable and Writable (for example net.Socket).
- Transform - Duplex streams that can modify or transform the data as it is written and read (for example zlib.createDeflate()).
API for Stream Consumers
const http = require('http');
const server = http.createServer( (req, res) => {
// req is an http.IncomingMessage, which is a Readable Stream
// res is an http.ServerResponse, which is a Writable Stream
let body = '';
// Get the data as utf8 strings.
// If an encoding is not set, Buffer objects will be received.
req.setEncoding('utf8');
// Readable streams emit 'data' events once a listener is added
req.on('data', (chunk) => {
body += chunk;
});
// the end event indicates that the entire body has been received
req.on('end', () => {
try {
const data = JSON.parse(body);
// write back something interesting to the user:
res.write(typeof data);
res.end();
} catch (er) {
// uh oh! bad json!
res.statusCode = 400;
return res.end(`error: ${er.message}`);
}
});
});
server.listen(1337);
// $ curl localhost:1337 -d '{}'
// object
// $ curl localhost:1337 -d '"foo"'
// string
// $ curl localhost:1337 -d 'not json'
// error: Unexpected token o
Writable Streams
- HTTP requests, on the client
- HTTP responses, on the server
- fs write streams
- zlib streams
- crypto streams
- TCP sockets
- child process stdin
- process.stdout
- process.stderr
const myStream = getWritableStreamSomehow();
myStream.write('some data');
myStream.write('some more data');
myStream.end('done writing data');
// stream.Writable
Events
writableStream.on('close', function () {});
writableStream.on('drain', function () {});
// Write the data to the supplied writable stream one million times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
let i = 1000000;
write();
function write() {
var ok = true;
do {
i--;
if (i === 0) {
// last time!
writer.write(data, encoding, callback);
} else {
// see if we should continue, or wait
// don't pass the callback, because we're not done yet.
ok = writer.write(data, encoding);
}
} while (i > 0 && ok);
if (i > 0) {
// had to stop early!
// write some more once it drains
writer.once('drain', write);
}
}
}
writableStream.on('error', function () {});
writableStream.on('finish', function () {});
const writer = getWritableStreamSomehow();
for (var i = 0; i < 100; i ++) {
writer.write('hello, #${i}!\n');
}
writer.end('This is the end\n');
writer.on('finish', () => {
console.error('All writes are now complete.');
});
writableStream.on('pipe', function () {});
const writer = getWritableStreamSomehow();
const reader = getReadableStreamSomehow();
writer.on('pipe', function (src) {
console.error('something is piping into the writer');
assert.equal(src, reader);
});
reader.pipe(writer);
writableStream.on('unpipe', function () {});
const writer = getWritableStreamSomehow();
const reader = getReadableStreamSomehow();
writer.on('unpipe', function (src) {
console.error('Something has stopped piping into the writer.');
assert.equal(src, reader);
});
reader.pipe(writer);
reader.unpipe(writer);
writable.cork();
writable.end(chunk, 'utf8', function () {});
// write 'hello, ' and then end with 'world!'
const file = fs.createWriteStream('example.txt');
file.write('hello, ');
file.end('world!');
// writing more now is not allowed!
writable.setDefaultEncoding('utf8');
writable.uncork();
stream.cork();
stream.write('some ');
stream.write('data ');
process.nextTick(function () {stream.uncork()});
stream.cork();
stream.write('some ');
stream.cork();
stream.write('data ');
process.nextTick(function () {
stream.uncork();
// The data will not be flushed until uncork() is called a second time.
stream.uncork();
});
writable.write(chunk, 'utf8', function () {});
Readable Streams
- HTTP responses, on the client
- HTTP requests, on the server
- fs read streams
- zlib streams
- crypto streams
- TCP sockets
- child process stdout and stderr
- process.stdin
Two Modes
In paused mode, the stream.read() method must be called explicitly to read chunks of data from the stream.
All Readable streams begin in paused mode but can be switched to flowing mode in one of the following ways:
- Adding a 'data' event handler.
- Calling the stream.resume() method.
- Calling the stream.pipe() method to send the data to a Writable.
The Readable can switch back to paused mode using one of the following:
- If there are no pipe destinations, by calling the stream.pause() method.
- If there are pipe destinations, by removing any 'data' event handlers, and removing all pipe destinations by calling the stream.unpipe() method.
Three States
- readable._readableState.flowing = null
- readable._readableState.flowing = false
- readable._readableState.flowing = true
Choose One
Developers that require more fine-grained control over the transfer and generation of data can use the EventEmitter and readable.pause()/readable.resume() APIs.
// stream.Readable
readableStream.on('close', function () {});
readableStream.on('data', function (chunk) {console.log(`Received ${chunk.length} bytes of data.`);});
readableStream.on('end', function () {console.log('There will be no more data.');});
readableStream.on('error', function () {});
readableStream.on('readable', function () {/* there is some data to read now */});
const fs = require('fs');
const rr = fs.createReadStream('foo.txt');
rr.on('readable', function () {console.log('readable:', rr.read());});
rr.on('end', function (){console.log('end');});
$ node test.js
readable: null
end
if (readable.isPaused()) {}
const readable = new stream.Readable
readable.isPaused() // === false
readable.pause()
readable.isPaused() // === true
readable.resume()
readable.isPaused() // === false
readable.pause();
const readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
readable.pause();
console.log('There will be no additional data for 1 second.');
setTimeout(() => {
console.log('Now data will start flowing again.');
readable.resume();
}, 1000);
});
readable.pipe(destination, options);
const readable = getReadableStreamSomehow();
const writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt'
readable.pipe(writable);
const r = fs.createReadStream('file.txt');
const z = zlib.createGzip();
const w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);
reader.pipe(writer, { end: false });
reader.on('end', () => {
writer.end('Goodbye\n');
});
readable.read(size);
const readable = getReadableStreamSomehow();
readable.on('readable', () => {
var chunk;
while (null !== (chunk = readable.read())) {
console.log(`Received ${chunk.length} bytes of data.`);
}
});
readable.resume();
getReadableStreamSomehow()
.resume()
.on('end', function () {console.log('Reached the end, but did not read anything.');});
readable.setEncoding('utf8');
const readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', (chunk) => {
assert.equal(typeof chunk, 'string');
console.log('got %d characters of string data', chunk.length);
});
readable.unpipe(destination);
const readable = getReadableStreamSomehow();
const writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt',
// but only for the first second
readable.pipe(writable);
setTimeout(() => {
console.log('Stop writing to file.txt');
readable.unpipe(writable);
console.log('Manually close the file stream');
writable.end();
}, 1000);
readable.unshift(chunk);
// Pull off a header delimited by \n\n
// use unshift() if we get too much
// Call the callback with (error, header, stream)
const StringDecoder = require('string_decoder').StringDecoder;
function parseHeader(stream, callback) {
stream.on('error', callback);
stream.on('readable', onReadable);
const decoder = new StringDecoder('utf8');
var header = '';
function onReadable() {
var chunk;
while (null !== (chunk = stream.read())) {
var str = decoder.write(chunk);
if (str.match(/\n\n/)) {
// found the header boundary
var split = str.split(/\n\n/);
header += split.shift();
const remaining = split.join('\n\n');
const buf = Buffer.from(remaining, 'utf8');
stream.removeListener('error', callback);
// set the readable listener before unshifting
stream.removeListener('readable', onReadable);
if (buf.length)
stream.unshift(buf);
// now the body of the message can be read from the stream.
callback(null, header, stream);
} else {
// still reading the header.
header += str;
}
}
}
}
readable.wrap(stream);
const OldReader = require('./old-api-module.js').OldReader;
const Readable = require('stream').Readable;
const oreader = new OldReader;
const myReader = new Readable().wrap(oreader);
myReader.on('readable', () => {
myReader.read(); // etc.
});
Duplex Streams
- TCP sockets
- zlib streams
- crypto streams
// stream.Duplex
Transform Streams
- zlib streams
- crypto streams
// stream.Transform
API for Stream Implementers
Implementing a Writable Stream
const Writable = require('stream').Writable;
class MyWritable extends Writable {
constructor(options) {
super(options);
}
_write(chunk, encoding, callback) {
if (chunk.toString().indexOf('a') >= 0) {
callback(new Error('chunk is invalid'));
} else {
callback();
}
}
}
const Writable = require('stream').Writable;
const myWritable = new Writable({
write(chunk, encoding, callback) {
if (chunk.toString().indexOf('a') >= 0) {
callback(new Error('chunk is invalid'));
} else {
callback();
}
},
writev(chunks, callback) {
// ...
}
});
Implementing a Readable Stream
const Readable = require('stream').Readable;
class MyReadable extends Readable {
constructor(options) {
// Calls the stream.Readable(options) constructor
super(options);
}
}
const Readable = require('stream').Readable;
const myReadable = new Readable({
read(size) {
if (checkSomeErrorCondition()) {
process.nextTick(function () {this.emit('error', err)});
return;
}
// do some work
}
});
// source is an object with readStop() and readStart() methods,
// and an `ondata` member that gets called when it has data, and
// an `onend` member that gets called when the data is over.
class SourceWrapper extends Readable {
constructor(options) {
super(options);
this._source = getLowlevelSourceObject();
// Every time there's data, push it into the internal buffer.
this._source.ondata = (chunk) => {
// if push() returns false, then stop reading from source
if (!this.push(chunk))
this._source.readStop();
};
// When the source ends, push the EOF-signaling `null` chunk
this._source.onend = () => {
this.push(null);
};
}
// _read will be called when the stream wants to pull more data in
// the advisory size argument is ignored in this case.
_read(size) {
this._source.readStart();
}
}
An Example Counting Stream
const Readable = require('stream').Readable;
class Counter extends Readable {
constructor(opt) {
super(opt);
this._max = 1000000;
this._index = 1;
}
_read() {
var i = this._index++;
if (i > this._max)
this.push(null);
else {
var str = '' + i;
var buf = Buffer.from(str, 'ascii');
this.push(buf);
}
}
}
Implementing a Duplex Stream
const Duplex = require('stream').Duplex;
class MyDuplex extends Duplex {
constructor(options) {
super(options);
}
}
const Duplex = require('stream').Duplex;
const myDuplex = new Duplex({
read(size) {
// ...
},
write(chunk, encoding, callback) {
// ...
}
});
An Example Duplex Stream
const Duplex = require('stream').Duplex;
const kSource = Symbol('source');
class MyDuplex extends Duplex {
constructor(source, options) {
super(options);
this[kSource] = source;
}
_write(chunk, encoding, callback) {
// The underlying source only deals with strings
if (Buffer.isBuffer(chunk))
chunk = chunk.toString(encoding);
this[kSource].writeSomeData(chunk, encoding);
callback();
}
_read(size) {
this[kSource].fetchSomeData(size, (data, encoding) => {
this.push(Buffer.from(data, encoding));
});
}
}
Object Mode Duplex Streams
const Transform = require('stream').Transform;
// All Transform streams are also Duplex Streams
const myTransform = new Transform({
writableObjectMode: true,
transform(chunk, encoding, callback) {
// Coerce the chunk to a number if necessary
chunk |= 0;
// Transform the chunk into something else.
const data = chunk.toString(16);
// Push the data onto the readable queue.
callback(null, '0'.repeat(data.length % 2) + data);
}
});
myTransform.setEncoding('ascii');
myTransform.on('data', (chunk) => console.log(chunk));
myTransform.write(1);
// Prints: 01
myTransform.write(10);
// Prints: 0a
myTransform.write(100);
// Prints: 64
Implementing a Transform Stream
const Transform = require('stream').Transform;
class MyTransform extends Transform {
constructor(options) {
super(options);
}
}
const Transform = require('stream').Transform;
const myTransform = new Transform({
transform(chunk, encoding, callback) {
// ...
}
});
transformStream.on('finish', function () {});
transformStream.on('end', function () {});
transform._flush(function () {});
transform._transform(chunk, 'utf8', function () {});
transform.prototype._transform = function (data, encoding, callback) {
this.push(data);
callback();
};
transform.prototype._transform = function (data, encoding, callback) {
callback(null, data);
};
Additional Notes
// Workaround
net.createServer((socket) => {
socket.on('end', () => {
socket.end('The message was received but was not processed.\n');
});
// start the flow of data, discarding it.
socket.resume();
}).listen(1337);
Compatibility with Older Node.js Versions
readable.read(0);
There are some cases where it is necessary to trigger a refresh of the underlying readable stream mechanisms, without actually consuming any data. In such cases, it is possible to call readable.read(0)
readable.push(''); // Use of readable.push('') is not recommended.
StringDecoder
const StringDecoder = require('string_decoder').StringDecoder;
const decoder = new StringDecoder('utf8');
const cent = Buffer.from([0xC2, 0xA2]);
console.log(decoder.write(cent));
const euro = Buffer.from([0xE2, 0x82, 0xAC]);
console.log(decoder.write(euro));
const StringDecoder = require('string_decoder').StringDecoder;
const decoder = new StringDecoder('utf8');
decoder.write(Buffer.from([0xE2]));
decoder.write(Buffer.from([0x82]));
console.log(decoder.end(Buffer.from([0xAC])));
var stringDecoder = new StringDecoder('utf8');
stringDecoder.write(buffer);
stringDecoder.end(buffer);
Timers
var timeout =setTimeout(function (...args) {}, 1500, ...args);
var interval =setInterval(function (...args) {}, 1500, ...args);
var immediate = setImmediate(function (...args) {}, ...args);
clearTimeout(timeout);
clearInterval(interval);
clearImmediate(immediate);
timeout.ref();
timeout.unref();
Transport Layer Security - TLS and Secure Socket Layer - SSL
const tls = require('tls');
// tls.Server
Events
tlsServer.on('tlsClientError', function (exception, tlsSocket) {});
tlsServer.on('newSession', function (sessionId, sessionData, callback) {});
tlsServer.on('OCSPRequest', function (certificate, issuer, callback) {});
tlsServer.on('resumeSession', function (sessionId, callback) {});
const tlsSessionStore = {};
server.on('newSession', (id, data, cb) => {
tlsSessionStore[id.toString('hex')] = data;
cb();
});
server.on('resumeSession', (id, cb) => {
cb(null, tlsSessionStore[id.toString('hex')] || null);
});
tlsServer.on('secureConnection', function (tlsSocket) {});
server.addContext(hostname, context);
server.address();
server.close(callback);
var connectionsNumber = server.connections;
server.getTicketKeys();
server.listen(port, hostname, callback);
server.setTicketKeys(keys);
// tls.TLSSocket
new tls.TLSSocket(socket, options);
Events
tlsSocket.on('OCSPResponse', function (response ) {});
tlsSocket.on('secureConnect', function () {});
tlsSocket.address(); // {port: 12346, family: 'IPv4', address: '127.0.0.1'}
if (tlsSocket.authorized) {}
if (tlsSocket.authorizationError) {}
if (tlsSocket.encrypted) {}
tlsSocket.getCipher(); // {name: 'AES256-SHA', version: 'TLSv1/SSLv3'}
tlsSocket.getEphemeralKeyInfo(); // {type: 'ECDH', name: 'prime256v1', size: 256}
tlsSocket.getPeerCertificate(detailed);
/*
{ subject:
{ C: 'UK',
ST: 'Acknack Ltd',
L: 'Rhys Jones',
O: 'node.js',
OU: 'Test TLS Certificate',
CN: 'localhost' },
issuerInfo:
{ C: 'UK',
ST: 'Acknack Ltd',
L: 'Rhys Jones',
O: 'node.js',
OU: 'Test TLS Certificate',
CN: 'localhost' },
issuer:
{ ... another certificate ... },
raw: < RAW DER buffer >,
valid_from: 'Nov 11 09:52:22 2009 GMT',
valid_to: 'Nov 6 09:52:22 2029 GMT',
fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',
serialNumber: 'B9B0D332A1AA5635' }
*/
tlsSocket.getProtocol(); // SSLv3, TLSv1, TLSv1.1, TLSv1.2, unknown
tlsSocket.getSession();
tlsSocket.getTLSTicket();
tlsSocket.localAddress // local IP address
tlsSocket.localPort // local port
tlsSocket.remoteAddress // '74.125.127.100'
tlsSocket.remoteFamily // 'IPv4' or 'IPv6'
tlsSocket.remotePort // 443
tlsSocket.renegotiate(options, function () {});
tlsSocket.setMaxSendFragment(16384);
tls.connect(options, callback);
tls.connect(port, host, options, function () {});
const tls = require('tls');
const fs = require('fs');
const options = {
// Necessary only if using the client certificate authentication
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-cert.pem'),
// Necessary only if the server uses the self-signed certificate
ca: [ fs.readFileSync('server-cert.pem') ]
};
const socket = tls.connect(8000, options, () => {
console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized');
process.stdin.pipe(socket);
process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {console.log(data);});
socket.on('end', () => {server.close();});
const tls = require('tls');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('client.pfx')
};
const socket = tls.connect(8000, options, () => {
console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized');
process.stdin.pipe(socket);
process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {console.log(data);});
socket.on('end', () => {server.close();});
tls.createSecureContext(options);
tls.createServer(options, secureConnectionListener);
const tls = require('tls');
const fs = require('fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
// This is necessary only if using the client certificate authentication.
requestCert: true,
// This is necessary only if the client uses the self-signed certificate.
ca: [ fs.readFileSync('client-cert.pem') ]
};
const server = tls.createServer(options, (socket) => {
console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized');
socket.write('welcome!\n');
socket.setEncoding('utf8');
socket.pipe(socket);
});
server.listen(8000, () => {console.log('server bound');});
const tls = require('tls');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('server.pfx'),
// This is necessary only if using the client certificate authentication.
requestCert: true,
};
const server = tls.createServer(options, (socket) => {
console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized');
socket.write('welcome!\n');
socket.setEncoding('utf8');
socket.pipe(socket);
});
server.listen(8000, () => {console.log('server bound');});
openssl s_client -connect 127.0.0.1:8000
tls.getCiphers();
console.log(tls.getCiphers()); // ['AES128-SHA', 'AES256-SHA', ...]
Deprecated APIs
// CryptoStream
cryptoStream.bytesWritten
// SecurePair
Events
securePair.on('secure', function () {});
tls.createSecurePair(context, isServer, requestCert, rejectUnauthorized, options);
pair = tls.createSecurePair( ... );
pair.encrypted.pipe(socket);
socket.pipe(pair.encrypted);
secure_socket = tls.TLSSocket(socket, options);
TTY
const tty = require('tty');
$ node -p -e "Boolean(process.stdout.isTTY)"
true
$ node -p -e "Boolean(process.stdout.isTTY)" | cat
false
// tty.ReadStream
if (readStream.isRaw) {}
readStream.setRawMode(mode);
// tty.WriteStream
Events
process.stdout.on('resize', function () {
console.log('screen size has changed!');
console.log(`${process.stdout.columns}x${process.stdout.rows}`);
});
var columns = writeStream.columns;
var rows = writeStream.rows;
if (tty.isatty(fd)) {}
UDP / Datagram Sockets
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server error:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
var address = server.address();
console.log(`server listening ${address.address}:${address.port}`);
});
server.bind(41234);
// server listening 0.0.0.0:41234
dgram.Socket
dgram.on('close', function () {});
dgram.on('error', function (error) {});
dgram.on('listening', function () {});
dgram.on('message', function (msg, rinfo) {console.log('Received %d bytes from %s:%d\n', msg.length, rinfo.address, rinfo.port);});
socket.addMembership(multicastAddress, multicastInterface);
socket.address();
socket.bind(port, address, function () {});
socket.bind(options, function () {});
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server error:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
var address = server.address();
console.log(`server listening ${address.address}:${address.port}`);
});
server.bind(41234);
// server listening 0.0.0.0:41234
socket.bind({
address: 'localhost',
port: 8000,
exclusive: true
});
socket.close(function () {});
socket.dropMembership(multicastAddress, multicastInterface);
socket.send(msg, offset, length, port, address, function () {});
const dgram = require('dgram');
const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {client.close();});
const dgram = require('dgram');
const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {client.close();});
const dgram = require('dgram');
const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
const client = dgram.createSocket('udp4');
client.send([buf1, buf2], 41234, 'localhost', (err) => {client.close();});
socket.setBroadcast(flag);
socket.setMulticastLoopback(flag);
socket.setMulticastTTL(ttl);
socket.setTTL(ttl);
socket.ref();
socket.unref();
Change to asynchronous socket.bind(); behavior
const s = dgram.createSocket('udp4');
s.bind(1234);
s.addMembership('224.0.0.114');
const s = dgram.createSocket('udp4');
s.bind(1234, function () {s.addMembership('224.0.0.114');});
dgram module functions
dgram.createSocket(options, function () {});
dgram.createSocket(type, function () {});
URL
const url = require('url');
http://user:pass@host.com:8080/p/a/t/h?query=string#hash
urlObject.href; // 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'
urlObject.protocol; // 'http:'
if (urlObject.slashes) {} // true if two ASCII forward-slash characters (/) are required following the colon in the protocol
urlObject.host; // 'host.com:8080'
urlObject.auth; // 'user:pass'
urlObject.hostname; // 'host.com'
urlObject.port; // '8080'
urlObject.pathname; // '/p/a/t/h'
urlObject.search; // '?query=string'
urlObject.path; // '/p/a/t/h?query=string'
urlObject.query; // 'query=string' or {'query': 'string'}
urlObject.hash; // '#hash'
url.format({urlObject});
url.parse(urlString, parseQueryString, slashesDenoteHost);
url.resolve(from, to);
url.resolve('/one/two/three', 'four') // '/one/two/four'
url.resolve('http://example.com/', '/one') // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'
Escaped Characters: < > " ` \r \n \t { } | \ ^ '
Util
const util = require('util');
util.debuglog(section);
const util = require('util');
const debuglog = util.debuglog('foo');
debuglog('hello from foo [%d]', 123);
// FOO 3245: hello from foo [123]
util.deprecate(function, string);
const util = require('util');
exports.puts = util.deprecate(function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
process.stdout.write(arguments[i] + '\n');
}
}, 'util.puts: Use console.log instead');
util.format(format, ...);
%s - String.
%d - Number (both integer and float).
%j - JSON. Replaced with the string '[Circular]' if the argument contains circular references.
%% - single percent sign ('%'). This does not consume an argument.
util.format('%s:%s', 'foo'); // Returns 'foo:%s'
util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'
util.format(1, 2, 3); // '1 2 3'
util.inherits(constructor, superConstructor);
const util = require('util');
const EventEmitter = require('events');
function MyStream() {
EventEmitter.call(this);
}
util.inherits(MyStream, EventEmitter);
MyStream.prototype.write = function(data) {
this.emit('data', data);
};
const stream = new MyStream();
console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true
stream.on('data', (data) => {console.log(`Received data: "${data}"`);});
stream.write('It works!'); // Received data: "It works!"
util.inspect(object, options);
console.log(util.inspect(util, { showHidden: true, depth: null }));
Customizing util.inspect colors
number - yellow
boolean - yellow
string - green
date - magenta
regexp - red
null - bold
undefined - grey
special - cyan (only applied to functions at this time)
name - (no styling)
Custom inspection functions on Objects
const util = require('util');
const obj = {name: 'nate'};
obj[util.inspect.custom] = function (depth) {
return `{${this.name}}`;
};
util.inspect(obj);
// "{nate}"
const util = require('util');
const obj = { foo: 'this will not show up in the inspect() output' };
obj[util.inspect.custom] = function(depth) {
return {bar: 'baz'};
};
util.inspect(obj);
// "{ bar: 'baz' }"
const util = require('util');
const obj = { foo: 'this will not show up in the inspect() output' };
obj.inspect = function(depth) {
return { bar: 'baz' };
};
util.inspect(obj);
// "{ bar: 'baz' }"
util.inspect.defaultOptions
const util = require('util');
const arr = Array(101);
console.log(arr); // logs the truncated array
util.inspect.defaultOptions.maxArrayLength = null;
console.log(arr); // logs the full array
util.inspect.custom
Deprecated APIs
util.debug(string);
util.error(...);
util.isArray(object);
const util = require('util');
util.isArray([]); // true
util.isArray(new Array); // true
util.isArray({}); // false
util.isBoolean(object);
const util = require('util');
util.isBoolean(1); // false
util.isBoolean(0); // false
util.isBoolean(false); // true
util.isBuffer(object);
const util = require('util');
util.isBuffer({length: 0}); // false
util.isBuffer([]); // false
util.isBuffer(Buffer.from('hello world')); // true
util.isDate(object);
const util = require('util');
util.isDate(new Date()); // true
util.isDate(Date()); // false (without 'new' returns a String)
util.isDate({}); // false
util.isError(object);
const util = require('util');
util.isError(new Error()); // true
util.isError(new TypeError()); // true
util.isError({ name: 'Error', message: 'an error occurred' }); // false
const util = require('util');
const obj = { name: 'Error', message: 'an error occurred' };
util.isError(obj); // false
obj[Symbol.toStringTag] = 'Error';
util.isError(obj); // true
util.isFunction(object);
const util = require('util');
function Foo() {}
const Bar = function() {};
util.isFunction({}); // false
util.isFunction(Foo); // true
util.isFunction(Bar); // true
util.isNull(object);
const util = require('util');
util.isNull(0); // false
util.isNull(undefined); // false
util.isNull(null); // true
util.isNullOrUndefined(object);
const util = require('util');
util.isNullOrUndefined(0); // false
util.isNullOrUndefined(undefined); // true
util.isNullOrUndefined(null); // true
util.isNumber(object);
const util = require('util');
util.isNumber(false); // false
util.isNumber(Infinity); // true
util.isNumber(0); // true
util.isNumber(NaN); // true
util.isObject(object);
const util = require('util');
util.isObject(5); // false
util.isObject(null); // false
util.isObject({}); // true
util.isObject(function(){}); // false
util.isPrimitive(object);
const util = require('util');
util.isPrimitive(5); // true
util.isPrimitive('foo'); // true
util.isPrimitive(false); // true
util.isPrimitive(null); // true
util.isPrimitive(undefined); // true
util.isPrimitive({}); // false
util.isPrimitive(function() {}); // false
util.isPrimitive(/^$/); // false
util.isPrimitive(new Date()); // false
util.isRegExp(object);
const util = require('util');
util.isRegExp(/some regexp/); // true
util.isRegExp(new RegExp('another regexp')); // true
util.isRegExp({}); // false
util.isString(object);
const util = require('util');
util.isString(''); // true
util.isString('foo'); // true
util.isString(String('foo')); // true
util.isString(5); // false
util.isSymbol(object);
const util = require('util');
util.isSymbol(5); // false
util.isSymbol('foo'); // false
util.isSymbol(Symbol('foo')); // true
util.isUndefined(object);
const util = require('util');
const foo = undefined;
util.isUndefined(5); // false
util.isUndefined(foo); // true
util.isUndefined(null); // false
util.log(string);
const util = require('util');
util.log('Timestamped message.');
util.print(...);
util.puts(...);
util._extend(target, source);
V8
const v8 = require('v8');
v8.getHeapStatistics();
/* Prints
{
total_heap_size: 7326976,
total_heap_size_executable: 4194304,
total_physical_size: 7326976,
total_available_size: 1152656,
used_heap_size: 3476208,
heap_size_limit: 1535115264
}
*/
v8.getHeapSpaceStatistics();
/* Prints
[
{
"space_name": "new_space",
"space_size": 2063872,
"space_used_size": 951112,
"space_available_size": 80824,
"physical_space_size": 2063872
}
]
*/
v8.setFlagsFromString(string);
// Print GC events to stdout for one minute.
const v8 = require('v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(function() {v8.setFlagsFromString('--notrace_gc');}, 60e3);
VM - Executing JavaScript
const vm = require('vm');
var script = new vm.Script(code, options);
script.runInContext(contextifiedSandbox, options);
const util = require('util');
const vm = require('vm');
const sandbox = {
animal: 'cat',
count: 2
};
const script = new vm.Script('count += 1; name = "kitty";');
script.runInNewContext(sandbox, options);
const util = require('util');
const vm = require('vm');
const script = new vm.Script('globalVar = "set"');
const sandboxes = [{}, {}, {}];
sandboxes.forEach(function (sandbox) {
script.runInNewContext(sandbox);
});
console.log(util.inspect(sandboxes));
// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
script.runInThisContext(options);
const vm = require('vm');
global.globalVar = 0;
const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
for (var i = 0; i < 1000; ++i) {
script.runInThisContext();
}
console.log(globalVar);
// 1000
// 1000
vm.createContext(sandbox);
vm.isContext(sandbox);
vm.runInContext(code, contextifiedSandbox, options);
const util = require('util');
const vm = require('vm');
const sandbox = { globalVar: 1 };
vm.createContext(sandbox);
for (var i = 0; i < 10; ++i) {
vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));
// { globalVar: 1024 }
vm.runInDebugContext(code);
const vm = require('vm');
const Debug = vm.runInDebugContext('Debug');
console.log(Debug.findScript(process.emit).name); // 'events.js'
console.log(Debug.findScript(process.exit).name); // 'internal/process.js'
vm.runInNewContext(code, sandbox, options);
const util = require('util');
const vm = require('vm');
const sandbox = {
animal: 'cat',
count: 2
};
vm.runInNewContext('count += 1; name = "kitty"', sandbox);
console.log(util.inspect(sandbox));
// { animal: 'cat', count: 3, name: 'kitty' }
vm.runInThisContext(code, options);
const vm = require('vm');
var localVar = 'initial value';
const vmResult = vm.runInThisContext('localVar = "vm";');
console.log('vmResult:', vmResult);
console.log('localVar:', localVar);
const evalResult = eval('localVar = "eval";');
console.log('evalResult:', evalResult);
console.log('localVar:', localVar);
// vmResult: 'vm', localVar: 'initial value'
// evalResult: 'eval', localVar: 'eval'
Example: Running an HTTP Server within a VM
'use strict';
const vm = require('vm');
let code =
`(function(require) {
const http = require('http');
http.createServer( (request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
})`;
vm.runInThisContext(code)(require);
Zlib
const zlib = require('zlib');
const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('input.txt');
const out = fs.createWriteStream('input.txt.gz');
inp.pipe(gzip).pipe(out);
const input = '.................................';
zlib.deflate(input, (err, buffer) => {
if (!err) {
console.log(buffer.toString('base64'));
} else {
// handle error
}
});
const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, (err, buffer) => {
if (!err) {
console.log(buffer.toString());
} else {
// handle error
}
});
Compressing HTTP requests and responses
// client request example
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
const request = http.get({ host: 'example.com',
path: '/',
port: 80,
headers: { 'Accept-Encoding': 'gzip,deflate' } });
request.on('response', (response) => {
var output = fs.createWriteStream('example.com_index.html');
switch (response.headers['content-encoding']) {
// or, just use zlib.createUnzip() to handle both cases
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output);
break;
default:
response.pipe(output);
break;
}
});
// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
http.createServer((request, response) => {
var raw = fs.createReadStream('index.html');
var acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) {
acceptEncoding = '';
}
// Note: this is not a conformant accept-encoding parser.
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
if (acceptEncoding.match(/\bdeflate\b/)) {
response.writeHead(200, { 'Content-Encoding': 'deflate' });
raw.pipe(zlib.createDeflate()).pipe(response);
} else if (acceptEncoding.match(/\bgzip\b/)) {
response.writeHead(200, { 'Content-Encoding': 'gzip' });
raw.pipe(zlib.createGzip()).pipe(response);
} else {
response.writeHead(200, {});
raw.pipe(response);
}
}).listen(1337);
// This is a truncated version of the buffer from the above examples
const buffer = Buffer.from('eJzT0yMA', 'base64');
zlib.unzip(buffer, { finishFlush: zlib.Z_SYNC_FLUSH }, (err, buffer) => {
if (!err) {
console.log(buffer.toString());
} else {
// handle error
}
});
Memory Usage Tuning
(1 << (windowBits+2)) + (1 << (memLevel+9))
{windowBits: 14, memLevel: 7}
1 << windowBits
Flushing
const zlib = require('zlib');
const http = require('http');
http.createServer((request, response) => {
// For the sake of simplicity, the Accept-Encoding checks are omitted.
response.writeHead(200, { 'content-encoding': 'gzip' });
const output = zlib.createGzip();
output.pipe(response);
setInterval(() => {
output.write(`The current time is ${Date()}\n`, () => {
// The data has been passed to zlib, but the compression algorithm may
// have decided to buffer the data for more efficient compression.
// Calling .flush() will make the data available as soon as the client
// is ready to receive it.
output.flush();
});
}, 1000);
}).listen(1337);
Constants
zlib.Z_NO_FLUSH
zlib.Z_PARTIAL_FLUSH
zlib.Z_SYNC_FLUSH
zlib.Z_FULL_FLUSH
zlib.Z_FINISH
zlib.Z_BLOCK
zlib.Z_TREES
zlib.Z_OK
zlib.Z_STREAM_END
zlib.Z_NEED_DICT
zlib.Z_ERRNO
zlib.Z_STREAM_ERROR
zlib.Z_DATA_ERROR
zlib.Z_MEM_ERROR
zlib.Z_BUF_ERROR
zlib.Z_VERSION_ERROR
Class Options:
- flush (default: zlib.Z_NO_FLUSH)
- finishFlush (default: zlib.Z_FINISH)
- chunkSize (default: 16*1024)
- windowBits
- level (compression only)
- memLevel (compression only)
- strategy (compression only)
- dictionary (deflate/inflate only, empty dictionary by default)
Class: zlib.Deflate
Class: zlib.DeflateRaw
Class: zlib.Gunzip
Class: zlib.Gzip
Class: zlib.Inflate
Class: zlib.InflateRaw
Class: zlib.Unzip
Class: zlib.Zlib
zlib.flush(kind, function () {});
zlib.params(level, strategy, function () {});
zlib.reset();
zlib.constants
zlib.createDeflate(options);
zlib.createDeflateRaw(options);
zlib.createGunzip(options);
zlib.createGzip(options);
zlib.createInflate(options);
zlib.createInflateRaw(options);
zlib.createUnzip(options);
Convenience Methods
zlib.deflate(buf, options, function () {});
zlib.deflateSync(buf, options);
zlib.deflateRaw(buf, options, function () {});
zlib.deflateRawSync(buf, options);
zlib.gunzip(buf, options, function () {});
zlib.gunzipSync(buf, options);
zlib.gzip(buf, options, function () {});
zlib.gzipSync(buf, options);
zlib.inflate(buf, options, function () {});
zlib.inflateSync(buf, options);
zlib.inflateRaw(buf, options, function () {});
zlib.inflateRawSync(buf, options);
zlib.unzip(buf, options, function () {});
zlib.unzipSync(buf, options);
It was really a nice post and I was really impressed by reading this
ОтветитьУдалитьNode JS Online training
Node JS training in Hyderabad