-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler.go
46 lines (35 loc) · 1.01 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package proxy
import (
"net"
"net/http"
"sync"
"github.com/rs/zerolog/log"
)
func HttpProxyConnectHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodConnect {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
logger := log.With().Str("from", r.RemoteAddr).Str("to", r.URL.Host).Logger()
clientConn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer clientConn.Close()
logger.Debug().Msgf("Proxy %s %s", r.Method, r.URL.Host)
targetConn, err := net.Dial("tcp", r.URL.Host)
if err != nil {
writeStatusLine(clientConn, http.StatusServiceUnavailable, r.Proto)
return
}
defer targetConn.Close()
writeStatusLine(clientConn, http.StatusOK, r.Proto)
logger.Debug().Msg("Transfer start")
wg := &sync.WaitGroup{}
wg.Add(2)
go copyIO(wg, targetConn, clientConn)
go copyIO(wg, clientConn, targetConn)
wg.Wait()
logger.Debug().Msg("Transfer complete")
}