Skip to content

Question: Does HTTP proxy support WebSocket connections?Β #23

@josecelano

Description

@josecelano

Summary

I'm evaluating Pingoo as a TLS termination proxy for Torrust Tracker deployments. Pingoo works excellently for standard HTTP/HTTPS traffic, but I encountered issues when trying to proxy WebSocket connections to Grafana.

Question: Is WebSocket proxying supported in http_proxy mode? If not, are there any workarounds or plans to add this feature?

Environment

  • Pingoo version: v0.14.0 (latest pingooio/pingoo:latest Docker image)
  • Upstream service: Grafana 12.3.1 (requires WebSocket for Grafana Live feature)
  • Deployment: Docker with --network host

Configuration

listeners:
  https:
    address: https://0.0.0.0:443

tls:
  acme:
    domains:
      - grafana.example.com
    contact: [email protected]

services:
  grafana:
    http_proxy: ["http://grafana:3000"]

Observed Behavior

βœ… HTTP requests work correctly

curl -s https://grafana.example.com/api/health
# Returns: {"commit":"9a98d91fd4","database":"ok","version":"12.3.1"}

❌ WebSocket connections fail

Browser console error:

WebSocket connection to 'wss://grafana.example.com/api/live/ws' failed:
WebSocket is closed before the connection is established

Pingoo logs show:

WARN [https] error serving HTTP connection: hyper::Error(IncompleteMessage)
DEBUG [https] peer closed connection without sending TLS close_notify, client=x.x.x.x:xxxxx

Root Cause Analysis

Looking at the source code, I found that http_proxy_service.rs removes hop-by-hop headers including Upgrade:

// https://github.com/pingooio/pingoo/blob/main/pingoo/services/http_proxy_service.rs#L26-L35
const HOP_HEADERS: &[&str] = &[
    "Connection",
    "Proxy-Connection",
    "Keep-Alive",
    "Proxy-Authenticate",
    "Proxy-Authorization",
    "Te",
    "Trailer",
    "Transfer-Encoding",
    "Upgrade",  // <-- This breaks WebSocket
];

WebSocket connections require the Upgrade: websocket header to be forwarded to the upstream server for the HTTP-to-WebSocket protocol upgrade handshake.

Expected Behavior

For comparison, nginx handles WebSocket proxying with:

location /api/live/ws {
    proxy_pass http://grafana:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

Questions

  1. Is WebSocket proxying currently supported in any mode?
  2. If not, would you consider adding WebSocket support to http_proxy?
  3. As a workaround, could TCP proxy mode (tcp+tls) be used while preserving some HTTP routing capability?

Use Case

We're deploying Torrust BitTorrent Tracker with a monitoring stack (Prometheus + Grafana). Pingoo works perfectly for:

  • Tracker API (REST/JSON)
  • HTTP Tracker (BitTorrent announce/scrape)

But Grafana's real-time dashboard features (Grafana Live) require WebSocket support.

Thank you for creating Pingoo - the automatic TLS certificate management and minimal configuration are fantastic! πŸŽ‰

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions