Description
Hi,
Could some one please be clear on the current level of support offered by tinygo
for the net/http
package when building for a wasm
target, but where the wasm
binary will be executed in a browser on common hardware/OS combinations e.g. linux/AMD64, linux/ARM64, macos/ARM64, windows/AMD64 etc?
I understand the situation for embedded hardware platforms is very different, where there may not be an OS as such and the API's can vary wildly between different devices. But I am not asking about wasm
net/http
support on those platforms. Nor, am I asking about support for other non-browser JS run-times (e.g NodeJS).
The standard Go compiler has supported net/http
for wasm
within a browser since wasm
support was first released. As far as I am aware this was achieved by mapping the net.http.Get(...)
and net.http.Client.Get(...)
methods to the fetch
api provided by the browser.
Could the tinygo
project not take a similar approach, even if this means specifying a new target e.g -target=wasmbrowser
?
I am aware of other 3rd party libraries (for example https://pkg.go.dev/marwan.io/wasm-fetch) that already do support the browser's fetch API. But these in general are not appropriate for two reasons:
- All of the Go programmer knowledge about how to use the `net.http.Client is lost.
- The programmer may not be calling
net.http.Client.Get(...)
directly in their code. It could be being called via a 3rd party package the programmer is using. In this case, short of PR to the 3rd party package authors, or a fork of the 3rd party package, it is impractical to change the 3rd party package over to use an alternative to thenet/http
package API's.
tinygo
therefore needs to support as much of the net/http
package is as appropriate when the wasm
is executed within a browser.
Having the net/http
package available would then enable tinygo
as suitable compiler for wasm
based web UI's. These UIs are typically making http.Get(...)
calls to exchange JSON payloads with a server and then processing the response to update the UI. But at the minute this doesn't look like its possible.
Two very simple examples:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
// use the default http client in net/http
_, err := http.Get("http://www.tinygo.org/") // <--------- runtime panic here AFAIK
if err != nil {
err := fmt.Errorf("http.Get fails with: %w", err)
log.Fatal(err)
}
}
and
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
c := http.Client{}
_, err := c.Get("http://www.tinygo.org/") <----------- runtime panic here AFAIK
if err != nil {
err := fmt.Errorf("http.Get fails with: %w", err)
log.Fatal(err)
}
}
These both result in the runtime panic of:
main.wasm:0x20f8d
Uncaught (in promise)
RuntimeError: unreachable
at main.runtime.runtimePanicAt (main.wasm:0x20f8d)
at main.runtime.nilPanic (main.wasm:0x4e6a)
at main.(:8888/*net/http.Client).Get (http://localhost:8888/main.wasm)
at main.runtime.run$1 (main.wasm:0x29e5b)
at main.runtime.run$1$gowrapper (main.wasm:0x202e5)
at main.tinygo_launch (main.wasm:0x6b5)
at main.(:8888/*internal/task.Task).Resume (http://localhost:8888/main.wasm)
at main.runtime.scheduler (main.wasm:0x205c4)
at main._start (main.wasm:0x20219)
at main._start.command_export (main.wasm:0x6a07c)
Is there some sort of update available on support for net/http
when the wasm
is executed by a browser?
If this isn't supported (as appears to be the case) is there a timeline available for this support or a list of actions that have to be taken?
Many thanks
Owen