SocksClient.createConnection renvoie un flux connecté à la destination demandée. Pour HTTPS, ce flux a encore besoin d'une poignée de main TLS avant de transporter la requête 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`
  );
});

La liste de proxys SOCKS5 fournit des candidats pour l'hôte et le port du proxy. onTransportError et onResponseBytes appartiennent à l'application existante ; le second doit analyser le flux de réponse HTTP. Les fragments de données TLS ne sont pas des messages HTTP complets de façon autonome.

Le servername est le nom DNS de la destination. Le tls.connect bas niveau de Node n'active pas SNI par défaut, et le nom d'hôte du proxy n'est pas l'identité du certificat du site.

Laissez la vérification du certificat activée. Fournir la socket connectée évite d'ouvrir une connexion directe séparée vers le site tout en préservant son identité TLS.

Le délai SOCKS borne cette négociation. L'échange TLS et applicatif ultérieur a toujours besoin du délai, de l'annulation et de la politique de nettoyage prévus par l'appelant.

Articles similaires