一个总结:
正向代理:隐藏客户端;反向代理:隐藏服务端;
下面的代码,可支持隐藏https服务,暴露为一个http(非https)的地址
此处,为golang实现的一个http转发的服务,其实也就是类似一个反向代理的功能,特此记录下源码,以备后续使用时查询
package main
import (
"compress/flate"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
)
type ProxyHandler struct{}
// 检测返回的body是否经过压缩,并返回解压的内容
func switchContentEncoding(res *http.Response) (bodyReader io.Reader, err error) {
switch res.Header.Get("Content-Encoding") {
case "gzip":
bodyReader, err = gzip.NewReader(res.Body)
case "deflate":
bodyReader = flate.NewReader(res.Body)
default:
bodyReader = res.Body
}
return
}
func (*ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//fmt.Println(r.RequestURI)
// /a?b=123
defer func() {
if err := recover(); err != nil {
w.WriteHeader(500)
log.Println(err)
}
}()
fmt.Println(r.URL) // /a?b=123
fmt.Println(r.URL.Path) // /a
fmt.Println(r.Body)
//if r.URL.Path == "/requisition/synOrder" {
//真实的后端服务地址
newreq, _ := http.NewRequest(r.Method, "https://backend.server.com"+r.URL.Path, r.Body)
//将原请求的header,拷贝赋值到新的请求上面
for k, v := range r.Header {
fmt.Printf("%s=%s\n", k, v[0])
newreq.Header.Set(k, v[0])
}
newresponse, _ := http.DefaultClient.Do(newreq)
reader := newresponse.Body
//下面的if为后端服务启动了gzip压缩,对返回的数据解压缩
if newresponse.Header.Get("Content-Encoding") == "gzip" {
reader, _ = gzip.NewReader(newresponse.Body)
}
res_cont, _ := ioutil.ReadAll(reader)
fmt.Println("=====response=====")
fmt.Println(string(res_cont))
w.Write(res_cont)
return
//}
w.Write([]byte("default index"))
}
// https://blog.51cto.com/u_12903656/5290512
func main() {
http.ListenAndServe(":8080", &ProxyHandler{})
}