go: net/http: ProxyFromEnvironment does not support socks5

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

go version go1.7.4 linux/amd64

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

actually it’s Manjaro

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bruce/go_ext_path"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build134643851=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

What did you do?

git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'
export http_proxy=socks5://127.0.0.1:1080
export https_proxy=socks5://127.0.0.1:1080
go get -u -v github.com/zmb3/gogetdoc

What did you expect to see?

Git can use socks5 proxy to clone a repo, so i expect go get can use socks5 proxy to download/update package github.com/zmb3/gogetdoc

What did you see instead?

github.com/zmb3/gogetdoc (download) Fetching https://golang.org/x/tools/go/buildutil?go-get=1 https fetch failed: Get https://golang.org/x/tools/go/buildutil?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout package golang.org/x/tools/go/buildutil: unrecognized import path “golang.org/x/tools/go/buildutil” (https fetch: Get https://golang.org/x/tools/go/buildutil?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout) Fetching https://golang.org/x/tools/go/loader?go-get=1 https fetch failed: Get https://golang.org/x/tools/go/loader?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout package golang.org/x/tools/go/loader: unrecognized import path “golang.org/x/tools/go/loader” (https fetch: Get https://golang.org/x/tools/go/loader?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout) [bruce@bruce-manjaro ~]$ set https_proxy=socks5://127.0.0.1:1080 [bruce@bruce-manjaro ~]$ go get -u -v github.com/zmb3/gogetdoc github.com/zmb3/gogetdoc (download) Fetching https://golang.org/x/tools/go/buildutil?go-get=1 https fetch failed: Get https://golang.org/x/tools/go/buildutil?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout package golang.org/x/tools/go/buildutil: unrecognized import path “golang.org/x/tools/go/buildutil” (https fetch: Get https://golang.org/x/tools/go/buildutil?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout) Fetching https://golang.org/x/tools/go/loader?go-get=1 https fetch failed: Get https://golang.org/x/tools/go/loader?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout package golang.org/x/tools/go/loader: unrecognized import path “golang.org/x/tools/go/loader” (https fetch: Get https://golang.org/x/tools/go/loader?go-get=1: http: error connecting to proxy http://socks5😕/127.0.0.1:1080: dial tcp 59.50.43.82:0: i/o timeout)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 24 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Maybe, implementaion will be like below.

package main

import (
	"context"
	"io"
	"log"
	"net"
	"net/http"
	"os"

	"golang.org/x/net/proxy"
)

type dialer struct {
	addr   string
	socks5 proxy.Dialer
}

func (d *dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
	// TODO: golang.org/x/net/proxy need to add DialContext
	return d.Dial(network, addr)
}

func (d *dialer) Dial(network, addr string) (net.Conn, error) {
	var err error
	if d.socks5 == nil {
		d.socks5, err = proxy.SOCKS5("tcp", d.addr, nil, proxy.Direct)
		if err != nil {
			return nil, err
		}
	}
	return d.socks5.Dial(network, addr)
}

func Socks5Proxy(addr string) *http.Transport {
	d := &dialer{addr: addr}
	return &http.Transport{
		DialContext: d.DialContext,
		Dial:        d.Dial,
	}
}

func main() {
	http.DefaultTransport = Socks5Proxy("127.0.0.1:1080")

	resp, err := http.Get("http://www.google.com/")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	io.Copy(os.Stdout, resp.Body)
}

tested with server written in go https://github.com/armon/go-socks5