Skip to content

Instantly share code, notes, and snippets.

@astrolemonade
Created May 31, 2023 09:47
Show Gist options
  • Save astrolemonade/6628b6e36c0ec5c6c50a277e1dbf0955 to your computer and use it in GitHub Desktop.
Save astrolemonade/6628b6e36c0ec5c6c50a277e1dbf0955 to your computer and use it in GitHub Desktop.
// HTTP Hello World Server + non-blocking I/O test.
//
// This requires gotip (https://pkg.go.dev/golang.org/dl/gotip) for:
//
// - https://github.com/golang/go/commit/41893389
// - https://github.com/golang/go/commit/c5c21845
// - https://github.com/golang/go/commit/a17de43e
//
// We can use the wasirun command to run the WebAssembly module:
//
// $ go install github.com/stealthrocket/wasi-go/cmd/wasirun@latest
//
// Example:
//
// $ GOOS=wasip1 GOARCH=wasm gotip build -o http.wasm http.go
// $ wasirun --listen 127.0.0.1:8080 http.wasm &
// [1] 22810
// $ curl http://127.0.0.1:8080/
// Hello, World!
//
// Note that wasmtime also supports pre-opening sockets:
//
// $ wasmtime --tcplisten 127.0.0.1:8080 http.wasm
package main
import (
"errors"
"log"
"net"
"net/http"
"os"
"syscall"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
l, err := findListener()
if err != nil {
return err
}
if l == nil {
return errors.New("no pre-opened sockets available")
}
defer l.Close()
return http.Serve(l, http.HandlerFunc(handleReq))
}
func handleReq(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!\n"))
}
func findListener() (net.Listener, error) {
// We start looking for pre-opened sockets at fd=3 because 0, 1, and 2
// are reserved for stdio. Pre-opened directories also start at fd=3, so
// we skip fds that aren't sockets. Once we reach EBADF we know there
// are no more pre-opens.
for preopenFd := uintptr(3); ; preopenFd++ {
f := os.NewFile(preopenFd, "")
l, err := net.FileListener(f)
f.Close()
var se syscall.Errno
switch errors.As(err, &se); se {
case syscall.ENOTSOCK:
continue
case syscall.EBADF:
err = nil
}
return l, err
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment