无法在Go中同时使用自定义的RoundTrip和Dial来使用httputil.ReverseProxy。

huangapple go评论65阅读模式
英文:

Unable to use custom RoundTrip and Dial at the same time with httputil.ReverseProxy in Go

问题

我正在使用Go语言的net/http/httputil/ReverseProxy库编写一个反向代理服务器。我已经使用了自定义的Director,并且需要为Transport定义自己的RoundTrip和Dial。

我可以像这样使用自定义的Dial:

transport := &http.Transport{
    Dial: func(network, addr string) (net.Conn, error) {
        lgr.Println("running custom magic below")
        // 自定义操作
        return net.Dial(network, addr)
    },
}
res := &httputil.ReverseProxy{Director: director, Transport: transport}
return res

所以我创建了一个自定义的Transport,它嵌入了http.Transport,像这样:

type customTransport struct {
    http.Transport
}

func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    res, err := http.DefaultTransport.RoundTrip(req)
    lgr.Println("checking the response")
    // 检查响应
    return res, err
}

我尝试以这种方式使用它来替代默认的Transport:

transport := &customTransport{http.Transport{
    Dial: func(network, addr string) (net.Conn, error) {
        lgr.Println("running custom magic below")
        // 自定义操作
        return net.Dial(network, addr)
    },
}}
res := &httputil.ReverseProxy{Director: director, Transport: transport}

问题是,尽管我的自定义RoundTrip正常工作,但Dial现在停止工作了,不再执行自定义操作。

当我在分配后立即记录transport.Dial时,我可以看到它在内存中的地址。当我记录上面函数返回的res中的RevereProxy.Transport时,我甚至可以看到相同的地址:

fmt.Printf("%#v", transport.Dial)
2016/02/18 12:11:48.401245 main.go:76: (func(string, string) (net.Conn, error))(0x4039a0)
fmt.Printf("%#v", proxy.Transport)
2016/02/18 12:11:48.401403 main.go:100: &main.customTransport{Transport:http.Transport{...}}

无论如何,似乎调用了核心net.Dial方法,而不是我的自定义Dial,我真的不知道为什么。:-( 任何想法将不胜感激!谢谢!

英文:

I'm writing a reverse proxy server in Go using the core net/http/httputil/ReverseProxy library. I already use a custom Director and I need to define my own RoundTrip and Dial for the Transport.

I'm able to use custom Dial like this:

transport := &http.Transport{
    Dial: func(network, addr string) (net.Conn, error) {
        lgr.Println("running custom magic below")
        // custom magic
        return net.Dial(network, addr)
    },
}
res := &httputil.ReverseProxy{Director: director, Transport: transport}
return res

So I created a custom transport that embeds http.Transport like this:

type customTransport struct {
    http.Transport
}

func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    res, err := http.DefaultTransport.RoundTrip(req)
    lgr.Println("checking the response")
    // check the response
    return res, err
}

And I tried to use it instead of the default Transport in this way:

transport := &customTransport{http.Transport{
    Dial: func(network, addr string) (net.Conn, error) {
        lgr.Println("running custom magic below")
        // custom magic
        return net.Dial(network, addr)
    },
}}
res := &httputil.ReverseProxy{Director: director, Transport: transport}

The problem is that while my custom RoundTrip works fine, the Dial stopped working now and no custom magic is done anymore.

When I log transport.Dial right after it is assigned, I see its address in memory. When I log my RevereProxy.Transport, which the function above returns in res, I even see the same address there:

fmt.Printf("%#v", transport.Dial)
2016/02/18 12:11:48.401245 main.go:76: (func(string, string) (net.Conn, error))(0x4039a0)
fmt.Printf("%#v", proxy.Transport)
2016/02/18 12:11:48.401403 main.go:100: &main.customTransport{Transport:http.Transport{idleMu:sync.Mutex{state:0, sema:0x0}, wantIdle:false, idleConn:map[http.connectMethodKey][]*http.persistConn(nil), idleConnCh:map[http.connectMethodKey]chan *http.persistConn(nil), reqMu:sync.Mutex{state:0, sema:0x0}, reqCanceler:map[*http.Request]func()(nil), altMu:sync.RWMutex{w:sync.Mutex{state:0, sema:0x0}, writerSem:0x0, readerSem:0x0, readerCount:0, readerWait:0}, altProto:map[string]http.RoundTripper(nil), Proxy:(func(*http.Request) (*url.URL, error))(nil), Dial:(func(string, string) (net.Conn, error))(0x4039a0), DialTLS:(func(string, string) (net.Conn, error))(nil), TLSClientConfig:(*tls.Config)(nil), TLSHandshakeTimeout:0, DisableKeepAlives:false, DisableCompression:false, MaxIdleConnsPerHost:0, ResponseHeaderTimeout:0, ExpectContinueTimeout:0, TLSNextProto:map[string]func(string, *tls.Conn) http.RoundTripper(nil), nextProtoOnce:sync.Once{m:sync.Mutex{state:0, sema:0x0}, done:0x0}, h2transport:(*http.http2Transport)(nil)}}

Anyway, it seems that the core net.Dial method is called instead of my custom Dial and I really don't have a clue why. 无法在Go中同时使用自定义的RoundTrip和Dial来使用httputil.ReverseProxy。 Any ideas would be highly appreciated! Thanks!

答案1

得分: 2

你正在定义一个自定义的Transport,但是在http.DefaultTransport上调用RoundTrip。你需要在嵌入的Transport上调用RoundTrip

type customTransport struct {
    *http.Transport
}

func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    res, err := t.Transport.RoundTrip(req)
    lgr.Println("检查响应")
    // 检查响应
    return res, err
}
英文:

You're defining a custom Transport, but calling RoundTrip on the http.DefaultTransport. You need to call RoundTrip on the embedded Transport:

type customTransport struct {
	*http.Transport
}

func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	res, err := t.Transport.RoundTrip(req)
	lgr.Println("checking the response")
	// check the response
	return res, err
}

答案2

得分: 0

不需要自定义Dial,只需在TLSClientConfig中设置InsecureSkipVerify选项:

proxy.Transport = &customTransport{
	Transport: &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	},
}
英文:

No need to custom Dial, simply set InsecureSkipVerify option in TLSClientConfig:

proxy.Transport = &customTransport{
	Transport: &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	},
}

huangapple
  • 本文由 发表于 2016年2月18日 19:40:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/35480455.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定