Created
May 31, 2023 09:47
-
-
Save astrolemonade/6628b6e36c0ec5c6c50a277e1dbf0955 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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