您的位置:首页 > 理论基础 > 计算机网络

一个简单的tcp代理(golang实现)

2015-05-13 14:49 561 查看
最近需要在生产环境中调试一个http的问题,但是网管说不能安装抓包工具......

想到的一种替代方案是,增加个反向代理,然后把所有的request和response打印一下即可

1. nginx/haproxy来做反向代理,肯定可行,但是我配置的不太熟练

2. 自己写个简单的即可,正好golang写这类程序很快,所以就花了一会儿重新熟悉下go的语法(有阵子没看忘掉了......)然后写了个

主要的思路就是接收客户端的request,然后把里面的Host header改成真正的服务器的Host,然后转发,并把接收到的response回发个客户端即可

下面是全部的代码,用法很简单 ./tcpproxy 127.0.0.1 1080 www.baidu.com:80

// TcpProxy project main.go
package main

import (
"fmt"
"net"
"os"
"regexp"
"strconv"
)

func main() {
if len(os.Args) < 4 {
fmt.Println("missing message!")
return
}
ip := os.Args[1]
port, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Println("error happened ,exit")
return
}
addr := os.Args[3]
host := "Host: " + addr

Service(ip, port, addr, host)
}

func Service(ip string, port int, dstaddr string, dsthost string) {
// listen and accept
listen, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP(ip), port, ""})
if err != nil {
fmt.Println("listen error: ", err.Error())
return
}
fmt.Println("init done...")

for {
client, err := listen.AcceptTCP()
if err != nil {
fmt.Println("accept error: ", err.Error())
continue
}
go Channal(client, dstaddr, dsthost)
}
}

func Channal(client *net.TCPConn, addr string, rhost string) {

tcpAddr, _ := net.ResolveTCPAddr("tcp4", addr)
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
fmt.Println("connection error: ", err.Error())
client.Close()
return
}

go ReadRequest(client, conn, rhost)
ReadResponse(conn, client)
}

func ReadRequest(lconn *net.TCPConn, rconn *net.TCPConn, dsthost string) {
for {
buf := make([]byte, 10240)
n, err := lconn.Read(buf)
if err != nil {
break
}

mesg := changeHost(string(buf[:n]), dsthost)
// print request
fmt.Println(mesg)
rconn.Write([]byte(mesg))
}
lconn.Close()
}

func ReadResponse(lconn *net.TCPConn, rconn *net.TCPConn) {
for {
buf := make([]byte, 10240)
n, err := lconn.Read(buf)
if err != nil {
break
}

fmt.Println(string(buf[:n]))
rconn.Write(buf[:n])
}
lconn.Close()
}

func changeHost(request string, newhost string) string {
reg := regexp.MustCompile(`Host[^\r\n]+`)
return reg.ReplaceAllString(request, newhost)
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: