This chapter exposes you to some additional built-in capabilities of Node.js. The os
module provides operating system functionality that can be useful when implementing your applications. The util
module provides various functionality, such as string formatting. The dns
module provides the ability to perform DNS lookups and reverse lookups from a Node.js application.
The following sections describe these modules and how to use them in your Node.js applications. Some of the methods will already be familiar to you because you have seen them in previous chapters.
os
ModuleThe os
module provides a useful set of functions that allow you to get information from the operating system (OS). For example, when accessing data from a stream that comes from the OS, you can use the os.endianness()
function to determine whether the OS is big endian or little endian so that you can use the correct read and write methods.
Table 10.1 lists the methods provided by the os
module and describes how they are used.
Table 10.1 Methods that can be called on the os
module
Event |
Description |
|
Returns a string path to the default temp directory for the OS. Useful if you need to store files temporarily and then remove them later. |
|
Returns |
|
Returns the hostname defined for the machine. This is useful when implementing network services that require a hostname. |
|
Returns the OS type as a string. |
Returns the platform as a string; for example, |
|
|
Returns the platform architecture; for example, |
|
Returns the OS version release. |
|
Returns a timestamp in seconds of how long the OS has been running. |
|
On UNIX-based systems, returns an array of values containing the system load value for |
|
Returns an integer specifying the system memory in bytes. |
|
Returns an integer specifying the free system memory in bytes. |
|
Returns an array of objects that describes the |
|
Returns an array of objects describing the |
|
Contains the appropriate End Of Line characters for the operating system; for example, |
To help you visualize using the os
module, Listing 10.1 calls each of the os
module calls, and the output is shown in Listing 10.1 Output.
Listing 10.1 os_info.js
:
Calling methods on the os
module
01 var os = require('os'); 02 console.log("tmpdir : " + os.tmpdir()); 03 console.log("endianness : " + os.endianness()); 04 console.log("hostname : " + os.hostname()); 05 console.log("type : " + os.type()); 06 console.log("platform : " + os.platform()); 07 console.log("arch : " + os.arch()); 08 console.log("release : " + os.release()); 09 console.log("uptime : " + os.uptime()); 10 console.log("loadavg : " + os.loadavg()); 11 console.log("totalmem : " + os.totalmem()); 12 console.log("freemem : " + os.freemem()); 13 console.log("EOL : " + os.EOL); 14 console.log("cpus : " + JSON.stringify(os.cpus())); 15 console.log("networkInterfaces : " + 16 JSON.stringify(os.networkInterfaces()));
Listing 10.1 Output Calling methods on the os
module
tmpdir : C:UsersCalebTZDAppDataLocalTemp endianness : LE hostname : DESKTOP-3I5OR8I type : Windows_NT platform : win32 arch : x64 release : 10.0.14393 uptime : 1473719.6450068 loadavg : 0,0,0 totalmem : 12768796672 freemem : 8033443840 EOL : cpus :
util
ModuleThe util
module is a catch-all module that provides functions for formatting strings, converting objects to strings, checking object types, performing synchronous writes to output streams, and some object inheritance enhancements.
The following sections cover most of the functionality in the util
module. They also explain ways to use the util
module in your Node.js applications.
When handling string data, it is important to be able to format the strings quickly. Node.js provides a rudimentary string formatting method in the util
module that handles many string formatting needs. The util.format()
function accepts a formatter string as the first argument and returns a formatted string. The following shows the syntax for the format()
method, where format
is the formatter string and then [...]
represents the following arguments:
util.format(format[...args])
The format
argument is a string that can contain zero or more placeholders. Each placeholder begins with a %
character and is replaced with the converted string value from its corresponding argument. The first formatter placeholder represents the second argument and so on. The following is a list of supported placeholders:
%s
: Specifies a string
%d
: Specifies a number (can be integer or float)
%i
: Specifies an integer
%f
: Specifies a floating point value
%j
: Specifies a JSON stringifyable object
%
: If left empty afterward, does not act as a placeholder
The following is a list of things to keep in mind when using format()
:
When there are not as many arguments as placeholders, the placeholder is not replaced. For example:util.format('%s = %s', 'Item1'); // 'Item1:%s'
When there are more arguments than placeholders, the extra arguments are converted to strings and concatenated with a space delimiter.util.format('%s = %s', 'Item1', 'Item2', 'Item3'); // 'Item1 = Item2 Item3'
If the first argument is not a format string, then util.format()
converts each argument to a string, concatenates them together using a space delimiter, and then returns the concatenated string. For example:util.format(1, 2, 3); // '1 2 3'
It is often useful to determine whether an object you have received back from a command is of a certain type. To do this, you can use the isinstanceof
operator, which compares the object types and returns true
or false
. For example:
([1,2,3] isinstanceof Array) //true
Often, especially when debugging, you need to convert a JavaScript object to a string representation. The util.inspect()
method allows you to inspect an object and then return a string representation of the object.
The following shows the syntax for the inspect()
method:
util.inspect(object, [options])
The object
parameter is the JavaScript object you want to convert to a string. The options
method allows you to control certain aspects of the formatting process. options
can contain the following properties:
showHidden
: When set to true
, the non-enumerable properties of the object are also converted to the string. Defaults to false
.
depth
: Limits the number of levels deep the inspect process traverses while formatting properties that are also objects. This can prevent infinite loops and also prevent instances where complex objects cost a lot of CPU cycles. Defaults to 2
; if it is null
, it can recurse forever.
colors
: When set to true
, the output is styled with ANSI color codes. Defaults to false
.
customInspect
: When set to false
, any custom inspect()
functions defined on the objects being inspected are not called. Defaults to true
.
You can attach your own inspect()
function to the object, thus controlling the output. The following code creates an object with first and last properties, but inspect
outputs only a name property:
var obj = { first:'Caleb', last:'Dayley' }; obj.inspect = function(depth) { return '{ name: "' + this.first + " " + this.last + '" }'; }; console.log(util.inspect(obj)); //Outputs: { name: "Caleb Dayley" }
The util
module provides the util.inherits()
method to allow you to create objects that inherit the prototype
methods from another. When you create the new object, the prototype
methods are automatically used. You have already seen this in a few examples in the book; for example, when implementing your own custom Readable
and Writable
streams.
The following shows the format of the util.inherits()
method:
util.inherits(constructor, superConstructor)
The prototype of constructor
is set to the prototype of superConstructor
and executed when a new object is created. You can access the superConstructor
from your custom object constructor using the constructor.super_
property.
Listing 10.2 illustrates using inherits()
to inherit the events.EventEmitter
object constructor to create a Writable
stream. Notice on line 11 the object is an instance of events.EventEmitter
. Also notice on line 12 the Writer.super_
value is eventsEmitter
. The results are shown in Listing 10.2 Output.
Listing 10.2 util_inherit.js
: Using inherits() to inherit the prototypes from events.EventEmitter
01 var util = require("util"); 02 var events = require("events"); 03 function Writer() { 04 events.EventEmitter.call(this); 05 } 06 util.inherits(Writer, events.EventEmitter); 07 Writer.prototype.write = function(data) { 08 this.emit("data", data); 09 }; 10 var w = new Writer(); 11 console.log(w instanceof events.EventEmitter); 12 console.log(Writer.super_ === events.EventEmitter); 13 w.on("data", function(data) { 14 console.log('Received data: "' + data + '"'); 15 }); 16 w.write("Some Data!");
Listing 10.2 Output util_inherit.js
: Using inherits()
to inherit the prototypes from events.EventEmitter
true true Received data: "Some Data!"
dns
ModuleIf your Node.js application needs to resolve DNS domain names, look up domains, or do reverse lookups, then the dns
module is helpful. A DNS lookup contacts the domain name server and requests records about a specific domain name. A reverse lookup contacts the domain name server and requests the DNS name associated with an IP address. The dns
module provides functionality for most of the lookups that you may need to perform. Table 10.2 lists the lookup calls and their syntax, and describes how they are used.
Table 10.2 Methods that can be called on the dns
Module
Event |
Description |
|
Resolves the function (error, addresses) |
|
Resolves the The function (error, addresses) |
Same as |
|
|
Same as |
|
Same as |
|
Same as |
|
Same as |
|
Same as |
|
Same as |
|
Does a reverse lookup on the function (error, domains) |
Listing 10.3 illustrates performing lookups and reverse lookups. In line 3, resolve4()
is used to look up the IPv4 addresses, and then in lines 5–8, reverse()
is called on those same addresses and the reverse lookup performed. Listing 10.3 Output shows the result.
Listing 10.3 dns_lookup.js
: Performing lookups and then reverse lookups on domains and IP addresses
01 var dns = require('dns'); 02 console.log("Resolving www.google.com . . ."); 03 dns.resolve4('www.google.com', function (err, addresses) { 04 console.log('IPv4 addresses: ' + JSON.stringify(addresses, false, ' ')); 05 addresses.forEach(function (addr) { 06 dns.reverse(addr, function (err, domains) { 07 console.log('Reverse for ' + addr + ': ' + JSON.stringify(domains)); 08 }); 09 }); 10 });
Listing 10.3 Output dns_lookup.js
: Performing lookups and then reverse lookups on domains and IP addresses
Resolving www.google.com . . . IPv4 addresses: [ "172.217.6.68" ] Reverse for 172.217.6.68: ["sfo07s17-in-f4.1e100.net","sfo07s17-in-f68.1e100.net"]
crypto
ModuleThe crypto
module is interesting and fun to play around with. As the name suggests, it creates cryptographic information, or in other words, creates secure communication using secret code. To use crypto
, you must make sure that it is loaded into your Node project. Although cool, this module isn’t necessary, and a Node application can be built without including support for crypto
. The easiest way to do ensure crypto
is loaded is to use a simple try catch (err)
; for example:
let crypto; try { crypto = require('crypto'); } catch (err) { console.log('crypto support is disabled!'); }
The crypto
module includes several classes that provide functionality to encrypt and decrypt data and streams. Table 10.3 lists all the different classes that the crypto
module provides.
Table 10.3 Classes that can be used in the crypto
module
Class |
Description |
|
Used for working with SPKAC (a certificate signing request mechanism) and primarily used to handle output of HTML5. |
|
Used to encrypt data in either a stream that is both readable and writable, or using the |
|
The opposite of |
|
Used to create key exchanges for Diffie-Hellman (a specific method for exchanging cryptographic keys). |
|
Used to create key exchanges for ECDH (same as Diffie-Hellman, but the two parties use an elliptical curve public-private key pair). |
Used to create hash digests of data using a readable and writable stream or |
|
|
Used to create Hmac digests of data using a readable and writable stream or |
|
Used to generate signatures. |
|
Used in tandem with |
The most common use for the crypto
module is to use the Cipher
and Decipher
classes to create encrypted data that can be stored and decrypted later; for example, passwords. Initially, passwords are entered as text, but it would be foolish to actually store them as text. Instead, passwords are encrypted using an encryption algorithm such as the ('aes192')
method. This allows you to store data encrypted so if it is accessed without decrypting, your password is protected from prying minds. Listing 10.4 shows an example of encrypting and decrypting a password string. The output follows in Listing 10.4 Output.
Listing 10.4 encrypt_password.js
:
Using cipher
and decipher
to encrypt and then decrypt data
var crypto = require('crypto'); var crypMethod = 'aes192'; var secret = 'MySecret'; function encryptPassword(pwd){ var cipher = crypto.createCipher(crypMethod, secret); var cryptedPwd = cipher.update(pwd,'utf8','hex'); cryptedPwd += cipher.final('hex'); return cryptedPwd; } function decryptPassword(pwd){ var decipher = crypto.createDecipher(crypMethod, secret); var decryptedPwd = decipher.update(pwd,'hex','utf8'); decryptedPwd += decipher.final('utf8'); return decryptedPwd; } var encryptedPwd = encryptPassword("BadWolf"); console.log("Encrypted Password"); console.log(encryptedPwd); console.log(" Decrypted Password"); console.log(decryptPassword(encryptedPwd));
Listing 10.4 Output Using cipher
and decipher
to encrypt and then decrypt data
Encrypted Password 0ebc7d846519b955332681c75c834d50 Decrypted Password BadWolf
This section lists some other Node modules and objects that would be beneficial for you to know about:
Global: Object available throughout all the modules. Globals range anywhere from _dirname
, which gives you the name of the directory, to the Process
object.
V8: Module used to expose APIs, specifically for the version of V8 that is built in to the Node binary.
Debugger: Module used to debug your Node application. To use, simply start Node with the debug
argument, like so: $ node debug myscript.js
.
Assertion testing: Module that provides a basic set of assertion tests used to test invariants.
C/C++ add-ons: Objects that allow you to dynamically link shared objects written in C or C++. They provide an interface that both JavaScript in Node and C/C++ libraries can use, allowing them to work as a regular Node.js applications.
REPL (Read Event Print Loop): Accepts individual lines of input, evaluates them using a user-defined function, and then outputs the results.
The os
module allows you to get information about the system, including the operating system type and version, the platform architecture, and programming helps, such as the amount of free memory, temp folder location, and EOL characters. The util
module is the catch-all library for Node that has methods for synchronous output, string formatting, and type checking. The dns
module performs DNS lookups and reverse lookups from a Node.js application. The crypto
module encrypts and decrypts data to secure private data.
In the next chapter, you jump into the world of MongoDB. You learn the MongoDB basics and how to implement it in the Node.js world.
18.224.59.192