Skip to content

Instantly share code, notes, and snippets.

@DigDeeply
Created February 19, 2019 09:50
Show Gist options
  • Save DigDeeply/955d4d65b3ed54e59606a22690deff6a to your computer and use it in GitHub Desktop.
Save DigDeeply/955d4d65b3ed54e59606a22690deff6a to your computer and use it in GitHub Desktop.
A proxy server support Http And Https
package main
import (
"fmt"
"io"
"log"
"net"
"net/url"
"strings"
)
/**
* 代理服务,启动一个代理服务,支持https和http服务.
* @author fukun 2019-02-19
**/
func main() {
fmt.Println("hello, proxy")
ln, err := net.Listen("tcp4", ":8080")
if err != nil {
log.Fatalln(err)
}
for {
conn, err := ln.Accept()
if err != nil {
log.Fatalln(err)
}
go handle(conn)
}
}
func handle(pconn net.Conn) {
var b [2048]byte
n, err := pconn.Read(b[:])
defer pconn.Close()
fmt.Println(n, string(b[:]))
// getRemoteAddr
headerstrs := strings.Split(string(b[:]), "\r\n")
var method string
var turl string
var version string
n, err = fmt.Sscanf(headerstrs[0], "%s %s %s", &method, &turl, &version)
// fmt.Println(method, turl, version)
parseURL, err := url.Parse(turl)
fmt.Println(parseURL.Host, parseURL.Scheme, err)
var targetHost string
if method == "CONNECT" {
targetHost = turl
} else {
targetPort := ""
if parseURL.Port() == "" {
targetPort = "80"
}
targetHost = fmt.Sprintf("%s:%s", parseURL.Host, targetPort)
}
fmt.Println("dial remote addr: ", targetHost)
conn, err := net.Dial("tcp4", targetHost)
if method == "CONNECT" {
pconn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
} else {
conn.Write(b[:])
}
if err != nil {
log.Fatalln(err)
}
stop := make(chan struct{}, 1)
go func() {
_, err := io.Copy(pconn, conn)
if err != nil {
log.Fatalln("copy pconn to conn", err)
}
stop <- struct{}{}
}()
go func() {
_, err := io.Copy(conn, pconn)
if err != nil {
log.Fatalln(err)
}
stop <- struct{}{}
}()
<-stop
<-stop
conn.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment