Passa al contenuto principale

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:

  1. Metodo HTTP: Deve essere GET
  2. Versione HTTP: Almeno HTTP/1.1
  3. Header obbligatori: Host, Upgrade, Connection, Sec-WebSocket-Key, Sec-WebSocket-Version devono essere presenti
  4. 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:

  1. Prendere il valore Sec-WebSocket-Key del client
  2. Concatenare con la stringa GUID fissa: 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
  3. Eseguire l'hash SHA-1 sulla stringa concatenata
  4. 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

  1. Validare Origin: I server dovrebbero validare l'header Origin per prevenire attacchi cross-site
  2. Utilizzare TLS: Utilizzare wss:// negli ambienti di produzione
  3. Validare tutti gli header: Assicurarsi che tutti gli header obbligatori siano presenti e correttamente formattati
  4. Limitare le connessioni: Implementare rate limiting per prevenire attacchi DoS