golang 实现正向代理服务器
正向代理
是一种客户端的代理技术,帮助客户端访问无法访问的服务资源,可以隐藏用户真实IP。比如∶浏览器web代理、VPN等
反向代理
是一种服务端的代理技术,帮助服务器做负载均衡、缓存、提供安全校验等,可以隐藏服务器真实IP。比如:LVS技术、nginx proxy_pass等
实现浏览器 正向代理过程
- 用户请求
- 代理服务器监听中
- 上游TCP连接
- 回调方法
- 拷贝请求数据
- 请求下游服务 Transport RoundTrip
- 回写上游数据
实现浏览器 正向代理
运行代码: demo/proxy/forward_proxy/forward_proxy.go
浏览器设置: 打开计算机 代理设置 勾选 web 代理 设置代理服务器ip/端口:localhost:8080
正向代理 - 代码实现
package main
import (
"fmt"
"io"
"net"
"net/http"
"strings"
)
/**
正向代理
*/
type Pxy struct{}
// 定义结构体 实现 ServeHTTP。就能把请求 传递到 http handle 里面
func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
fmt.Printf("Received request %s %s %s\n", req.Method, req.Host, req.RemoteAddr)
transport := http.DefaultTransport // 数据链接词
// step 1,浅拷贝对象,然后就再新增属性数据; 避免使用同一个 http,下文重定向是被影响
outReq := new(http.Request)
*outReq = *req
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
if prior, ok := outReq.Header["X-Forwarded-For"]; ok {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
outReq.Header.Set("X-Forwarded-For", clientIP) // X-Forwarded-For 设置远程代理 ip
}
// step 2, 请求下游
res, err := transport.RoundTrip(outReq)
if err != nil {
rw.WriteHeader(http.StatusBadGateway)
return
}
// step 3, 把下游请求内容返回给上游
for key, value := range res.Header {
for _, v := range value {
rw.Header().Add(key, v)
}
}
rw.WriteHeader(res.StatusCode)
io.Copy(rw, res.Body)
res.Body.Close()
}
func main() {
fmt.Println("Serve on :8080")
http.Handle("/", &Pxy{})
http.ListenAndServe("0.0.0.0:8080", nil)
}