实现的效果:

如果访问的url路径是类似 /163/  或 /163/debian 的形式,则转发到163开源镜像服务器

 

直接上代码:

 

类似的还有更简单的做法,关键在httputil.ReverseProxy的Director字段

 

关于req.URL.Host和req.Host:

go http包中对request中Host的注释:

// For server requests Host specifies the host on which the
// URL is sought. Per RFC 2616, this is either the value of
// the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string

另外:
req.URL.Host是从URL中解析出来的,
req.Host是http请求头部"Host" , 这个头部用于实现虚拟主机(一个ip托管多个域名),http1.1规范中,Host头是必须存在的

对于下面的请求:
GET /index.html HTTP/1.1
Host: www.example.org:8080
req.URL.Host是空的
对于通过代理的请求,req.URL.Host是目标主机,req.Host是代理服务器。
对于不是走代理的请求,req.URL.Host是空的,req.Host是目标主机