英文:
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. 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,
},
},
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论