4. Opening Handshake (Handshake di apertura)
L'handshake di apertura (Opening Handshake) del protocollo WebSocket è progettato per essere compatibile con l'infrastruttura HTTP esistente. L'handshake è una richiesta HTTP Upgrade.
4.1 Client Requirements (Requisiti del client)
La richiesta di handshake inviata dal client deve essere una richiesta HTTP valida nel seguente formato:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Extensions: permessage-deflate
Campi header obbligatori
Host
- Contiene l'host e il numero di porta del server
- Conforme alla specifica HTTP/1.1
Upgrade: websocket
- deve (MUST) includere questo header
- Il valore è "websocket" (case-insensitive)
Connection: Upgrade
- deve (MUST) includere questo header
- Indica che questa è una richiesta Upgrade
Sec-WebSocket-Key
- deve (MUST) includere questo header
- Valore di 16 byte generato casualmente, codificato in Base64
- Utilizzato per verificare che il server comprenda il protocollo WebSocket
Sec-WebSocket-Version: 13
- deve (MUST) includere questo header
- Il numero di versione corrente è 13
Campi header opzionali
Origin
- I client browser devono (MUST) includerlo
- I client non-browser possono (MAY) includerlo
- Utilizzato per la validazione di sicurezza lato server
Sec-WebSocket-Protocol
- opzionale (OPTIONAL)
- Specifica l'elenco dei sottoprotocolli supportati dal client
- Più valori separati da virgole
Sec-WebSocket-Extensions
- opzionale (OPTIONAL)
- Specifica le estensioni supportate dal client
- Formato:
extension-name [; parameter=value]*
4.2 Server-Side Requirements (Requisiti lato server)
Il server deve validare l'handshake del client e restituire una risposta appropriata.
4.2.1 Reading the Client's Opening Handshake (Lettura dell'handshake del client)
Il server deve (MUST) validare quanto segue:
- Metodo HTTP: Deve essere GET
- Versione HTTP: Almeno HTTP/1.1
- Header obbligatori: Host, Upgrade, Connection, Sec-WebSocket-Key, Sec-WebSocket-Version devono essere presenti
- Sec-WebSocket-Version: Deve essere 13 (o una versione supportata dal server)
Se la validazione fallisce, il server dovrebbe (SHOULD) restituire un codice di stato di errore HTTP appropriato.
4.2.2 Sending the Server's Opening Handshake (Invio dell'handshake del server)
Se la validazione ha successo, il server deve (MUST) inviare una risposta di handshake:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Calcolo di Sec-WebSocket-Accept
Questa è una parte critica dell'handshake. Il server deve calcolare come segue:
- Prendere il valore
Sec-WebSocket-Keydel client - Concatenare con la stringa GUID fissa:
258EAFA5-E914-47DA-95CA-C5AB0DC85B11 - Eseguire l'hash SHA-1 sulla stringa concatenata
- Codificare in Base64 il risultato dell'hash
Esempio di algoritmo (JavaScript):
const crypto = require('crypto');
function generateAcceptKey(clientKey) {
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
const concatenated = clientKey + GUID;
const hash = crypto.createHash('sha1').update(concatenated).digest();
return hash.toString('base64');
}
// Esempio
const clientKey = 'dGhlIHNhbXBsZSBub25jZQ==';
const acceptKey = generateAcceptKey(clientKey);
console.log(acceptKey); // s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
4.3 Collecting Extensions and Subprotocols (Raccolta di estensioni e sottoprotocolli)
Negoziazione dei sottoprotocolli
Il client può elencare più sottoprotocolli nell'header Sec-WebSocket-Protocol:
Sec-WebSocket-Protocol: chat, superchat
Il server deve (MUST) selezionarne uno (o nessuno) dall'elenco del client e restituirlo nella risposta:
Sec-WebSocket-Protocol: chat
Se il server non supporta nessuno dei sottoprotocolli richiesti dal client, può omettere l'header Sec-WebSocket-Protocol.
Negoziazione delle estensioni
La negoziazione delle estensioni avviene tramite l'header Sec-WebSocket-Extensions:
Richiesta del client:
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Risposta del server:
Sec-WebSocket-Extensions: permessage-deflate
Il server può accettare, modificare i parametri o rifiutare le estensioni.
4.4 Supporting Multiple Versions (Supporto di più versioni)
Se il server non supporta la versione richiesta dal client, dovrebbe (SHOULD) restituire HTTP 426 Upgrade Required e includere un header Sec-WebSocket-Version che elenca le versioni supportate:
HTTP/1.1 426 Upgrade Required
Sec-WebSocket-Version: 13, 8, 7
Esempi completi di handshake
Handshake riuscito
Client → Server:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com
Server → Client:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Esempi di handshake fallito
Versione non supportata:
HTTP/1.1 426 Upgrade Required
Sec-WebSocket-Version: 13
Origin non accettata:
HTTP/1.1 403 Forbidden
Considerazioni sulla sicurezza
- Validare Origin: I server dovrebbero validare l'header
Originper prevenire attacchi cross-site - Utilizzare TLS: Utilizzare wss:// negli ambienti di produzione
- Validare tutti gli header: Assicurarsi che tutti gli header obbligatori siano presenti e correttamente formattati
- Limitare le connessioni: Implementare rate limiting per prevenire attacchi DoS
Link di riferimento
- Capitolo precedente: 3. WebSocket URIs
- Capitolo successivo: 5. Data Framing (Frammentazione dei dati)
- Esempio di implementazione: Calcolo della chiave di handshake