Direct Code
package main
import (
"bytes"
"fmt"
"io"
"log"
"net"
"net/url"
"strings"
)
func App() {
listener, err := net.Listen("tcp", ":9999")
if err != nil {
println("Failed to start, ", err.Error())
}
for {
client, err := listener.Accept()
println("New client……")
if err != nil {
println("Accept failed, ", err.Error())
}
// Dealing with clients' requests
go func() {
var b [1024]byte
n, err := client.Read(b[:])
if err != nil {
println("Read head failed,", err.Error())
}
var method, host, address string
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 access
address = hostPortURL.Scheme + ":443"
} else { // HTTP access
if strings.Index(hostPortURL.Host, ":") == -1 { // Host without port, default 80
address = hostPortURL.Host + ":80"
} else {
address = hostPortURL.Host
}
}
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])
}
// Forwarding
go io.Copy(server, client)
io.Copy(client, server)
}()
}
}
func main() {
App()
}