Trabajando con HTTP 2 en Node JS 10

Publicado el 26 julio 2018 por Juan Ricardo Castro Lurita @pepoflex

En unos años el protocolo de Navegación más rápido y moderno será HTTP 2, los desarrolladores que se encargan de darle mantenimiento a Node JS ya están trabajando en una versión experimental del modulo http2, en este articulo veremos todos los detalles.

En Node JS 10 existe de manera experimental un módulo para trabajar con el protocolo http 2 que en unos años probablemente termine siendo estable, para acceder a este módulo podemos escribir:

const http2 = require('http2');

Una característica del módulo http 2 es que la conexión entre el servidor y el cliente es más simétrica, con esto podemos obtener eventos de tipo ‘error’ , ‘connect’ y ‘stream’ en el propio código del lado del cliente o del servidor.

Conexión Http 2 de Lado del Cliente

En el siguiente ejemplo accedemos como usuario o cliente a un servidor, este debe tener un certificado .pem y la data la mostramos con la codificación estándar UTF-8

const http2 = require('http2');
const fs = require('fs');
const client = http2.connect('https://localhost:8443', {
  ca: fs.readFileSync('localhost-cert.pem')
});
client.on('error', (err) => console.error(err));

const req = client.request({ ':path': '/' });

req.on('response', (headers, flags) => {
  for (const name in headers) {
    console.log(`${name}: ${headers[name]}`);
  }
});

req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
  console.log(`\n${data}`);
  client.close();
});
req.end();

Conexión Http 2 de Lado del Servidor

El siguiente ejemplo ser servidor cuenta con una key y un certificado, ambos en formato .pem, así mismo usamos http2.createSecureServer para que el servidor se conecte de manera segura con los clientes que tienen o tendrán acceso al servidor, mostramos el estado 200 cuando el servidor funcione correctamente.

const http2 = require('http2');
const fs = require('fs');

const server = http2.createSecureServer({
  key: fs.readFileSync('localhost-privkey.pem'),
  cert: fs.readFileSync('localhost-cert.pem')
});
server.on('error', (err) => console.error(err));

server.on('stream', (stream, headers) => {
  // stream is a Duplex
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });
  stream.end('<h1>Hola Mundo</h1>');
});

server.listen(8443);

Sesiones en Http2

Mediante la clase http2.Http2Session se puede establecer una sesión activa para un usuario, este debe intentar acceder al servidor por medio de un cliente con protocolo Http 2 para consumir los datos o contenidos del servidor como podemos ver en la siguiente imagen.

imagen: webtuga.pt

Cada sesión puede tener comportamientos diferentes durante su navegación, variará si la sesión es como cliente o como servidor, podemos indicarle el modo en que Http2Session iniciará una sesión con http2session.type

Http2Session y Sockets

Con la llegada del protocolo Http2 los Sockets tendrán una forma diferente de trabajar en Node JS, como la clase Http2Session se vincula a net.Socket o tls.TLSS por cada sesión que es creada, así mismo cuando se termina una sesión el Socket y la sesión con Http2Session son destruidos.

A continuación vermos una lista de eventos que se producen cuando se trabaja con Http2Session y Sockets.

Evento: ‘close’

Fue agregado en la versión 8.4.0 de Node JS

Se produce cada ves que una sesión bajo Http2Session es finalizada o destruida.

Evento: ‘connect’

Fue agregado en la versión 8.4.0 de Node JS

Se produce cada ves que Http2Session se ha conectado correctamente en la sesión.

Evento: ‘error’

Fue agregado en la versión 8.4.0 de Node JS

Se produce cuando hay problemas de procesamiento con Http2Session.

Evento: ‘localSettings’

Fue agregado en la versión 8.4.0 de Node JS

Cuando envías una nueva configuración con http2session.settings() esta configuracion no surge efecto hasta que se emita el evento ‘localSettings’ , por ejemplo:

session.settings({ enablePush: false });

session.on('localSettings', (settings) => {
  /* Acá usamos la nueva configuración */
});

Evento: ‘timeout’

Fue agregado en la versión 8.4.0 de Node JS

Si estableces un tiempo para una sesión con http2session.setTimeout() se emite un evento cuando el tiempo se acabo y ya no hay actividad en Http2Session por ejemplo:

session.setTimeout(5000); /* Establecemos 5 segundos */
session.on('timeout', () => { /* .. */ });

Manejo Estricto de Caracteres no Válidos

Por el momento en http 2  se exige estrictamente no usar caracteres inválidos cuando declares un un nombre o los valores de una encabezado. Los encabezados no distinguen entre mayúsculas y minúsculas, cada ves que envíes un encabezado como Content-Type los convertirá a content-type cuando sea enviado.

Las cabecera que envies debe contener uno o más de los siguientes caracteres ASCII: a- z, A- Z, 0- 9, !, #, $, %, &, ‘, *, +, -, ., ^, _, ` (acento grave), |y ~.

Cuando intentas pasar un carácter invalido, se cerrará con un error que se muestra en pantalla. A continuación un ejemplo de envío de cabeceras de manera limpia:

// nos retorna content-type = text/plain
const server = http2.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});

Hay muchos puntos por hablar sobre Http 2 en Node JS, en otro artículo detallaremos más sobre este interesante tema.

Síguenos en las Redes Sociales para que no te pierdas nuestros próximos contenidos.