Skip to content

Commit 2666262

Browse files
neilalexanderneild
authored andcommitted
net/http: guarantee that the Transport dial functions are respected in js/wasm
The net/http package has a documented contract that if DialContext, DialDLSContext, Dial or DialTLS are specified in an instance of Transport, that they will be used to set up the connection. If they are not specified, then a reasonable fallback is made (e.g. using the net package). This is ordinarily true, except for when compiling for the js/wasm target, where the browser's Fetch API is preferred in all cases (except for when it is undefined/unavailable) and therefore the dial functions are all ignored. As a result, the http.Transport implementation under js/wasm doesn't meet that contract. This PR updates the RoundTrip behaviour of http.Transport so that if DialContext, DialTLSContext, Dial or DialTLS are specified, they are used as expected. The Fetch API will be used as a fallback if they are not specified. Fixes #27495 Change-Id: I88c6eb6ffdd077827b421d606f3e60ebdafd538f GitHub-Last-Rev: 948a0ed GitHub-Pull-Request: #46923 Reviewed-on: https://go-review.googlesource.com/c/go/+/330852 Reviewed-by: Damien Neil <[email protected]> Trust: Damien Neil <[email protected]> Trust: Carlos Amedee <[email protected]> Run-TryBot: Damien Neil <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 3124968 commit 2666262

File tree

6 files changed

+48
-4
lines changed

6 files changed

+48
-4
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,7 @@ Nathan Youngman <[email protected]>
10151015
Nathaniel Cook <[email protected]>
10161016
Naveen Kumar Sangi <[email protected]>
10171017
Neelesh Chandola <[email protected]>
1018+
Neil Alexander <[email protected]>
10181019
Neil Lyons <[email protected]>
10191020
Netflix, Inc.
10201021
Neuman Vong <[email protected]>

CONTRIBUTORS

+1
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,7 @@ Naveen Kumar Sangi <[email protected]>
19011901
Neeilan Selvalingam <[email protected]>
19021902
Neelesh Chandola <[email protected]>
19031903
Nehal J Wani <[email protected]>
1904+
Neil Alexander <[email protected]>
19041905
Neil Lyons <[email protected]>
19051906
Neuman Vong <[email protected]>
19061907
Neven Sajko <[email protected]>

src/net/http/roundtrip_js.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,19 @@ const jsFetchCreds = "js.fetch:credentials"
4141
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters
4242
const jsFetchRedirect = "js.fetch:redirect"
4343

44-
var useFakeNetwork = js.Global().Get("fetch").IsUndefined()
44+
// jsFetchMissing will be true if the Fetch API is not present in
45+
// the browser globals.
46+
var jsFetchMissing = js.Global().Get("fetch").IsUndefined()
4547

4648
// RoundTrip implements the RoundTripper interface using the WHATWG Fetch API.
4749
func (t *Transport) RoundTrip(req *Request) (*Response, error) {
48-
if useFakeNetwork {
50+
// The Transport has a documented contract that states that if the DialContext or
51+
// DialTLSContext functions are set, they will be used to set up the connections.
52+
// If they aren't set then the documented contract is to use Dial or DialTLS, even
53+
// though they are deprecated. Therefore, if any of these are set, we should obey
54+
// the contract and dial using the regular round-trip instead. Otherwise, we'll try
55+
// to fall back on the Fetch API, unless it's not available.
56+
if t.Dial != nil || t.DialContext != nil || t.DialTLS != nil || t.DialTLSContext != nil || jsFetchMissing {
4957
return t.roundTrip(req)
5058
}
5159

src/net/http/transport.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ import (
4242
// $no_proxy) environment variables.
4343
var DefaultTransport RoundTripper = &Transport{
4444
Proxy: ProxyFromEnvironment,
45-
DialContext: (&net.Dialer{
45+
DialContext: defaultTransportDialContext(&net.Dialer{
4646
Timeout: 30 * time.Second,
4747
KeepAlive: 30 * time.Second,
48-
}).DialContext,
48+
}),
4949
ForceAttemptHTTP2: true,
5050
MaxIdleConns: 100,
5151
IdleConnTimeout: 90 * time.Second,

src/net/http/transport_default_js.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build js && wasm
6+
// +build js,wasm
7+
8+
package http
9+
10+
import (
11+
"context"
12+
"net"
13+
)
14+
15+
func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
16+
return nil
17+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !(js && wasm)
6+
// +build !js !wasm
7+
8+
package http
9+
10+
import (
11+
"context"
12+
"net"
13+
)
14+
15+
func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
16+
return dialer.DialContext
17+
}

0 commit comments

Comments
 (0)