← Retour au blog

WebSocket, gRPC, HTTP/2 via proxy : comment choisir le protocole pour votre stack

Nous examinons les particularités du proxy WebSocket, gRPC et HTTP/2 : quel protocole choisir, comment configurer un serveur proxy et éviter les erreurs fréquentes des développeurs.

📅21 septembre 2026

Lors de l'utilisation de proxies, les développeurs se heurtent souvent au fait que les configurations classiques de proxy HTTP ne fonctionnent pas pour les connexions WebSocket, et que gRPC échoue complètement avec des erreurs de handshake TLS. Le problème est que WebSocket, HTTP/2 et gRPC ne sont pas simplement des « variantes d'HTTP », mais des modèles de transport différents avec leurs propres exigences en matière de tunneling, de multiplexage et de gestion des en-têtes. Dans cet article, nous allons examiner comment proxy chaque protocole, quels pièges se présentent dans la pratique et comment choisir le protocole et le type de proxy pour une tâche spécifique - du parsing via WebSocket aux microservices gRPC à fort trafic.

Quelles sont les différences entre les protocoles et pourquoi cela est important pour le proxy

HTTP/1.1 fonctionne selon le modèle « requête - réponse » : le client ouvre une connexion, envoie une requête, reçoit une réponse et ferme la connexion ou la garde ouverte pour la prochaine requête (keep-alive). Les serveurs proxy ont été optimisés pendant des décennies pour ce modèle - parsing des en-têtes, mise en tampon du corps de la requête, routage simple basé sur l'en-tête Host.

WebSocket casse ce modèle : après le handshake HTTP initial (Upgrade: websocket), la connexion se transforme en un canal bidirectionnel permanent, où les données peuvent circuler dans les deux sens à tout moment. Le proxy doit « relâcher » cette connexion et simplement transférer les octets dans les deux sens, sans essayer de les interpréter comme des requêtes HTTP.

HTTP/2 ajoute le multiplexage - plusieurs requêtes logiques passent par une seule connexion TCP en parallèle, utilisant des trames binaires au lieu d'en-têtes textuels. Pour le proxy, cela signifie qu'il ne suffit pas de lire le texte ligne par ligne - un support du protocole binaire HTTP/2 au niveau du proxy ou un tunneling TCP transparent sur TLS est nécessaire.

gRPC va encore plus loin : il est strictement construit sur HTTP/2, utilise Protocol Buffers pour la sérialisation et nécessite un transport compatible HTTP/2 sur tout le chemin du client au serveur. Si le proxy « rétrograde » la connexion à un moment donné à HTTP/1.1, la requête gRPC ne passera tout simplement pas.

Comprendre ces différences est critique, car le choix d'un mauvais type de proxy ou une mauvaise configuration du tunneling entraîne des coupures de connexion, des timeouts et des erreurs difficiles à expliquer, qui sont difficiles à diagnostiquer sans comprendre le niveau de transport.

WebSocket via proxy : configuration et code

Pour WebSocket via proxy, il existe deux scénarios principaux : un proxy HTTP avec la méthode CONNECT (pour WSS, c'est-à-dire WebSocket sur TLS) et un proxy SOCKS5, qui tunnelise la connexion TCP sans distinction de protocole. SOCKS5 pose généralement moins de problèmes, car il a été conçu dès le départ comme un « tuyau transparent » pour tout le trafic TCP.

Exemple de connexion à WebSocket via un proxy SOCKS5 en Python avec la bibliothèque websockets et python-socks :

import asyncio
from python_socks.sync import Proxy
import websockets
import websockets.sync.client as ws_client

def connect_ws_via_proxy():
    proxy = Proxy.from_url("socks5://user:pass@proxy_host:1080")
    sock = proxy.connect(dest_host="echo.websocket.events", dest_port=443)

    ws = ws_client.connect(
        "wss://echo.websocket.events",
        sock=sock,
        server_hostname="echo.websocket.events"
    )
    ws.send("Hello via proxy")
    print(ws.recv())
    ws.close()

connect_ws_via_proxy()

Sur Node.js, une tâche similaire est résolue via le package ws en combinaison avec socks-proxy-agent :

const WebSocket = require('ws');
const { SocksProxyAgent } = require('socks-proxy-agent');

const agent = new SocksProxyAgent('socks5://user:pass@proxy_host:1080');
const socket = new WebSocket('wss://echo.websocket.events', { agent });

socket.on('open', () => socket.send('Hello via proxy'));
socket.on('message', (data) => console.log(data.toString()));

Si le proxy n'est accessible que via HTTP (avec la méthode CONNECT), le schéma est similaire - la plupart des clients WebSocket modernes savent travailler via un tunnel HTTP, il est juste important de s'assurer que le proxy ne coupe pas les connexions de longue durée à cause d'un timeout. C'est un problème fréquent avec les proxies de centres de données bon marché, qui ont une limite stricte de 30 à 60 secondes pour une connexion inactive - pour les tâches WebSocket de streaming, c'est critique, et il vaut mieux clarifier les paramètres de keep-alive avec le fournisseur.

HTTP/2 via proxy : multiplexage et pièges

La principale difficulté avec HTTP/2 via proxy est que de nombreux serveurs proxy (en particulier les anciens Squid ou les simples proxies de transfert) ne fonctionnent qu'avec HTTP/1.1 et rétrogradent automatiquement la connexion. Pour le client, cela est souvent imperceptible (la requête est tout de même exécutée), mais les avantages du multiplexage sont perdus - les latences augmentent, surtout avec un grand nombre de requêtes parallèles vers un même hôte.

Pour vérifier si la connexion via proxy prend en charge HTTP/2, vous pouvez utiliser cURL avec le drapeau --http2 et une sortie détaillée :

curl -v --http2 -x http://user:pass@proxy_host:8080 https://example.com

# Dans la sortie, recherchez la ligne :
# * Using HTTP2, server supports multiplexing
# Si elle n'est pas présente, la connexion a été rétrogradée à HTTP/1.1

En Python, pour HTTP/2 via proxy, vous avez besoin de la bibliothèque httpx avec le support HTTP/2 activé :

import httpx

proxies = {
    "http://": "http://user:pass@proxy_host:8080",
    "https://": "http://user:pass@proxy_host:8080",
}

with httpx.Client(proxies=proxies, http2=True) as client:
    response = client.get("https://example.com")
    print(response.http_version)  # nous attendons "HTTP/2"
    print(response.status_code)

Un point important : HTTP/2 nécessite TLS avec l'extension ALPN pour la négociation du protocole, donc le proxy doit tunneliser le trafic TLS de manière transparente via CONNECT, et non terminer TLS lui-même (sauf s'il s'agit d'un proxy spécialisé compatible HTTP/2). C'est pourquoi pour les tâches avec HTTP/2, les proxies résidentiels et les proxies de centres de données se comportent différemment - il est important de vérifier auprès du fournisseur si le tunneling TLS de bout en bout est pris en charge sans rupture des négociations ALPN.

gRPC via proxy : TLS, ALPN et exigences particulières

gRPC est le protocole le plus exigeant de cette série. Il est strictement lié à HTTP/2 et utilise souvent TLS bidirectionnel (mTLS) pour l'authentification. Un proxy de transfert ordinaire, qui ne prend pas en charge le tunneling HTTP/2 CONNECT « tel quel », ne laissera tout simplement pas passer le trafic gRPC - la connexion échouera avec des erreurs de type UNAVAILABLE: upstream connect error.

Pour proxy gRPC en Python (avec la bibliothèque grpc), le proxy est défini via des variables d'environnement, car le support intégré des proxies dans les options de canal n'a pas été historiquement présent :

import os
import grpc

os.environ["grpc_proxy"] = "http://user:pass@proxy_host:8080"
os.environ["https_proxy"] = "http://user:pass@proxy_host:8080"

channel = grpc.secure_channel(
    "grpc.example.com:443",
    grpc.ssl_channel_credentials()
)

# Exemple d'appel via le stub généré
# stub = YourServiceStub(channel)
# response = stub.YourMethod(request)

Sur Node.js, le proxy pour gRPC est configuré via les options de canal grpc-js en combinaison avec un agent proxy compatible HTTP/2 :

const grpc = require('@grpc/grpc-js');
const { HttpsProxyAgent } = require('https-proxy-agent');

process.env.grpc_proxy = 'http://user:pass@proxy_host:8080';
process.env.https_proxy = 'http://user:pass@proxy_host:8080';

const client = new YourServiceClient(
  'grpc.example.com:443',
  grpc.credentials.createSsl()
);

Pour un fonctionnement stable de gRPC via proxy, une faible latence et une connexion TCP stable sans coupures fréquentes sont critiques - les flux multiplexés gRPC sont plus sensibles aux pannes réseau que les requêtes HTTP/1.1 individuelles. Dans de tels scénarios, les proxies résidentiels montrent souvent une meilleure stabilité par rapport aux pools de centres de données bon marché, car le chemin vers le serveur cible passe par une infrastructure réseau plus prévisible.

Tableau comparatif des protocoles

Protocole Type de connexion Exigences pour le proxy Type de proxy recommandé
HTTP/1.1 requête-réponse, keep-alive minimales, tout proxy HTTP Proxies de centres de données
WebSocket canal bidirectionnel permanent support des connexions longues, sans timeouts Proxies résidentiels
HTTP/2 flux binaires multiplexés tunneling TLS de bout en bout, ALPN Proxies résidentiels ou de centres de données
gRPC HTTP/2 + Protobuf, souvent mTLS faible latence, stabilité, HTTP/2 CONNECT Proxies mobiles pour contourner les filtres stricts

Comment choisir le protocole et le proxy pour votre stack

Le choix du protocole est rarement une décision libre - il est dicté par l'API cible. Mais le choix du type de proxy pour ce protocole est déjà de votre responsabilité, et il convient de s'appuyer sur un scénario spécifique :

Parsing de données via WebSocket (par exemple, streaming de cotations ou de données en temps réel à partir de sites de marché) nécessite une connexion stable et longue sans interruptions dues aux timeouts. Les proxies résidentiels fonctionnent mieux ici - ils sont moins souvent soumis aux algorithmes anti-fraude du service cible et maintiennent la connexion plus longtemps que les pools typiques de centres de données.

Intégration avec des microservices gRPC via un proxy externe (par exemple, lors des tests d'API depuis différentes géolocalisations) nécessite une faible latence et un support HTTP/2 sur tout le chemin. Pour cela, des IP résidentielles avec un bon routage conviennent, et pour les tâches critiques en termes de temps - des proxies mobiles, si le service cible filtre agressivement les plages d'adresses de centres de données.

Requêtes HTTP/2 massives vers des API REST/GraphQL avec multiplexage - c'est le scénario le plus fréquent où des proxies de centres de données rapides et bon marché suffisent, si le service cible ne bloque pas par défaut les plages d'adresses IP de centres de données.

Règle générale : plus le protocole est « capricieux » en matière de stabilité de connexion (WebSocket, gRPC), plus il est judicieux d'utiliser des IP résidentielles ou mobiles. Plus la requête est simple et courte (HTTP/1.1 ordinaire ou HTTP/2 sans longues sessions), plus il est confortable de travailler avec des proxies de centres de données - ils sont plus rapides et offrent une plus grande bande passante.

Erreurs courantes et leurs solutions

Erreur 1 : WebSocket se déconnecte toutes les 30-60 secondes. La raison en est que le proxy ou le répartiteur de charge intermédiaire ferme les connexions « inactives ». Solution : activer les trames ping/pong au niveau de l'application avec un intervalle inférieur au timeout du proxy (généralement 20-25 secondes suffisent).

Erreur 2 : gRPC échoue avec UNAVAILABLE via proxy, alors qu'il fonctionne directement. Le proxy ne prend pas en charge le tunneling HTTP/2 CONNECT. Solution : vérifier la documentation du fournisseur pour le support d'HTTP/2, ou utiliser un proxy SOCKS5 qui tunnelise TCP sans interpréter le protocole.

Erreur 3 : HTTP/2 est rétrogradé sans que cela soit perceptible. Cela se produit souvent en raison de l'absence de support ALPN sur le proxy. Vérifiez explicitement la version du protocole dans le code (comme dans l'exemple avec httpx ci-dessus) - ne comptez pas sur le fait que « tout fonctionne » si vous n'avez pas vérifié http_version dans la réponse.

Erreur 4 : Latence élevée lors du multiplexage gRPC via proxy. Souvent causée par un grand nombre de nœuds intermédiaires chez le fournisseur de proxy. Solution : tester la latence à l'avance via une simple requête RTT et choisir un fournisseur avec un routage direct, surtout pour les appels gRPC sensibles au temps.

Conclusion

WebSocket, HTTP/2 et gRPC nécessitent des approches différentes pour la configuration du proxy précisément parce qu'ils fonctionnent sur différents modèles de transport : du simple « relâcher la connexion TCP » pour WebSocket à un support strict de HTTP/2 CONNECT et ALPN pour gRPC. Vérifiez explicitement la version du protocole dans le code, testez à l'avance la stabilité des connexions longues et choisissez SOCKS5 là où la transparence du tunneling est essentielle.

Si votre stack inclut des connexions WebSocket de longue durée ou des appels gRPC sensibles à la latence, nous vous recommandons d'essayer des proxies résidentiels - ils offrent des connexions plus stables et prévisibles par rapport aux pools typiques de centres de données. Pour des requêtes HTTP/2 simples avec une haute bande passante, des proxies de centres de données conviennent, et pour des tâches avec un filtrage anti-fraude agressif du service cible - des proxies mobiles.