Search code examples
javascriptnode.jshttpserverresponse.write

HTTP File Servers and the .writeHead method


The goal of this exercise is to create an HTTP server that serves the same text file for each request that it receives. Here is my code. It doesn't work.

   var http = require ('http');
    var fs = require ('fs');
    var port = process.argv[2];
    var file = process.argv[3];
    var bl = require ('bl');

var server = http.createServer(function (request, response) {
    var stream = fs.createReadStream(file);
    var streamPipe = stream.pipe(response);
    response.write(streamPipe);
    });

server.listen(port);

I checked the correct answer, and that is to place the following code at the first line of the function, and remove my response.write() method:

response.writeHead(200, { 'content-type': 'text/plain' }); 

instead of my code, which I thought would write the data piped from the request stream to the response stream (line 10):

response.write(streamPipe)

I don't understand. Shouldn't response.writeHead go after the stream is established using the .createReadStream method, and not before?

Aren't I sending already existing data with response.write()? I want this to return a string and not an object, but the parameter has to be a string first, otherwise it doesn't work. The toString() method returns [object Object].

Can someone please explain the parameters of the writeHead method, and why it goes before everything else?

I realize this is a loaded question. I'm new to node, really excited to learn, but I just find it so difficult to understand. I have pretty basic JavaScript experience, and some Java, so I appreciate any and all help for an aspiring node.js developer.


Solution

  • Each HTTP response has three things: status, headers and content (which can be empty).

    Status simply tells a status of response, e.g. 200 OK, 404 Not Found, 500 Internal Server Error, etc.

    Headers is a sequence of key: value pairs which contain various meta data about the response like Content-Type: text/plain or Content-Length: 123456. Some of them are mandatory like Content-Length (actually there is a case when it is not, i.e. chunked encoding) and other are not.

    And finally content is just a sequence of bytes.

    And moreover that's exactly the order of those things in HTTP response stream. First there's status, then headers and at the end the content.

    So you will always call response.writeHead method as first because this method sends both status and headers to the client. It accepts a pair (status_code, headers_object) as arguments where status_code is just a number and headers_object is an object {key1: value1, key2: value2} that will be converted to headers sequence.

    Finally response.write method sends a chunk of the content to the client. It accepts a string as an argument.

    Read more about response methods here: https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback

    Note that you don't use response.write method explicitely in your example because stream.pipe(response) does that under the hood for you. Read this:

    https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options