用golang写一个proxy

我复杂的网络环境中,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 established\r\n\r\n"))
        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", c.netConn.RemoteAddr(), "<->", 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

这里写图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳清风09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值