add proxyListener

addon-dailer
lqqyt2423 2 years ago
parent 57770b464f
commit d95a8ccf21

@ -23,6 +23,7 @@ func NewClient(c net.Conn) *Client {
type Server struct { type Server struct {
Id uuid.UUID Id uuid.UUID
Conn net.Conn
Client *http.Client Client *http.Client
} }

@ -1,10 +1,10 @@
package flow package flow
import ( import (
"context"
"crypto/tls" "crypto/tls"
"net" "net"
"net/http" "net/http"
"time"
"github.com/lqqyt2423/go-mitmproxy/connection" "github.com/lqqyt2423/go-mitmproxy/connection"
) )
@ -16,6 +16,22 @@ type ConnContext struct {
Server *connection.Server Server *connection.Server
} }
func NewConnContext(c net.Conn) *ConnContext {
client := connection.NewClient(c)
return &ConnContext{
Client: client,
}
}
type serverConn struct {
net.Conn
}
func (c *serverConn) Close() error {
log.Debugln("in http serverConn close")
return c.Conn.Close()
}
func (connCtx *ConnContext) InitHttpServer(SslInsecure bool) { func (connCtx *ConnContext) InitHttpServer(SslInsecure bool) {
if connCtx.Server != nil { if connCtx.Server != nil {
return return
@ -30,10 +46,19 @@ func (connCtx *ConnContext) InitHttpServer(SslInsecure bool) {
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
// todo: change here // todo: change here
DialContext: (&net.Dialer{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
Timeout: 30 * time.Second, c, err := (&net.Dialer{
KeepAlive: 30 * time.Second, // Timeout: 30 * time.Second,
}).DialContext, // KeepAlive: 30 * time.Second,
}).DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
cw := &serverConn{c}
server.Conn = cw
return cw, nil
},
ForceAttemptHTTP2: false, // disable http2 ForceAttemptHTTP2: false, // disable http2
DisableCompression: true, // To get the original response from the server, set Transport.DisableCompression to true. DisableCompression: true, // To get the original response from the server, set Transport.DisableCompression to true.
@ -65,8 +90,8 @@ func (connCtx *ConnContext) InitHttpsServer(SslInsecure bool) {
// todo: change here // todo: change here
DialContext: (&net.Dialer{ DialContext: (&net.Dialer{
Timeout: 30 * time.Second, // Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second, // KeepAlive: 30 * time.Second,
}).DialContext, }).DialContext,
ForceAttemptHTTP2: false, // disable http2 ForceAttemptHTTP2: false, // disable http2

@ -16,13 +16,13 @@ import (
// 模拟了标准库中 server 运行,目的是仅通过当前进程内存转发 socket 数据,不需要经过 tcp 或 unix socket // 模拟了标准库中 server 运行,目的是仅通过当前进程内存转发 socket 数据,不需要经过 tcp 或 unix socket
// mock net.Listener // mock net.Listener
type listener struct { type middleListener struct {
connChan chan net.Conn connChan chan net.Conn
} }
func (l *listener) Accept() (net.Conn, error) { return <-l.connChan, nil } func (l *middleListener) Accept() (net.Conn, error) { return <-l.connChan, nil }
func (l *listener) Close() error { return nil } func (l *middleListener) Close() error { return nil }
func (l *listener) Addr() net.Addr { return nil } func (l *middleListener) Addr() net.Addr { return nil }
type pipeAddr struct { type pipeAddr struct {
remoteAddr string remoteAddr string
@ -106,7 +106,7 @@ func NewMiddle(proxy *Proxy, caPath string) (Interceptor, error) {
} }
m.Server = server m.Server = server
m.Listener = &listener{make(chan net.Conn)} m.Listener = &middleListener{make(chan net.Conn)}
return m, nil return m, nil
} }
@ -155,7 +155,7 @@ func (m *Middle) intercept(serverConn *connBuf) {
// tls // tls
serverConn.connContext.Client.Tls = true serverConn.connContext.Client.Tls = true
serverConn.connContext.InitHttpsServer(m.Proxy.Opts.SslInsecure) serverConn.connContext.InitHttpsServer(m.Proxy.Opts.SslInsecure)
m.Listener.(*listener).connChan <- serverConn m.Listener.(*middleListener).connChan <- serverConn
} else { } else {
// ws // ws
DefaultWebSocket.WS(serverConn, serverConn.host) DefaultWebSocket.WS(serverConn, serverConn.host)

@ -6,10 +6,9 @@ import (
"io" "io"
"net" "net"
"net/http" "net/http"
"time" "sync"
"github.com/lqqyt2423/go-mitmproxy/addon" "github.com/lqqyt2423/go-mitmproxy/addon"
"github.com/lqqyt2423/go-mitmproxy/connection"
"github.com/lqqyt2423/go-mitmproxy/flow" "github.com/lqqyt2423/go-mitmproxy/flow"
_log "github.com/sirupsen/logrus" _log "github.com/sirupsen/logrus"
) )
@ -30,8 +29,42 @@ type Proxy struct {
Server *http.Server Server *http.Server
Interceptor Interceptor Interceptor Interceptor
Addons []addon.Addon Addons []addon.Addon
}
type proxyListener struct {
net.Listener
proxy *Proxy
}
func (l *proxyListener) Accept() (net.Conn, error) {
c, err := l.Listener.Accept()
if err != nil {
return nil, err
}
return &proxyConn{
Conn: c,
proxy: l.proxy,
}, nil
}
activeConn map[net.Conn]*flow.ConnContext type proxyConn struct {
net.Conn
proxy *Proxy
connCtx *flow.ConnContext
closeOnce sync.Once
}
func (c *proxyConn) Close() error {
log.Debugln("in proxyConn close")
c.closeOnce.Do(func() {
for _, addon := range c.proxy.Addons {
addon.ClientDisconnected(c.connCtx.Client)
}
})
return c.Conn.Close()
} }
func NewProxy(opts *Options) (*Proxy, error) { func NewProxy(opts *Options) (*Proxy, error) {
@ -42,26 +75,15 @@ func NewProxy(opts *Options) (*Proxy, error) {
proxy.Server = &http.Server{ proxy.Server = &http.Server{
Addr: opts.Addr, Addr: opts.Addr,
Handler: proxy, Handler: proxy,
IdleTimeout: 5 * time.Second, // IdleTimeout: 5 * time.Second,
ConnContext: func(ctx context.Context, c net.Conn) context.Context { ConnContext: func(ctx context.Context, c net.Conn) context.Context {
client := connection.NewClient(c) connCtx := flow.NewConnContext(c)
connCtx := &flow.ConnContext{
Client: client,
}
proxy.activeConn[c] = connCtx
return context.WithValue(ctx, flow.ConnContextKey, connCtx)
},
ConnState: func(c net.Conn, cs http.ConnState) {
if cs == http.StateNew {
client := proxy.activeConn[c].Client
for _, addon := range proxy.Addons { for _, addon := range proxy.Addons {
addon.ClientConnected(client) addon.ClientConnected(connCtx.Client)
}
} else if cs == http.StateClosed {
proxy.whenClientConnClose(c)
} }
c.(*proxyConn).connCtx = connCtx
return context.WithValue(ctx, flow.ConnContextKey, connCtx)
}, },
} }
@ -77,8 +99,6 @@ func NewProxy(opts *Options) (*Proxy, error) {
proxy.Addons = make([]addon.Addon, 0) proxy.Addons = make([]addon.Addon, 0)
proxy.activeConn = make(map[net.Conn]*flow.ConnContext)
return proxy, nil return proxy, nil
} }
@ -91,7 +111,20 @@ func (proxy *Proxy) Start() error {
go func() { go func() {
log.Infof("Proxy start listen at %v\n", proxy.Server.Addr) log.Infof("Proxy start listen at %v\n", proxy.Server.Addr)
err := proxy.Server.ListenAndServe() addr := proxy.Server.Addr
if addr == "" {
addr = ":http"
}
ln, err := net.Listen("tcp", addr)
if err != nil {
errChan <- err
return
}
pln := &proxyListener{
Listener: ln,
proxy: proxy,
}
err = proxy.Server.Serve(pln)
errChan <- err errChan <- err
}() }()
@ -286,11 +319,10 @@ func (proxy *Proxy) handleConnect(res http.ResponseWriter, req *http.Request) {
return return
} }
cconn.(*net.TCPConn).SetLinger(0) // send RST other than FIN when finished, to avoid TIME_WAIT state // cconn.(*net.TCPConn).SetLinger(0) // send RST other than FIN when finished, to avoid TIME_WAIT state
cconn.(*net.TCPConn).SetKeepAlive(false) // cconn.(*net.TCPConn).SetKeepAlive(false)
defer func() { defer func() {
cconn.Close() cconn.Close()
proxy.whenClientConnClose(cconn)
}() }()
_, err = io.WriteString(cconn, "HTTP/1.1 200 Connection Established\r\n\r\n") _, err = io.WriteString(cconn, "HTTP/1.1 200 Connection Established\r\n\r\n")
@ -301,15 +333,3 @@ func (proxy *Proxy) handleConnect(res http.ResponseWriter, req *http.Request) {
Transfer(log, conn, cconn) Transfer(log, conn, cconn)
} }
func (proxy *Proxy) whenClientConnClose(c net.Conn) {
connCtx := proxy.activeConn[c]
for _, addon := range proxy.Addons {
addon.ClientDisconnected(connCtx.Client)
}
connCtx.Server.Client.CloseIdleConnections()
delete(proxy.activeConn, c)
}

Loading…
Cancel
Save