我看现在关于 golang 反向代理的实现基本依靠的是 httputil.ReverseProxy
:
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
// NewProxy takes target host and creates a reverse proxy
// NewProxy 拿到 targetHost 后,创建一个反向代理
func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
url, err := url.Parse(targetHost)
if err != nil {
return nil, err
}
return httputil.NewSingleHostReverseProxy(url), nil
}
// ProxyRequestHandler handles the http request using proxy
// ProxyRequestHandler 使用 proxy 处理请求
func ProxyRequestHandler(proxy *httputil.ReverseProxy) func( http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
proxy.ServeHTTP(w, r)
}
}
func main() {
// initialize a reverse proxy and pass the actual backend server url here
// 初始化反向代理并传入真正后端服务的地址
proxy, err := NewProxy("http://my-api-server.com")
if err != nil {
panic(err)
}
// handle all requests to your server using the proxy
// 使用 proxy 处理所有请求到你的服务
http.HandleFunc("/", ProxyRequestHandler(proxy))
log.Fatal( http.ListenAndServe(":8080", nil))
}
上面的代码只实现了 监听一个端口 来实现特点网站的反向代码
怎么实现类似 nginx 监听一个端口 支持多个网站的反代实现呢
我想通过 r.URL.Host
针对不同来来源来进行不同的操作 实现了 HTTP 的 单端口多网站的代理实现
return func(w http.ResponseWriter, r *http.Request) {
r.URL.Host
proxy.ServeHTTP(w, r)
}
但是 HTTPS 的怎么做了, 每个不同的域名都有不同的证书
log.Fatal( http.ListenAndServe(":8080", nil))
http.ListenAndServeTLS()
1
dzdh 2022-08-29 13:48:33 +08:00
前阵子刚研究过。
伪代码: ``` func main() { tlsConfig := &tls.Config{ GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { return tls.X509KeyPair(certBlockByte, keyBlockByte), nil }, } httpsSrv := http.Server{ Addr: ":443", TLSConfig: tlsConfig, } httpSrv := http.Server{ Addr: ":80", } go httpSrv.ListenAndServe() go httpsSrv.ListenAndServe() } ``` |
2
dzdh 2022-08-29 13:50:47 +08:00 1
GetCertificate 部分通过接口也好,通过数据库、redis 都可,返回一个 tls.Certficiate 就可
proxy.ServeHTTP 的 request,在传入前,把 request.Host 置空,否则不走 r.URL.Host 直接走了 r.Host |
3
DollarKiller OP @dzdh 谢谢老师 太厉害了
|