
In questo tutorial vedremo come usare le API di SSL Labs per verificare la qualità di un certificato SSL con Node.js e i WebSocket.
Per usare le API di SSL Labs occorre effettuare chiamate ad intervalli regolari verso un medesimo endpoint per ottenere lo status attuale del processo di valutazione del certificato.
A tale scopo occorre creare una classe che ci consenta di ripetere la medesima azione senza incorrere nel rischio dei memory
leak insito nell'uso diretto del metodo setInterval()
.
'use strict';
const { EventEmitter } = require('events');
class Scheduler extends EventEmitter {
constructor(action = function () {}, ms = 2000) {
super();
this.action = action;
this.handle = undefined;
this.interval = ms;
this.on('timeout', () => {
this.action(this);
});
}
start() {
if (!this.handle) {
this.handle = setInterval(() => this.emit('timeout'), this.interval);
}
}
stop() {
if (this.handle) {
clearInterval(this.handle);
this.handle = undefined;
}
}
}
module.exports = Scheduler;
Usando gli eventi possiamo controllare con molta più precisione il ripetersi della medesima richiesta HTTP alle API remote. Creiamo quindi una classe per effettuare tale richiesta. Useremo i moduli got (versione 11.8.3) per le richieste HTTP e validator per la validazione dei dati.
'use strict';
const API_URL = 'https://api.ssllabs.com/api/v3/analyze';
const got = require('got');
const validator = require('validator');
class ApiClient {
static fetch(host) {
if(!validator.isFQDN(host)) {
return Promise.reject(new Error('Invalid parameter.'));
}
return got(`${API_URL}?host=${host}`).json();
}
}
module.exports = ApiClient;
In ExpressJS possiamo creare un WebSocket sfruttando l'istanza del server HTTP creata dall'applicazione. Quindi riceviamo dal client il nome dell'host e restituiamo i dati che ci giungono dalle API remote ad intervalli regolari. Usiamo il modulo ws per creare e gestire i WebSocket.
const wsServer = new ws.Server({ noServer: true });
wsServer.on('connection', socket => {
socket.on('message', message => {
const host = message.toString();
const task = new Scheduler(async timer => {
try {
const data = await Client.fetch(host);
const { status, endpoints } = data;
socket.send(JSON.stringify({
status,
endpoints
}));
if(status.toLowerCase() === 'ready') {
timer.stop();
}
} catch(err) {
timer.stop();
}
}, 2000);
task.start();
});
});
Quando SSL Labs ci comunica che i test si sono conclusi (lo status finale è "READY") abbiamo accesso anche al voto finale (da A ad F) contenuto negli array degli endpoint che corrisponde all'elenco dei test effettuati.