-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathproxy.go
118 lines (101 loc) · 2.61 KB
/
proxy.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package proxy
import (
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"github.com/gobwas/ws"
yaklog "github.com/yaklang/yaklang/common/log"
"golang.org/x/net/proxy"
"net"
"net/http"
"time"
)
type HandleReq func(req *http.Request, ctx *Context) (*http.Request, *http.Response)
type HandleResp func(resp *http.Response, ctx *Context) *http.Response
type HandleWebSocket func(frame ws.Frame, reverse bool, ctx *Context) ws.Frame
type HandleRaw func(raw []byte, reverse bool, ctx *Context) []byte
type HttpProxy struct {
Host string
Port string
Threads int
Cert *x509.Certificate
Key *rsa.PrivateKey
DefaultSNI string
HTTPClient *http.Client
Dialer proxy.Dialer
reqHandlers []HandleReq
respHandlers []HandleResp
webSocketHandlers []HandleWebSocket
rawHandlers []HandleRaw
}
func NewHttpProxy() *HttpProxy {
return &HttpProxy{
Host: "0.0.0.0",
Port: "1080",
Threads: 100,
HTTPClient: &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 15 * time.Second,
KeepAlive: 15 * time.Second,
}).DialContext,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
ForceAttemptHTTP2: false,
//DisableCompression: false,
},
},
}
}
const (
MODE_ALL = iota
MODE_WITHOUT_HANDLER
)
func (h *HttpProxy) Copy(mode int) *HttpProxy {
httpProxy := &HttpProxy{
Host: h.Host,
Port: h.Port,
Threads: h.Threads,
Cert: h.Cert,
Key: h.Key,
DefaultSNI: h.DefaultSNI,
HTTPClient: h.HTTPClient,
Dialer: h.Dialer,
}
switch mode {
case MODE_ALL:
httpProxy.reqHandlers = h.reqHandlers
httpProxy.respHandlers = h.respHandlers
httpProxy.webSocketHandlers = h.webSocketHandlers
httpProxy.rawHandlers = h.rawHandlers
case MODE_WITHOUT_HANDLER:
}
return httpProxy
}
func (h *HttpProxy) Serve(mode Mode) {
httpProxy, err := net.Listen("tcp", h.Host+":"+h.Port)
if err != nil {
yaklog.Fatalf("listen %s failed", h.Host+":"+h.Port)
}
yaklog.Infof("listen %s success", h.Host+":"+h.Port)
threads := make(chan struct{}, h.Threads)
for {
ctx := NewContext()
client, err := httpProxy.Accept()
if err != nil {
yaklog.Errorf("%s accept client connection failed - %v", ctx.Preffix(), err)
continue
}
ctx.ClientAddr = client.RemoteAddr().String()
yaklog.Infof("%s accept %s connection success", ctx.Preffix(), ctx.ClientAddr)
threads <- struct{}{}
go func(client net.Conn) {
defer func() {
_ = client.Close()
<-threads
}()
_ = mode.HandleConnect(client, h, ctx)
}(client)
}
}