首先在linux vps上,安装go环境。
把以下蓝色的代码保存为http-proxy-by-flysnow.go,保存在linux vps上。
把以下蓝色的代码保存为http-proxy-by-flysnow.go,保存在linux vps上。
package main
import (
"bytes"
"fmt"
"io"
"log"
"net"
"net/url"
"strings"
)
func main() {
log.SetFlags(log.LstdFlags|log.Lshortfile)
l, err := net.Listen("tcp", ":5082")
if err != nil {
log.Panic(err)
}
for {
client, err := l.Accept()
if err != nil {
log.Panic(err)
}
go handleClientRequest(client)
}
}
func handleClientRequest(client net.Conn) {
if client == nil {
return
}
defer client.Close()
var b [1024]byte
n, err := client.Read(b[:])
if err != nil {
log.Println(err)
return
}
var method, host, address string
fmt.Sscanf(string(b[:bytes.IndexByte(b[:], '\n')]), "%s%s", &method, &host)
hostPortURL, err := url.Parse(host)
if err != nil {
log.Println(err)
return
}
if hostPortURL.Opaque == "443" { //https访问
address = hostPortURL.Scheme + ":443"
} else { //http访问
if strings.Index(hostPortURL.Host, ":") == -1 { //host不带端口, 默认80
address = hostPortURL.Host + ":80"
} else {
address = hostPortURL.Host
}
}
//获得了请求的host和port,就开始拨号吧
server, err := net.Dial("tcp", address)
if err != nil {
log.Println(err)
return
}
if method == "CONNECT" {
fmt.Fprint(client, "HTTP/1.1 200 Connection established\r\n\r\n")
} else {
server.Write(b[:n])
}
//进行转发
go io.Copy(server, client)
io.Copy(client, server)
}
然后,运行go build http-proxy-by-flysnow.go
在当前目录下,就会生成可执行文件http-proxy-by-flysnow。
root@host ~]# ./http-proxy-by-flysnow &
[1] 30974
[root@host ~]#
[root@host ~]# lsof -i:5082
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
http-prox 30974 root 3u IPv6 1803120 0t0 TCP *:qcp (LISTEN)
[root@host ~]#
这个http-proxy-by-flysnow可以用作各种tunnel程序的后端程序。