什么是网络代理
- 用户通过代理请求信息
- 请求通过网络代理完成转发达到目标服务器
- 目标服务器响应后在通过网络代理回传给用户
网络代理和网络转发区别:
网络代理:用户不直接连接服务器,网络代理去连接,获取数据后返回给用户
网络转发:是路由器对报文的转发操作,中间可能对数据包修改
代理类型
正向代理
原理: 正向代理是从客户端的角度出发,服务于特定用户(比如说一个局域网内的客户)无法访问的服务资源,可以隐藏用户真实IP,比如:浏览器web代理,VPN;
实现一个web浏览器代理:
- 代理接收客户端请求,复制原请求对象,并根据数据配置新请求各种参数
- 把新请求发送到真实的服务端,并接收到服务端返回
- 代理服务器对相应做一些处理,然后返回给客户端
正向代理的代码:
type Pxy struct{
}
func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
fmt.Printf("Received request %s %s %s\n", req.Method, req.Host, req.RemoteAddr)
//panic("implement me")
transport := http.DefaultTransport //定义一个默认的链接池
// 1.浅拷贝对象,然后就在新增属性数据
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)
}
//2.请求下游
resp, err := transport.RoundTrip(outReq)
// resp 里面的内容进行输出
if err != nil {
rw.WriteHeader(http.StatusBadGateway) //状态不良网关
return
}
//3.把下游的请求返回给上游
for key, value := range resp.Header {
//头的写入
for _, v := range value {
rw.Header().Add(key, v)
}
}
rw.WriteHeader(resp.StatusCode)
io.Copy(rw, resp.Body) // 拷贝body的内容
resp.Body.Close()
}
//web 的正向代理
func main() {
fmt.Println("server on :8080")
http.Handle("/", &Pxy{
})
http.ListenAndServe("127.0.0.1:800", nil)
}
反向代理
原理: 是一种服务端的代理技术,帮助服务器做负载均衡,缓存,提供安全校验等,可以隐藏服务器真实IP,比如:LVS技术,nginx proxy_pass等
如何实现一个反向代理:
- 代理接收客户端请求,更改请求结构体信息
- 通过一定的均衡负载算法获取下游的服务地址
- 把请求都送到下游服务器,并获取返回的内容
- 对返回的内容做一些处理,然后返回给客户端
反向代理:
- 先构建好下游服务器
//模拟反向代理的真实服务器
type RealServer struct {
Addr string
}
func (r *RealServer) Run() {
log.Println(