Lightweight but fully-capable WebTransport server for Go

Overview

webtransport-go

This package provides a lightweight WebTransport-over-HTTP/3 server implementation in Go.

What is WebTransport?

WebTransport (https://www.w3.org/TR/webtransport/) is a 21st century replacement for WebSockets. It's currently supported by Chrome, with support in other browsers coming shortly. It has several benefits over WebSockets:

  • It's built on top of HTTP/3 which uses QUIC (not TCP) as the transport. QUIC provides significant performance advantages over TCP, especially on congested networks.

  • Unlike WebSockets where you get just a single send/receive stream, WebTransport provides for multiple server-initiated or client-initiated unidirectional or bidirectional (reliable) streams, plus (unreliable) datagrams.

  • Unlike XHR/fetch calls, WebTransport provides a means (serverCertificateHashes) for a browser to communicate securely with endpoints where issuance of Web PKI certificates is not possible, for example, a device over the LAN which is only accessible via a private IP address and hence a self-signed certificate. This is potentially big for IoT.

Neither WebTransport nor HTTP/3 are standardized yet. We adhere to: draft-ietf-quic-http-34 and draft-ietf-webtrans-http3-02.

Documentation

GoDoc has full documentation on webtransport-go's public API.

Complete Go server and browser-based client example

Take a look at the webtransport-go-example repo for a complete server (and browser client) example.

Minimal "getting started" example

You'll need to get a certificate for your server. Please read the comments at the top of Google's WebTransport server example in Python for detailed instructions.

First, set up WebTransport server parameters:

server := &webtransport.Server{
	ListenAddr:     ":4433",
	TLSCert:        webtransport.CertFile{Path: "cert.pem"},
	TLSKey:         webtransport.CertFile{Path: "cert.key"},
}

Then, set up an http.Handler to accept a session, wait for an incoming bidirectional stream from the client, then (in this example) receive data and echo it back:

http.HandleFunc("/counter", func(rw http.ResponseWriter, r *http.Request) {
	session := r.Body.(*webtransport.Session)
	session.AcceptSession()
	defer session.CloseSession()

	// Wait for incoming bidi stream
	s, err := session.AcceptStream()
	if err != nil {
		return
	}

	for {
		buf := make([]byte, 1024)
		n, err := s.Read(buf)
		if err != nil {
			break
		}
		fmt.Printf("Received from bidi stream %v: %s\n", s.StreamID(), buf[:n])
		sendMsg := bytes.ToUpper(buf[:n])
		fmt.Printf("Sending to bidi stream %v: %s\n", s.StreamID(), sendMsg)
		s.Write(sendMsg)
	}
}

Finally, start the server:

ctx, cancel := context.WithCancel(context.Background())
server.Run(ctx)

Here is a simple Chrome browser client to talk to this server. You can open a new browser tab and paste it into the Chrome DevTools console:

let transport = new WebTransport("https://localhost:4433/counter");
await transport.ready;
let stream = await transport.createBidirectionalStream();
let encoder = new TextEncoder();
let decoder = new TextDecoder();
let writer = stream.writable.getWriter();
let reader = stream.readable.getReader();
await writer.write(encoder.encode("Hello, world!"))
console.log(decoder.decode((await reader.read()).value));
transport.close();

Authors and acknowledgment

This package was written by me, drawing on several sources of inspiration:

  • Experimenting with QUIC and WebTransport in Go which describes the implementation in Go of a simple server for WebTransport over QUIC, which is now defunct but formed the basis for the WebTransport over HTTP/3 draft standard.
  • Pull request #3256 for the quic-go package, which implements (an earlier draft spec for) WebTransport but is a heavyweight structural change for the package for which there doesn't appear any appetite from the package maintainer.
  • HTTP/3 server built into quic-go. This package doesn't use quic-go's HTTP/3 server (only the underlying QUIC transport implementation), but webtransport-go implements its own minimal HTTP/3 server as needed to support WebTransport.

Instead, webtransport-go implements the latest draft standards for all the supported protocols, is very lightweight, and doesn't depend on any non-standard Go package forks or WIP modules.

License

Provided under the MIT license.

You might also like...
Open Service Mesh (OSM) is a lightweight, extensible, cloud native service mesh that allows users to uniformly manage, secure, and get out-of-the-box observability features for highly dynamic microservice environments.
Open Service Mesh (OSM) is a lightweight, extensible, cloud native service mesh that allows users to uniformly manage, secure, and get out-of-the-box observability features for highly dynamic microservice environments.

Open Service Mesh (OSM) Open Service Mesh (OSM) is a lightweight, extensible, Cloud Native service mesh that allows users to uniformly manage, secure,

Lightweight Kubernetes

K3s - Lightweight Kubernetes Lightweight Kubernetes. Production ready, easy to install, half the memory, all in a binary less than 100 MB. Great for:

A lightweight Vault client module written in Go, with no dependencies, that is intuitive and user-friendly

libvault A lightweight Hashicorp Vault client written in Go, with no dependencies. It aims to provide an intuitive, simple API that is easy to use. Ju

Lightweight, CRD based envoy control plane for kubernetes

Lighweight, CRD based Envoy control plane for Kubernetes: Implemented as a Kubernetes Operator Deploy and manage an Envoy xDS server using the Discove

Lightweight and dead-simple CI detection.

is-ci Lightweight and dead-simple CI detection for golang. This mod is based on the @npmcli/ci-detect package. Install go get -u github.com/wesleimp/i

The Coherence command line interface (CLI) is a lightweight tool, in the tradition of tools such as kubectl
The Coherence command line interface (CLI) is a lightweight tool, in the tradition of tools such as kubectl

Coherence Command Line Interface (CLI) Contents Overview Why use the Coherence C

Cmsnr - cmsnr (pronounced "commissioner") is a lightweight framework for running OPA in a sidecar alongside your applications in Kubernetes.

cmsnr Description cmsnr (pronounced "commissioner") is a lightweight framework for running OPA in a sidecar alongside your applications in Kubernetes.

K8s-ingress-health-bot - A K8s Ingress Health Bot is a lightweight application to check the health of the ingress endpoints for a given kubernetes namespace.

k8s-ingress-health-bot A K8s Ingress Health Bot is a lightweight application to check the health of qualified ingress endpoints for a given kubernetes

Lightweight, single-binary Backup Repository client. Part of E2E Backup Architecture designed by RiotKit

Backup Maker Tiny backup client packed in a single binary. Interacts with a Backup Repository server to store files, uses GPG to secure your backups e

Comments
  • WebTransport client

    WebTransport client

    Currently, this package only offers a WebTransport server implementation. It is desirable to have a WebTransport client implementation also in this package. The benefit is that, having a WebTransport client implementation allows automated end to end testing of a WebTransport server at the protocol level, as well as remote monitoring of a WebTransport application server.

    opened by yoursunny 0
Owner
Adrian Cable
Adrian Cable
vcluster - Create fully functional virtual Kubernetes clusters - Each cluster runs inside a Kubernetes namespace and can be started within seconds

Website • Quickstart • Documentation • Blog • Twitter • Slack vcluster - Virtual Clusters For Kubernetes Lightweight & Low-Overhead - Based on k3s, bu

Loft Labs 2.2k Nov 24, 2022
DeSo: a blockchain built from the ground up to support a fully-featured social network

About DeSo DeSo is a blockchain built from the ground up to support a fully-feat

null 0 Dec 18, 2021
webhook is a lightweight incoming webhook server to run shell commands

What is webhook? webhook is a lightweight configurable tool written in Go, that allows you to easily create HTTP endpoints (hooks) on your server, whi

Adnan Hajdarević 8.4k Nov 25, 2022
Matheus Fidelis 16 Nov 2, 2022
This is Paul, but in GO!

This is Paul. Overview This repo contains everything that makes Paul, Paul! TODO Here is what we still need to do to make Paul a real boy. Add securit

Turnbros 0 Jan 11, 2022
Kubernetes OS Server - Kubernetes Extension API server exposing OS configuration like sysctl via Kubernetes API

KOSS is a Extension API Server which exposes OS properties and functionality using Kubernetes API, so it can be accessed using e.g. kubectl. At the moment this is highly experimental and only managing sysctl is supported. To make things actually usable, you must run KOSS binary as root on the machine you will be managing.

Mateusz Gozdek 3 May 19, 2021
Gemini server running on the dailybuild server

#dailybuild notice This is the titan2 repo for the dailybuild server. It the static binary is built in a GitHub runner and sent over to the dailybuild

null 0 Nov 26, 2021
Go-http-server-docker - Simple sample server using docker and go

go-http-server-docker Simple sample webserver using docker and go.

null 0 Jan 8, 2022
Webhook-server - Webhook Server for KubeDB resources

webhook-server Webhook Server for KubeDB resources Installation To install KubeD

Kubernetes Database 1 Feb 22, 2022
EdgeDB-Golang-Docker-Sample - The sample of connection between EdgeDB Server and Go Echo API Server

EdgeDB Golang Docker Sample 『Go + Docker Composeを使ってEdgeDBを動かしてみた』のサンプルコードです。 使い

null 7 Nov 2, 2022