Files
sower/proxy/util.go
T
2020-03-22 16:49:40 +08:00

75 lines
1.5 KiB
Go

package proxy
import (
"bufio"
"crypto/tls"
"io"
"net"
"net/http"
"sync"
"sync/atomic"
"time"
"github.com/wweir/sower/util"
)
func ParseHTTP(conn net.Conn) (net.Conn, string, error) {
teeConn := &util.TeeConn{Conn: conn}
defer teeConn.Stop()
resp, err := http.ReadRequest(bufio.NewReader(teeConn))
if err != nil {
return teeConn, "", err
}
if _, _, err := net.SplitHostPort(resp.Host); err != nil {
resp.Host = net.JoinHostPort(resp.Host, "80")
}
return teeConn, resp.Host, nil
}
func ParseHTTPS(conn net.Conn) (net.Conn, string, error) {
teeConn := &util.TeeConn{Conn: conn}
defer teeConn.Stop()
var domain string
tls.Server(teeConn, &tls.Config{
GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
domain = hello.ServerName
return nil, nil
},
}).Handshake()
return teeConn, net.JoinHostPort(domain, "443"), nil
}
func withDefaultPort(addr string, port string) (address, host string) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return net.JoinHostPort(addr, port), addr
}
return addr, host
}
func relay(conn1, conn2 net.Conn) {
wg := &sync.WaitGroup{}
exitFlag := new(int32)
wg.Add(2)
go redirect(conn2, conn1, wg, exitFlag)
redirect(conn1, conn2, wg, exitFlag)
wg.Wait()
}
func redirect(dst, src net.Conn, wg *sync.WaitGroup, exitFlag *int32) {
io.Copy(dst, src)
if atomic.CompareAndSwapInt32(exitFlag, 0, 1) {
// wakeup blocked goroutine
now := time.Now()
src.SetDeadline(now)
dst.SetDeadline(now)
}
wg.Done()
}