Documentation for Jetty

HTTP/2 Support for Agent Transport

Status: In Progress - Transport Abstraction Complete

Goal

Replace the WebSocket-based JSON protocol between the edge server and CLI agents with HTTP/2 (gRPC bidirectional streaming). Benefits:

  • Native multiplexing -- no head-of-line blocking per connection.
  • Streaming request/response bodies without base64 encoding overhead.
  • Standard load-balancer and observability tooling for gRPC.
  • Connection-level flow control built into HTTP/2.

Architecture

  Public HTTP      Edge Server        Agent (CLI)
  ----------->  [ edge router ] --grpc--> [ agent ]
                     |                       |
                 AgentTransport           gRPC client
                  (interface)

The edge router talks to agents through the AgentTransport interface (cli/internal/edge/transport.go). Today the only implementation is WebSocketTransport; when gRPC is ready a GRPCTransport will be added with zero changes to routing, rate-limiting, or health-check code.

Completed Work

1. Transport Abstraction (cli/internal/edge/transport.go)

  • AgentTransport interface with SendHTTPRequest, ReceiveHTTPResponse, Close, and IsHealthy methods.
  • WebSocketTransport implementation wrapping the existing gorilla/websocket connection with the same write-mutex + pending-map pattern.
  • Helper methods: RegisterPending, DeliverResponse, WriteRaw, Conn.

2. Proto Definitions (cli/internal/proto/tunnel.proto)

  • gRPC service TunnelAgent with Register and ForwardHTTP RPCs.
  • HTTPChunk message supporting HEADERS / DATA / TRAILERS streaming.
  • Message types mirror current wsproto structs for straightforward migration.

3. Edge Config Updates (cli/internal/edge/edge.go)

  • Config.TransportMode field ("websocket" default, "grpc" planned).
  • Config.GRPCAddr field (default ":8091").
  • session.transport field of type AgentTransport.
  • session.close() delegates to transport.Close() when available.

Remaining Work

  1. Protobuf codegen -- run protoc to generate Go stubs from tunnel.proto.
  2. GRPCTransport -- implement AgentTransport backed by a gRPC bidirectional stream.
  3. Migrate hot path -- replace direct sess.conn.WriteMessage / sess.pending usage in handlePublicHTTP and readAgentLoop with sess.transport.SendHTTPRequest / DeliverResponse.
  4. Agent-side gRPC client -- new dial mode in the CLI agent.
  5. Integration tests -- test both WebSocket and gRPC transports end-to-end.
  6. Gradual rollout -- TransportMode config lets operators switch per-edge instance; agents can negotiate protocol on connect.

Implementation Notes

  • The WebSocketTransport intentionally keeps the existing pending-map and write-mutex patterns so the refactor is purely structural with no behavioural change.
  • session.conn is retained alongside session.transport because ping/pong handling and raw TCP/UDP frames still need direct WebSocket access. These will migrate into the transport interface in later phases.
  • The proto file uses bidirectional streaming (ForwardHTTP) rather than unary RPCs so that large bodies can be chunked without buffering.

Send feedback

Found an issue or have a suggestion? Let us know.