Last active
May 9, 2018 10:42
-
-
Save ego008/bb403cc9bfb6736d1b6d9626dddf5c36 to your computer and use it in GitHub Desktop.
Golang http/https proxy
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 | |
// ex $ curl --proxy http://127.0.0.1:12345 -L https://www.google.com | |
import ( | |
"bytes" | |
"io" | |
"log" | |
"net" | |
"net/url" | |
"strconv" | |
"strings" | |
) | |
func main() { | |
log.SetFlags(log.LstdFlags | log.Lshortfile) | |
l, err := net.Listen("tcp", ":12345") | |
if err != nil { | |
log.Panic(err) | |
} | |
defer l.Close() | |
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 | |
ni := bytes.IndexByte(b[:], '\n') | |
if ni != -1 { | |
// 避免url 过长崩溃 | |
sl := strings.Split(string(b[:ni]), " ") | |
if len(sl) >= 2 { | |
method, host = sl[0], sl[1] | |
if _, err := strconv.Atoi(string(host[0])); err == nil { | |
// fixed https://github.com/golang/go/issues/19297 | |
host = "//" + 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" { | |
client.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) | |
} else { | |
server.Write(b[:n]) | |
} | |
//进行转发 | |
go io.Copy(server, client) | |
io.Copy(client, server) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment