Documentation ¶
Overview ¶
Package webtransport provides a lightweight WebTransport-over-HTTP/3 server implementation in Go.
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.
Neither WebTransport nor HTTP/3 are standardized yet. We adhere to: draft-ietf-quic-http-34 https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-34 and draft-ietf-webtrans-http3-02 https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3-02
You can find a complete server (and browser client) example here: https://github.com/adriancable/webtransport-go-example
Here's a minimal server example to get you going. First, you'll need to create a certificate, as explained in the comments here: https://github.com/GoogleChrome/samples/blob/gh-pages/webtransport/webtransport_server.py
Set up the WebTransport server parameters:
server := &webtransport.Server{ ListenAddr: ":4433", TLSCert: webtransport.CertFile{Path: "cert.pem"}, TLSKey: webtransport.CertFile{Path: "cert.key"}, AllowedOrigins: []string{"googlechrome.github.io", "localhost:8000", "new-tab-page"}, }
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();
Index ¶
- type CertFile
- type QuicConfig
- type ReceiveStream
- type SendStream
- type Server
- type Session
- func (s *Session) AcceptSession()
- func (s *Session) AcceptStream() (Stream, error)
- func (s *Session) AcceptUniStream(ctx context.Context) (ReceiveStream, error)
- func (s *Session) CloseSession()
- func (s *Session) CloseWithError(code quic.ApplicationErrorCode, str string)
- func (s *Session) Context() context.Context
- func (s *Session) OpenStream() (Stream, error)
- func (s *Session) OpenStreamSync(ctx context.Context) (Stream, error)
- func (s *Session) OpenUniStream() (SendStream, error)
- func (s *Session) OpenUniStreamSync(ctx context.Context) (SendStream, error)
- func (s *Session) ReceiveMessage(ctx context.Context) ([]byte, error)
- func (s *Session) RejectSession(errorCode int)
- func (s *Session) SendMessage(msg []byte) error
- type Stream
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CertFile ¶
A CertFile represents a TLS certificate or key, expressed either as a file path or as the certificate/key itself as a []byte.
type ReceiveStream ¶
type ReceiveStream struct { quic.ReceiveStream // contains filtered or unexported fields }
ReceiveStream wraps a quic.ReceiveStream providing a unidirectional WebTransport client->server stream, including a Read function.
type SendStream ¶
type SendStream struct { quic.SendStream // contains filtered or unexported fields }
SendStream wraps a quic.SendStream providing a unidirectional WebTransport server->client stream, including a Write function.
type Server ¶
type Server struct { http.Handler // ListenAddr sets an address to bind server to, e.g. ":4433" ListenAddr string // TLSCert defines a path to, or byte array containing, a certificate (CRT file) TLSCert CertFile // TLSKey defines a path to, or byte array containing, the certificate's private key (KEY file) TLSKey CertFile // AllowedOrigins represents list of allowed origins to connect from AllowedOrigins []string // Additional configuration parameters to pass onto QUIC listener QuicConfig *QuicConfig }
A Server defines parameters for running a WebTransport server. Use http.HandleFunc to register HTTP/3 endpoints for handling WebTransport requests.
type Session ¶
type Session struct { quic.Stream Session quic.Session ClientControlStream quic.ReceiveStream ServerControlStream quic.SendStream // contains filtered or unexported fields }
Session is a WebTransport session (and the Body of a WebTransport http.Request) wrapping the request stream (a quic.Stream), the two control streams and a quic.Session.
func (*Session) AcceptSession ¶
func (s *Session) AcceptSession()
AcceptSession accepts an incoming WebTransport session. Call it in your http.HandleFunc.
func (*Session) AcceptStream ¶
AcceptStream accepts an incoming (that is, client-initated) bidirectional stream, blocking if necessary until one is available. Supply your own context, or use the WebTransport session's Context() so that ending the WebTransport session automatically cancels this call.
func (*Session) AcceptUniStream ¶
func (s *Session) AcceptUniStream(ctx context.Context) (ReceiveStream, error)
AcceptStream accepts an incoming (that is, client-initated) unidirectional stream, blocking if necessary until one is available. Supply your own context, or use the WebTransport session's Context() so that ending the WebTransport session automatically cancels this call.
func (*Session) CloseSession ¶
func (s *Session) CloseSession()
CloseSession cleanly closes a WebTransport session. All active streams are cancelled before terminating the session.
func (*Session) CloseWithError ¶
CloseWithError closes a WebTransport session with a supplied error code and string.
func (*Session) OpenStream ¶
OpenStream creates an outgoing (that is, server-initiated) bidirectional stream. It returns immediately.
func (*Session) OpenStreamSync ¶
OpenStream creates an outgoing (that is, server-initiated) bidirectional stream. It generally returns immediately, but if the session's maximum number of streams has been exceeded, it will block until a slot is available. Supply your own context, or use the WebTransport session's Context() so that ending the WebTransport session automatically cancels this call.
func (*Session) OpenUniStream ¶
func (s *Session) OpenUniStream() (SendStream, error)
OpenUniStream creates an outgoing (that is, server-initiated) bidirectional stream. It returns immediately.
func (*Session) OpenUniStreamSync ¶
func (s *Session) OpenUniStreamSync(ctx context.Context) (SendStream, error)
OpenUniStreamSync creates an outgoing (that is, server-initiated) unidirectional stream. It generally returns immediately, but if the session's maximum number of streams has been exceeded, it will block until a slot is available. Supply your own context, or use the WebTransport session's Context() so that ending the WebTransport session automatically cancels this call.
func (*Session) ReceiveMessage ¶
ReceiveMessage returns a datagram received from a WebTransport session, blocking if necessary until one is available. Supply your own context, or use the WebTransport session's Context() so that ending the WebTransport session automatically cancels this call. Note that datagrams are unreliable - depending on network conditions, datagrams sent by the client may never be received by the server.
func (*Session) RejectSession ¶
AcceptSession rejects an incoming WebTransport session, returning the supplied HTML error code to the client. Call it in your http.HandleFunc.
func (*Session) SendMessage ¶
SendMessage sends a datagram over a WebTransport session. Supply your own context, or use the WebTransport session's Context() so that ending the WebTransport session automatically cancels this call. Note that datagrams are unreliable - depending on network conditions, datagrams sent by the server may never be received by the client.