Documentation
¶
Overview ¶
Package bridge carries HTTP requests between two JavaScript realms over postMessage: the dashboard runs on the page (it needs the canvas) and the engine in a Web Worker (it needs Atomics.wait), and the dashboard's API client — and wctr, run in the dashboard's terminal — reach the engine's API handler through this bridge. Responses stream, so the log follow, wait and pull endpoints work as over a socket.
The protocol is seven message types, all carrying the request's id:
page -> worker http.req {method, url, header, data, stream}
page -> worker http.body {data} (a streamed request body)
page -> worker http.eof {} (its end)
page -> worker http.cancel {}
worker -> page http.head {status, header}
worker -> page http.data {data}
worker -> page http.end {err}
A request body of known length (every JSON body) travels whole in http.req. One of unknown length -- a stdin, as the engine's exec start reads after its JSON object -- is streamed: http.req says stream, then http.body chunks follow as the client produces them, then http.eof, so an interactive process gets its input while its output streams back.
The core here is plain Go over a post function, natively tested; the JavaScript glue (bridge_js.go) only converts Message to and from a JS object. The "http." prefix lets the messages share a worker's channel with other traffic (the playground's terminal messages).
Security: the server accepts only a path (never a scheme or host, so a page cannot aim the engine's handler elsewhere), a fixed set of methods, a bounded body, a bounded header, and a bounded number of requests in flight; the client bounds what it buffers per response.
Index ¶
Constants ¶
const ( TypeRequest = "http.req" TypeBody = "http.body" TypeEOF = "http.eof" TypeCancel = "http.cancel" TypeHead = "http.head" TypeData = "http.data" TypeEnd = "http.end" )
Message types.
const ( MaxBody = 1 << 20 // a request body MaxHeader = 32 // header fields of a request or response MaxInFlight = 64 // concurrent requests a server runs MaxBuffered = 16 << 20 // response bytes a client holds unread (and request bytes a server does) )
Bounds.
Variables ¶
var ErrClosed = errors.New("bridge: the engine closed the connection")
ErrClosed is the error of a body read after the server went away.
Functions ¶
Types ¶
type Message ¶
type Message struct {
T string
ID int
Method string
URL string
Header map[string]string
Data []byte
Status int
Err string
// Stream: the request body follows as http.body messages, then http.eof.
Stream bool
}
Message is one message of the protocol.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server runs requests that arrive as messages through an http.Handler.
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport is the client side: an http.RoundTripper whose requests go out as messages and whose responses come back through Deliver.
func NewTransport ¶
NewTransport sends requests with post.