-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathconnect.go
44 lines (38 loc) · 1.06 KB
/
connect.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
package main
import (
"io"
"net"
"net/http"
"time"
"strings"
)
// serveConnect handles a CONNECT call on a.config.Addr and connects it to the
// tlsProxy on a.config.TLSAddr
func (a *App) serveConnect(rw http.ResponseWriter, req *http.Request, entry *Entry) {
destHost := strings.TrimPrefix(entry.DestHost, "http://")
if req.URL.Port() == "443" {
destHost = a.config.TLSAddr
}
destConn, err := net.DialTimeout("tcp", destHost, 10*time.Second)
if err != nil {
http.Error(rw, err.Error(), http.StatusServiceUnavailable)
return
}
hijacker, ok := rw.(http.Hijacker)
if !ok {
http.Error(rw, "Hijacking not supported", http.StatusInternalServerError)
return
}
clientConn, _, err := hijacker.Hijack()
if err != nil {
http.Error(rw, err.Error(), http.StatusServiceUnavailable)
}
clientConn.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
go transfer(destConn, clientConn)
go transfer(clientConn, destConn)
}
func transfer(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
_, _ = io.Copy(destination, source)
}