SocksClient.createConnection restituisce un flusso connesso alla destinazione richiesta. Per HTTPS quel flusso ha ancora bisogno di un handshake TLS prima di trasportare la richiesta HTTP.

import { SocksClient } from 'socks';
import tls from 'node:tls';

const targetHost = 'service.example';
const info = await SocksClient.createConnection({
  proxy: { host: 'proxy.example', port: 1080, type: 5 },
  command: 'connect',
  destination: { host: targetHost, port: 443 },
  timeout: 10000,
});
const secure = tls.connect({
  socket: info.socket,
  servername: targetHost,
});
secure.on('error', onTransportError);
secure.on('data', onResponseBytes);
secure.once('secureConnect', () => {
  secure.write(
    `GET /data HTTP/1.1\r\nHost: ${targetHost}\r\nConnection: close\r\n\r\n`
  );
});

L'elenco dei proxy SOCKS5 fornisce candidati per l'host e la porta del proxy. onTransportError e onResponseBytes appartengono all'applicazione esistente; il secondo deve analizzare il flusso di risposta HTTP. I blocchi di dati TLS non sono messaggi HTTP completi in modo autonomo.

Il servername è il nome DNS della destinazione. Il tls.connect di basso livello di Node non abilita SNI per impostazione predefinita, e il nome host del proxy non è l'identità del certificato del sito.

Lascia attiva la verifica del certificato. Fornire il socket connesso evita di aprire una connessione diretta separata verso il sito e ne preserva l'identità TLS.

Il timeout SOCKS limita quella negoziazione. Lo scambio TLS e applicativo successivo richiede comunque il timeout, la cancellazione e la politica di pulizia previsti dal chiamante.

Articoli correlati