Last active
November 25, 2018 13:37
-
-
Save dfang/72c306f371347446e3a6236f80b3735e to your computer and use it in GitHub Desktop.
simplest http proxy server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"fmt" | |
"io" | |
"log" | |
"net" | |
"net/url" | |
"strings" | |
) | |
func main() { | |
log.SetFlags(log.LstdFlags | log.Lshortfile) | |
l, err := net.Listen("tcp", ":8787") | |
if err != nil { | |
log.Panic(err) | |
} else { | |
log.Println("listening on :8787") | |
} | |
for { | |
client, err := l.Accept() | |
if err != nil { | |
log.Panic(err) | |
} else { | |
log.Println(client) | |
} | |
go handleClientRequest(client) | |
} | |
} | |
func handleClientRequest(client net.Conn) { | |
log.Println(client) | |
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.Println(b) | |
fmt.Println(len(b)) | |
// 打印HTTP HEADER | |
fmt.Println(string(b[:])) | |
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) | |
} | |
// 最简单的demo | |
// 只为了理解http proxy如何工作 | |
// https://www.jianshu.com/p/53e219fbf3c5 | |
// https://gist.github.com/fabrizioc1/4327250 | |
// https://medium.com/@mlowicki/http-s-proxy-in-golang-in-less-than-100-lines-of-code-6a51c2f2c38c | |
// https://gist.github.com/yowu/f7dc34bd4736a65ff28d | |
// 用curl测试 | |
// curl -v -x localhost:8787 baidu.com | |
// curl -x socks5h://localhost:8001 http://www.baidu.com/ | |
// curl -x socks5://localhost:8001 http://www.baidu.com/ | |
// curl -x socks4h://localhost:8001 http://www.baidu.com/ | |
// curl --socks4 proxy.example.com http://www.example.com/ | |
// curl --socks5 proxy.example.com http://www.example.com/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
client
https://play.golang.org/p/l0iLtkD1DV
http://nextdoorhacker.com/2016/05/08/proxy-aware-http-client-in-go/