加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

用golang写一个proxy

发布时间:2020-12-16 09:40:38 所属栏目:大数据 来源:网络整理
导读:我复杂的网络环境中,proxy是个很有用的工具,我们可以通过proxy代理帮我们完成网络流量的转发。 这个proxy得先能接收请求,所以这里先启动一个tcp的监听,获取请求 func (s * Server ) Start() { var err error s.listener, err = net.Listen( "tcp" ,s.add

我复杂的网络环境中,proxy是个很有用的工具,我们可以通过proxy代理帮我们完成网络流量的转发。
这个proxy得先能接收请求,所以这里先启动一个tcp的监听,获取请求

func (s *Server) Start() {
    var err error
    s.listener,err = net.Listen("tcp",s.addr)
    if err != nil {
        glog.Fatal(err)
    }


    glog.Infof("proxy listen in %s,waiting for connection...n",s.addr)

    for {
        conn,err := s.listener.Accept()
        if err != nil {
            glog.Error(err)
            continue
        }
        go newConn(s,conn).serve()
    }
}

当获取的请求连接conn,交个serve方法去处理。

func (c *conn) serve() {
    defer c.netConn.Close()
    rawHttpRequestHeader,remote,isHttps,err := c.getTunnelInfo()
    if err != nil {
        glog.Error(err)
        return
    }


    glog.Info("connecting to " + remote)
    remoteConn,err := net.Dial("tcp",remote)
    if err != nil {
        glog.Error(err)
        return
    }

    if isHttps {
        glog.V(10).Infof("get https req remote %s n",remote)
        // if https,should sent 200 to client
        _,err = c.netConn.Write([]byte("HTTP/1.1 200 Connection establishedrnrn"))
        if err != nil {
            glog.Error(err)
            return
        }
    } else {
        // if not https,should sent the request header to remote
        _,err = rawHttpRequestHeader.WriteTo(remoteConn)
        if err != nil {
            glog.Error(err)
            return
        }
    }

    // build bidirectional-streams
    glog.Info("begin tunnel",c.netConn.RemoteAddr(),"<->",remote)
    c.tunnel(remoteConn)
    glog.Info("stop tunnel",remote)
}

getTunnelInfo是获取连接信息的,譬如访问host、port、协议和请求头之类的东西。
然后就可以建立远程连接,通过net.Dial(“tcp”,remote)建立。
最后就是简单复制流量c.tunnel(remoteConn),具体代码如下

_,err := io.Copy(c.netConn,remoteConn)

这样就可以通过它转发流量
下面是例子
启动服务

./goproxy --addr :9999 --log_dir=/tmp/goproxy --v=10

到另外的机器上面执行
http:
curl --proxy 10.39.0.45:9999 http://10.39.0.45:9090

https:
curl -k --proxy 10.39.0.45:9999 https://10.0.0.43:443

完整代码如下
https://github.com/timchenxiaoyu/goproxy。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读