Skip to content

net/http: js-wasm in nodejs HTTP requests fail #69106

Open
@sekulicd

Description

@sekulicd

Go version

go version go1.22.0 darwin/amd64

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/sekulicd/Library/Caches/go-build'
GOENV='/Users/sekulicd/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/sekulicd/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/sekulicd/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/Cellar/go/1.22.0/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/Cellar/go/1.22.0/libexec/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.22.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/sekulicd/go/src/tst/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/q2/t3b78q_d1d9br0p8q1zqd8nc0000gn/T/go-build1746037209=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

I want to make HTTP request from Go WASM inside Node JS.

Here is sample main.go

//go:build js && wasm
// +build js,wasm

package main

import (
	"io/ioutil"
	"log"
	"net/http"
)

func main() {
	c := http.Client{
		Transport: http.DefaultTransport,
	}
	resp, err := c.Get("https://httpbin.org/anything")
	if err != nil {
		log.Fatal(err)
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	log.Println(string(body))
}

When i try to execute WebAssembly with Node.js with cmd:

GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" .

I get bellow error:

2024/08/28 14:11:49 Get "https://httpbin.org/anything": dial tcp: lookup httpbin.org on 192.168.17.142:53: write udp 127.0.0.1:4->192.168.17.142:53: write: Connection reset by peer

I understood that with this PR if i add js/wasm build tags that http.DefaultTransport will use RoundTripper with fetch options.

What did you see happen?

2024/08/28 14:11:49 Get "https://httpbin.org/anything": dial tcp: lookup httpbin.org on 192.168.17.142:53: write udp 127.0.0.1:4->192.168.17.142:53: write: Connection reset by peer

What did you expect to see?

Response similar to bellow:

{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "en-US,en;q=0.9,sr;q=0.8,hr;q=0.7,bs;q=0.6,sh;q=0.5",
"Host": "httpbin.org",
"Priority": "u=0, i",
"Sec-Ch-Ua": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"macOS\"",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-66cf14ab-0caaf43c6309fce12a8d7bc2"
},
"json": null,
"method": "GET",
"origin": "77.222.25.88",
"url": "https://httpbin.org/anything"
}

Activity

changed the title [-]Make HTTP req from WASM in Node js[/-] [+]net/http: js-wasm in nodejs HTTP requests fail[/+] on Aug 28, 2024
prattmic

prattmic commented on Aug 28, 2024

@prattmic
Member

cc @golang/wasm @golang/js @neild

added this to the Backlog milestone on Aug 28, 2024
added
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
on Aug 28, 2024
Zxilly

Zxilly commented on Aug 29, 2024

@Zxilly
Member

With the following code

//go:build js && wasm

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"runtime"
	"syscall/js"
)

func main() {
	fmt.Println(runtime.GOOS)
	fmt.Println(runtime.GOARCH)

	var p = js.Global().Get("process").Get("version").String()
	fmt.Println(p)

	c := http.Client{
		Transport: http.DefaultTransport,
	}
	resp, err := c.Get("https://httpbin.org/anything")
	if err != nil {
		log.Fatal(err)
	}

	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	log.Println(string(body))
}

I got

PS T:\gotmp> go run main.go
js
wasm
v22.3.0
2024/08/30 00:34:06 {
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "br, gzip, deflate",
    "Accept-Language": "*",
    "Host": "httpbin.org",
    "Sec-Fetch-Mode": "cors",
    "User-Agent": "node",
    "X-Amzn-Trace-Id": "Root=1-66d0a2fe-548f0f4a397f75581a5b352b"
  },
  "json": null,
  "method": "GET",
  "origin": "20.63.141.121",
  "url": "https://httpbin.org/anything"
}

Can you share more information about the environment?

Zxilly

Zxilly commented on Aug 29, 2024

@Zxilly
Member

Can you check if this code is working correctly without using the js/wasm target?

sekulicd

sekulicd commented on Sep 3, 2024

@sekulicd
Author

Can you check if this code is working correctly without using the js/wasm target?

Yeah, i know its working with go run but not with mentioned node binary, my goal is to make http req from node js using go http pkg

Zxilly

Zxilly commented on Sep 3, 2024

@Zxilly
Member

Can you describe the Node.js version you use?

Zxilly

Zxilly commented on Sep 3, 2024

@Zxilly
Member

Note that when I use go run, the appropriate wasm wrapper is already present in the environment variable, so I am indeed running a wasm binary, as you can see from the runtime information printed.

sekulicd

sekulicd commented on Sep 3, 2024

@sekulicd
Author

Note that when I use go run, the appropriate wasm wrapper is already present in the environment variable, so I am indeed running a wasm binary, as you can see from the runtime information printed.

v21.7.3

Zxilly

Zxilly commented on Sep 3, 2024

@Zxilly
Member
PS T:\gotmp> $env:GOARCH="wasm"
PS T:\gotmp> $env:GOOS="js"
PS T:\gotmp> cat .\main.go
//go:build js && wasm

package main

import (
        "fmt"
        "io"
        "log"
        "net/http"
        "runtime"
        "syscall/js"
)

func main() {
        fmt.Println(runtime.GOOS)
        fmt.Println(runtime.GOARCH)

        var p = js.Global().Get("process").Get("version").String()
        fmt.Println(p)

        c := http.Client{
                Transport: http.DefaultTransport,
        }
        resp, err := c.Get("https://httpbin.org/anything")
        if err != nil {
                log.Fatal(err)
        }

        defer resp.Body.Close()

        body, err := io.ReadAll(resp.Body)
        if err != nil {
                log.Fatal(err)
        }

        log.Println(string(body))
}
PS T:\gotmp> node --version
v21.7.3
PS T:\gotmp> go version
go version go1.23.0 windows/amd64
PS T:\gotmp> go run main.go
js
wasm
v21.7.3
2024/09/03 22:36:21 {
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "br, gzip, deflate",
    "Accept-Language": "*",
    "Host": "httpbin.org",
    "Sec-Fetch-Mode": "cors",
    "User-Agent": "node",
    "X-Amzn-Trace-Id": "Root=1-66d71ee2-595ae3d765b1eb967f72c0e7"
  },
  "json": null,
  "method": "GET",
  "origin": "8.217.95.142",
  "url": "https://httpbin.org/anything"
}

I can't reproduce it with exactly same version on Windows. Can you try to reproduce it on Linux?

sekulicd

sekulicd commented on Sep 4, 2024

@sekulicd
Author

I can't reproduce it with exactly same version on Windows. Can you try to reproduce it on Linux?

I am running this on MacOS(12.7.6), i followed this tutorial, did u tried with cmd i used? :
GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" .

Zxilly

Zxilly commented on Sep 4, 2024

@Zxilly
Member

I can reproduce it on Linux

zxilly@Zxilly-s-PC:/mnt/t/gotmp$ GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" .
js
wasm
v22.8.0
2024/09/04 17:39:14 Get "https://httpbin.org/anything": dial tcp: lookup httpbin.org on 127.0.0.53:53: write udp 127.0.0.1:4->127.0.0.53:53: write: Connection reset by peer
exit status 1

I'll dive into it.

Zxilly

Zxilly commented on Sep 5, 2024

@Zxilly
Member

related: #57613 #60011

linked a pull request that will close this issue on Sep 5, 2024
gopherbot

gopherbot commented on Sep 5, 2024

@gopherbot
Contributor

Change https://go.dev/cl/611215 mentions this issue: net/http: only disable fetch in test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-JSarch-wasmWebAssembly issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      Participants

      @prattmic@sekulicd@dmitshur@gopherbot@Zxilly

      Issue actions

        net/http: js-wasm in nodejs HTTP requests fail · Issue #69106 · golang/go