-
Notifications
You must be signed in to change notification settings - Fork 47
/
addon.go
114 lines (89 loc) · 4.12 KB
/
addon.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
package proxy
import (
"io"
"net/http"
"time"
log "github.com/sirupsen/logrus"
)
type Addon interface {
// A client has connected to mitmproxy. Note that a connection can correspond to multiple HTTP requests.
ClientConnected(*ClientConn)
// A client connection has been closed (either by us or the client).
ClientDisconnected(*ClientConn)
// Mitmproxy has connected to a server.
ServerConnected(*ConnContext)
// A server connection has been closed (either by us or the server).
ServerDisconnected(*ConnContext)
// The TLS handshake with the server has been completed successfully.
TlsEstablishedServer(*ConnContext)
// HTTP request headers were successfully read. At this point, the body is empty.
Requestheaders(*Flow)
// The full HTTP request has been read.
Request(*Flow)
// HTTP response headers were successfully read. At this point, the body is empty.
Responseheaders(*Flow)
// The full HTTP response has been read.
Response(*Flow)
// Stream request body modifier
StreamRequestModifier(*Flow, io.Reader) io.Reader
// Stream response body modifier
StreamResponseModifier(*Flow, io.Reader) io.Reader
// onAccessProxyServer
AccessProxyServer(req *http.Request, res http.ResponseWriter)
}
// BaseAddon do nothing
type BaseAddon struct{}
func (addon *BaseAddon) ClientConnected(*ClientConn) {}
func (addon *BaseAddon) ClientDisconnected(*ClientConn) {}
func (addon *BaseAddon) ServerConnected(*ConnContext) {}
func (addon *BaseAddon) ServerDisconnected(*ConnContext) {}
func (addon *BaseAddon) TlsEstablishedServer(*ConnContext) {}
func (addon *BaseAddon) Requestheaders(*Flow) {}
func (addon *BaseAddon) Request(*Flow) {}
func (addon *BaseAddon) Responseheaders(*Flow) {}
func (addon *BaseAddon) Response(*Flow) {}
func (addon *BaseAddon) StreamRequestModifier(f *Flow, in io.Reader) io.Reader { return in }
func (addon *BaseAddon) StreamResponseModifier(f *Flow, in io.Reader) io.Reader { return in }
func (addon *BaseAddon) AccessProxyServer(req *http.Request, res http.ResponseWriter) {}
// LogAddon log connection and flow
type LogAddon struct {
BaseAddon
}
func (addon *LogAddon) ClientConnected(client *ClientConn) {
log.Infof("%v client connect\n", client.Conn.RemoteAddr())
}
func (addon *LogAddon) ClientDisconnected(client *ClientConn) {
log.Infof("%v client disconnect\n", client.Conn.RemoteAddr())
}
func (addon *LogAddon) ServerConnected(connCtx *ConnContext) {
log.Infof("%v server connect %v (%v->%v)\n", connCtx.ClientConn.Conn.RemoteAddr(), connCtx.ServerConn.Address, connCtx.ServerConn.Conn.LocalAddr(), connCtx.ServerConn.Conn.RemoteAddr())
}
func (addon *LogAddon) ServerDisconnected(connCtx *ConnContext) {
log.Infof("%v server disconnect %v (%v->%v) - %v\n", connCtx.ClientConn.Conn.RemoteAddr(), connCtx.ServerConn.Address, connCtx.ServerConn.Conn.LocalAddr(), connCtx.ServerConn.Conn.RemoteAddr(), connCtx.FlowCount)
}
func (addon *LogAddon) Requestheaders(f *Flow) {
log.Debugf("%v Requestheaders %v %v\n", f.ConnContext.ClientConn.Conn.RemoteAddr(), f.Request.Method, f.Request.URL.String())
start := time.Now()
go func() {
<-f.Done()
var StatusCode int
if f.Response != nil {
StatusCode = f.Response.StatusCode
}
var contentLen int
if f.Response != nil && f.Response.Body != nil {
contentLen = len(f.Response.Body)
}
log.Infof("%v %v %v %v %v - %v ms\n", f.ConnContext.ClientConn.Conn.RemoteAddr(), f.Request.Method, f.Request.URL.String(), StatusCode, contentLen, time.Since(start).Milliseconds())
}()
}
type UpstreamCertAddon struct {
BaseAddon
UpstreamCert bool // Connect to upstream server to look up certificate details.
}
func NewUpstreamCertAddon(upstreamCert bool) *UpstreamCertAddon {
return &UpstreamCertAddon{UpstreamCert: upstreamCert}
}
func (addon *UpstreamCertAddon) ClientConnected(conn *ClientConn) {
conn.UpstreamCert = addon.UpstreamCert
}