Understanding content types
A client will often pass along a request header indicating the expected response MIME (Multi-purpose Internet Mail Extension) type. Clients will also indicate the MIME type of a request body. Servers will similarly provide header information about the MIME type of a response body. The MIME type for HTML is text/html, for example.
As we have seen, it is the responsibility of an HTTP response to set headers describing the entity it contains. Similarly, a GET request will normally indicate the resource type, the MIME type, it expects as a response. Such a request header might look like this:
Accept: text/html
It is the responsibility of a server receiving such instructions to prepare a body entity conforming to the sent MIME type, and if it is able to do so, it should return a similar response header:
Content-Type: text/html; charset=utf-8
Because requests also identify the specific resource desired (such as /files/index.html), the server must ensure that the requested resource it is streaming back to the client is in fact of the correct MIME type. While it may seem obvious that a resource identified by the extension html is in fact of the MIME type text/html, this is not at all certain—a filesystem does nothing to prevent an image file from being given an html extension. Parsing extensions is an imperfect method of determining file type. We need to do more.
The UNIX file program is able to determine the MIME type of a system file. For example, one might determine the MIME type of a file without an extension (for example, resource) by running this command:
file --brief --mime resource
We pass arguments instructing file to output the MIME type of resource, and that the output should be brief (only the MIME type, and no other information). This command might return something like text/plain; charset=us-ascii. Here, we have a tool to solve our problem.
For more information about the file utility consult, go to: http://man7.org/linux/man-pages/man1/file.1.html
Recalling that Node is able to spawn child processes, we have a solution to our problem of accurately determining the MIME type of system files. We can use the Node command exec method of Node's child_process module in order to determine the MIME type of a file, like so:
let exec = require('child_process').exec;
exec("file --brief --mime resource", (err, mime) => {
console.log(mime);
});
This technique is also useful when validating a file streamed in from an external location. Following the axiom "never trust the client", it is always a good idea to check whether the Content-type header of a file posted to a Node server matches the actual MIME type of the received file as it exists on the local filesystem.