You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
1.4 KiB
64 lines
1.4 KiB
package main
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
/*
|
|
*
|
|
@author: sre
|
|
@date: 2022/8/21 0021
|
|
@desc: todo
|
|
*
|
|
*/
|
|
|
|
type goPrivoxy struct {
|
|
}
|
|
|
|
func (p *goPrivoxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|
log.Printf("接受请求 %s %s %s\n", req.Method, req.Host, req.RemoteAddr)
|
|
|
|
transport := http.DefaultTransport
|
|
|
|
// 第一步: 代理接受到客户端的请求,复制原来的请求对象,并根据数据配置新请求的各种参数(添加上X-Forward-For头部等)
|
|
outReq := new(http.Request)
|
|
*outReq = *req // 这只是一个浅层拷贝
|
|
|
|
clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
|
|
if err == nil {
|
|
prior, ok := outReq.Header["X-Forwarded-For"]
|
|
if ok {
|
|
clientIP = strings.Join(prior, ", ") + ", " + clientIP
|
|
}
|
|
outReq.Header.Set("X-Forwarded-For", clientIP)
|
|
}
|
|
|
|
// 第二步: 把新请求复制到服务器端,并接收到服务器端返回的响应
|
|
res, err := transport.RoundTrip(outReq)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadGateway) // 502
|
|
return
|
|
}
|
|
|
|
// 第三步:代理服务器对响应做一些处理,然后返回给客户端
|
|
for key, value := range res.Header {
|
|
for _, v := range value {
|
|
w.Header().Add(key, v)
|
|
}
|
|
}
|
|
|
|
w.WriteHeader(res.StatusCode)
|
|
io.Copy(w, res.Body)
|
|
res.Body.Close()
|
|
}
|
|
|
|
func main() {
|
|
log.Println("goPrivoxy start at 0.0.0.0:8118")
|
|
http.Handle("/", &goPrivoxy{})
|
|
http.ListenAndServe("0.0.0.0:8118", nil)
|
|
}
|