-
Notifications
You must be signed in to change notification settings - Fork 47
/
connection.go
98 lines (83 loc) · 2.21 KB
/
connection.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package proxy
import (
"context"
"crypto/tls"
"encoding/json"
"net"
"net/http"
uuid "github.com/satori/go.uuid"
)
// client connection
type ClientConn struct {
Id uuid.UUID
Conn net.Conn
Tls bool
NegotiatedProtocol string
UpstreamCert bool // Connect to upstream server to look up certificate details. Default: True
clientHello *tls.ClientHelloInfo
}
func newClientConn(c net.Conn) *ClientConn {
return &ClientConn{
Id: uuid.NewV4(),
Conn: c,
Tls: false,
UpstreamCert: true,
}
}
func (c *ClientConn) MarshalJSON() ([]byte, error) {
m := make(map[string]interface{})
m["id"] = c.Id
m["tls"] = c.Tls
m["address"] = c.Conn.RemoteAddr().String()
return json.Marshal(m)
}
// server connection
type ServerConn struct {
Id uuid.UUID
Address string
Conn net.Conn
client *http.Client
tlsConn *tls.Conn
tlsState *tls.ConnectionState
}
func newServerConn() *ServerConn {
return &ServerConn{
Id: uuid.NewV4(),
}
}
func (c *ServerConn) MarshalJSON() ([]byte, error) {
m := make(map[string]interface{})
m["id"] = c.Id
m["address"] = c.Address
peername := ""
if c.Conn != nil {
peername = c.Conn.RemoteAddr().String()
}
m["peername"] = peername
return json.Marshal(m)
}
func (c *ServerConn) TlsState() *tls.ConnectionState {
return c.tlsState
}
// connection context ctx key
var connContextKey = new(struct{})
// connection context
type ConnContext struct {
ClientConn *ClientConn `json:"clientConn"`
ServerConn *ServerConn `json:"serverConn"`
Intercept bool `json:"intercept"` // Indicates whether to parse HTTPS
FlowCount uint32 `json:"-"` // Number of HTTP requests made on the same connection
proxy *Proxy
closeAfterResponse bool // after http response, http server will close the connection
dialFn func(context.Context) error // when begin request, if there no ServerConn, use this func to dial
}
func newConnContext(c net.Conn, proxy *Proxy) *ConnContext {
clientConn := newClientConn(c)
return &ConnContext{
ClientConn: clientConn,
proxy: proxy,
}
}
func (connCtx *ConnContext) Id() uuid.UUID {
return connCtx.ClientConn.Id
}