golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.09k stars 17.68k forks source link

net/http: HTTP requests failing with 'Protocol not available' on wasm/js when running in browser #59605

Open rayvbr opened 1 year ago

rayvbr commented 1 year ago

What version of Go are you using (go version)?

$ go version
1.20.3

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
wasm/js

Chrome version: Version 111.0.5563.146 (Official Build) (x86_64)

(also reproducible with various Chromium-based browsers)

What did you do?

When doing a simple HTTP GET in a Go library compiled for wasm/js, all versions Go 1.18 and later are failing when running inside Chrome with dial tcp: lookup <some_domain>: Protocol not available.

When running on Go 1.17, this works fine. But Go 1.18 and later give the error above

The issue seems to be introduced by https://github.com/golang/go/commit/266626211e40d1f2c3a34fa4cd2023f5310cbd7d and possibly made worse by https://github.com/golang/go/commit/4c5d97990e4a39bd3e903f8e318b7234db3ba91f. These commits seem to try to "autodetect" a Node environment by checking the presence of certain browser settings. While that may have been valid at time of committing, it seems the assumptions on which they were based no longer hold for more recent browser versions.

Perhaps a more direct/explicit way of checking whether we're running in a Node or browser environment would be more suitable? The methods above look a bit hacky

dr2chase commented 1 year ago

@golang/wasm, @neild

rayvbr commented 1 year ago

I can confirm that removing the following lines from src/net/http/roundtrip_js.go fixes the issue:

if t.Dial != nil || t.DialContext != nil || t.DialTLS != nil || t.DialTLSContext != nil || jsFetchMissing || jsFetchDisabled {
    return t.roundTrip(req)
}

Just removing jsFetchDisabled is not sufficient

philippgille commented 1 year ago

With Go 1.21 and a (GOOS=js GOARCH=wasm) program that makes a simple HTTP request it works for me without manual modifications in a browser, in Deno and in Bun. But not in Node, where I get the same "Protocol not available" error.