• No se han encontrado resultados

6. ANÁLISIS DE LAS NUEVAS TENDENCIAS QUE AFECTAN AL DESARROLLO ORGANIZACIONAL

6.2 Organizaciones en constante aprendizaje

6.2.1 Innovación

The protocol is structured around the concept of requests and responses, materialized in Node. JS as objects of the http.ServerRequest and http.ServerResponse constructors,

respectively.

When a user first browses to a website, the user agent (the browser) creates a request that gets sent to the web server over TCP, and a response is emitted.

What do requests and responses look like? To find out, first create a Hello World Node HTTP server that listens on http://localhost:3000:

require(‘http’).createServer(function (req, res) { res.writeHead(200);

res.end(‘Hello World’);

}).listen(3000);

Next, establish a telnet connection and write your own request:

GET / HTTP/1.1

After typing GET / HTTP/1.1, press Enter twice.

The response, illustrated in Figure 7-1, comes in right afterward!

Figure 7-1: The response produced by our HTTP server.

The response text looks like this:

HTTP/1.1 200 OK Connection: keep-alive Transfer-Encoding: chunked

C H A P T E R 7 • HTTP

89

b

Hello World 0

The first relevant section of this response is the headers, which you’ll read about next.

HEADERS

As you can see, HTTP is a protocol in the same fashion as IRC. Its purpose is to enable the exchange of documents. It utilizes headers that precede both requests and responses to describe different aspects of the communication and the content.

As an example, think of the different types of content that web pages deliver: text, HTML, XML, JSON, PNG and JPEG images, and a large number of other possibilities.

The type of content that’s sent is annotated by the famous Content-Type header.

Look at how this applies in practice. Bring back hello world, but this time add some HTML in there:

require(‘http’).createServer(function (req, res) { res.writeHead(200);

res.end(‘Hello <b>World</b>’);

}).listen(3000);

Notice that the word World is surrounded by bold tags. You can check it out with the rudi- mentary TCP client again (see Figure 7-2).

Figure 7-2: The Hello <b>World</b> response

90

PA R T I I • Essential Node APIs GET / HTTP/1.1 HTTP/1.1 200 OK Connection: keep-alive Transfer-Encoding: chunked 12 Hello <b>World</b> 0

Now, however, see what happens when you look at it with a browser (see Figure 7-3).

Figure 7-3: The browser shows the response as plain text.

That doesn’t look like rich text, but why?

As it occurs, the HTTP client (the browser) doesn’t know what type of content you’re sending because you didn’t include that as part of your communication. The browser therefore considers what you’re seeing as content type text/plain, or normal plain text, and doesn’t

try to render it as HTML.

If you adjust the code to include the appropriate header, you fix the problem (see Figure 7-4):

require(‘http’).createServer(function (req, res) { res.writeHead(200, { ‘Content-Type’: ‘text/html’ }); res.end(‘Hello <b>World</b>’);

C H A P T E R 7 • HTTP

91

Figure 7-4: The response, this time with the additional header.

The response text is as follows:

HTTP/1.1 200 OK Content-Type: text/html Connection: keep-alive Transfer-Encoding: chunked 12 Hello <b>World</b> 0

Notice the header is included as part of the response text. The same response is parsed out by the browser (see Figure 7-5), which now renders the HTML correctly.

92

PA R T I I • Essential Node APIs

Notice that despite having specified a header with the writeHead API call, Node still

includes two other headers: Transfer-Encoding and Connection.

The default value for the Transfer-Encoding header is chunked. The main reason for

this is that due to Node asynchronous nature, it’s not rare for a response to be created progressively.

Consider the following example:

require(‘http’).createServer(function (req, res) { res.writeHead(200); res.write(‘Hello’); setTimeout(function () { res.end(‘World’); }, 500); }).listen(3000);

Notice that you can send data as part of multiple write calls, before you call end. In the

spirit of trying to respond as fast as possible to clients, by the time the first write is called,

Node can already send all the response headers and the first chunk of data (Hello).

Later on, when the setTimeout callback is fired, another chunk can be written. Since this

time around you use end instead of write, Node finishes the response and no further writes

are allowed.

Another instance where writing in chunks is very efficient is when the file system is involved. It’s not uncommon for web servers to serve files like images that are somewhere in the hard drive. Since Node can write a response in chunks, and also allows us to read a file in chunks, you can leverage the ReadStream filesystem APIs for this purpose.

The following example reads the image image.png and serves it with the right Content- Type header:

require(‘http’).createServer(function (req, res) { res.writeHead(200, { ‘Content-Type’: ‘image/png’); var stream = require(‘fs’).createReadStream(‘image.png’); stream.on(‘data’, function (data) {

res.write(data); }); stream.on(‘end’, function () { res.end(); }); }).listen(3000);

C H A P T E R 7 • HTTP

93

By writing the image as a series of chunks, you ensure:

◾ Efficient memory allocation. If you read the image completely for each request prior to

writing it (by leveraging fs.readFile), you’d probably end up using more memory

over time when handlings lots of requests.

◾ You write data as soon as it becomes available to you.

In addition, notice that what you’re doing is piping one Stream (an FS one) onto another (an http.ServerResponse object). As I’ve mentioned before, streams are a very important

abstraction in Node.JS. Piping streams is a very common action, so Node.JS offers a method to make the above example very succinct:

require(‘http’).createServer(function (req, res) { res.writeHead(200, { ‘Content-Type’: ‘image/png’); require(‘fs’).createReadStream(‘image.png’).pipe(res); }).listen(3000);

Now that you understand why Node defaults to a chunked transfer encoding, let’s talk about