httputilmain
package main
import (
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
u, _ := url.Parse("http://localhost:8888")
http.Handle("/", httputil.NewSingleHostReverseProxy(u))
http.ListenAndServe(":9999", nil)
}
:9999:8888:8888
404www.baidu.comNewSingleHostReverseProxy
type ReverseProxy struct {
Director func(*http.Request)
Transport http.RoundTripper
FlushInterval time.Duration
ErrorLog *log.Logger
BufferPool BufferPool
ModifyResponse func(*http.Response) error
ErrorHandler func(http.ResponseWriter, *http.Request, error)
}
并无神奇之处,反向代理就是一个结构体!
ErrorHandler404
ModifyResponse
BufferPool
Errorlog
FlushInterval
Transport
Director
接下来就来看看我们是如何得到一个反向代理结构体的。
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
targetQuery := target.RawQuery
director := func(req *http.Request) {
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
if targetQuery == "" || req.URL.RawQuery == "" {
req.URL.RawQuery = targetQuery + req.URL.RawQuery
} else {
req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
}
if _, ok := req.Header["User-Agent"]; !ok {
req.Header.Set("User-Agent", "")
}
}
return &ReverseProxy{Director: director}
}
NewSingleHostReverseProxyDirectorReverseProxydirectorHostPathreq.Host
NewSingleHostReverseProxy
func NewProxy(target *url.URL) *httputil.ReverseProxy {
targetQuery := target.RawQuery
director := func(req *http.Request) {
req.Host = target.Host // -- 加入这句 --
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
if targetQuery == "" || req.URL.RawQuery == "" {
req.URL.RawQuery = targetQuery + req.URL.RawQuery
} else {
req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
}
if _, ok := req.Header["User-Agent"]; !ok {
// explicitly disable User-Agent so it's not set to default value
req.Header.Set("User-Agent", "")
}
}
return &httputil.ReverseProxy{Director: director}
}
httputil.NewSingleHostReverseProxy(u)NewProxy(u)
DirectorNewSingleHostReverseProxyDirector
p := httputil.NewSingleHostReverseProxy(u)
d := p.Director
p.Director = func(r *http.Request) {
d(r)
r.Host = u.Host
}
最后附图一张。