Skip to content

State of support for net/http on wasm targets running within browsers on commodity hardware (AMD64/ARM64 etc) #4420

Open
@owenwaller

Description

@owenwaller

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:

  1. All of the Go programmer knowledge about how to use the `net.http.Client is lost.
  2. 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 the net/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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestnetworkAnything to do with network use from TinyGowasmWebAssembly

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions