recorder: add input/output traffic stats for handler recorder object
This commit is contained in:
@@ -9,7 +9,7 @@ require (
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/gin-contrib/cors v1.6.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-gost/core v0.1.6
|
||||
github.com/go-gost/core v0.1.7
|
||||
github.com/go-gost/gosocks4 v0.0.1
|
||||
github.com/go-gost/gosocks5 v0.4.2
|
||||
github.com/go-gost/plugin v0.1.1
|
||||
|
||||
@@ -53,8 +53,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-gost/core v0.1.6 h1:0Vdck2qrcfi1jz5f7fhfj+Uu0qvZhCdTdIisa5NDa98=
|
||||
github.com/go-gost/core v0.1.6/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
|
||||
github.com/go-gost/core v0.1.7 h1:EP2Ux2SZR1omV6362MfTZG+oZTuaAODGqc0M9c/ZdEI=
|
||||
github.com/go-gost/core v0.1.7/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
|
||||
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s=
|
||||
github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
|
||||
github.com/go-gost/gosocks5 v0.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc=
|
||||
|
||||
@@ -16,11 +16,13 @@ import (
|
||||
"github.com/go-gost/core/hosts"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
xhop "github.com/go-gost/x/hop"
|
||||
resolver_util "github.com/go-gost/x/internal/util/resolver"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
"github.com/go-gost/x/resolver/exchanger"
|
||||
@@ -152,11 +154,17 @@ func (h *dnsHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
ro.Duration = time.Since(start)
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Warnf("recorder: %v", err)
|
||||
}
|
||||
|
||||
@@ -119,10 +119,16 @@ func (h *httpHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Error("record: %v", err)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
xbypass "github.com/go-gost/x/bypass"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
@@ -19,14 +20,11 @@ import (
|
||||
"github.com/go-gost/x/internal/util/sniffing"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultBodySize = 1024 * 1024 // 1MB
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.HandlerRegistry().Register("red", NewHandler)
|
||||
registry.HandlerRegistry().Register("redir", NewHandler)
|
||||
@@ -90,12 +88,17 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
|
||||
@@ -9,11 +9,13 @@ import (
|
||||
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
xbypass "github.com/go-gost/x/bypass"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@@ -75,12 +77,20 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Error("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/go-gost/core/hop"
|
||||
"github.com/go-gost/core/limiter/traffic"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
"github.com/go-gost/relay"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
stats_util "github.com/go-gost/x/internal/util/stats"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@@ -112,12 +114,19 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
@@ -11,20 +11,18 @@ import (
|
||||
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/go-gost/x/internal/util/sniffing"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultBodySize = 1024 * 1024 // 1MB
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.HandlerRegistry().Register("sni", NewHandler)
|
||||
}
|
||||
@@ -90,10 +88,16 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
|
||||
@@ -112,14 +112,21 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/limiter/traffic"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
"github.com/go-gost/gosocks5"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
stats_util "github.com/go-gost/x/internal/util/stats"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@@ -110,14 +112,21 @@ func (h *socks5Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
+11
-2
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/go-gost/core/handler"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
"github.com/go-gost/gosocks5"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
"github.com/go-gost/x/internal/util/ss"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
"github.com/shadowsocks/go-shadowsocks2/core"
|
||||
@@ -94,14 +96,21 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
+11
-2
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/go-gost/core/handler"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
xbypass "github.com/go-gost/x/bypass"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
@@ -23,6 +24,7 @@ import (
|
||||
sshd_util "github.com/go-gost/x/internal/util/sshd"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
"golang.org/x/crypto/ssh"
|
||||
@@ -94,14 +96,21 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
+11
-2
@@ -14,12 +14,14 @@ import (
|
||||
"github.com/go-gost/core/hop"
|
||||
"github.com/go-gost/core/logger"
|
||||
md "github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
ctxvalue "github.com/go-gost/x/ctx"
|
||||
xio "github.com/go-gost/x/internal/io"
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
"github.com/go-gost/x/internal/util/sniffing"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
@@ -91,14 +93,21 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
|
||||
"local": conn.LocalAddr().String(),
|
||||
"sid": ctxvalue.SidFromContext(ctx),
|
||||
})
|
||||
|
||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(start)
|
||||
ro.Record(ctx, h.recorder.Recorder)
|
||||
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(start),
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"github.com/go-gost/core/bypass"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/observer/stats"
|
||||
"github.com/go-gost/core/recorder"
|
||||
dissector "github.com/go-gost/tls-dissector"
|
||||
xbypass "github.com/go-gost/x/bypass"
|
||||
@@ -26,6 +27,7 @@ import (
|
||||
xnet "github.com/go-gost/x/internal/net"
|
||||
xhttp "github.com/go-gost/x/internal/net/http"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||
xrecorder "github.com/go-gost/x/recorder"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
@@ -100,17 +102,22 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
opt(&o)
|
||||
}
|
||||
|
||||
ro := o.RecorderObject
|
||||
log := o.Log
|
||||
|
||||
pStats := stats.Stats{}
|
||||
conn = stats_wrapper.WrapConn(conn, &pStats)
|
||||
|
||||
br := bufio.NewReader(conn)
|
||||
req, err := http.ReadRequest(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if o.Log.IsLevelEnabled(logger.TraceLevel) {
|
||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(req, false)
|
||||
o.Log.Trace(string(dump))
|
||||
log.Trace(string(dump))
|
||||
}
|
||||
|
||||
ro := o.RecorderObject
|
||||
host := req.Host
|
||||
if host != "" {
|
||||
if _, _, err := net.SplitHostPort(host); err != nil {
|
||||
@@ -118,7 +125,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
}
|
||||
ro.Host = host
|
||||
|
||||
o.Log = o.Log.WithFields(map[string]any{
|
||||
log = log.WithFields(map[string]any{
|
||||
"host": host,
|
||||
})
|
||||
|
||||
@@ -168,7 +175,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
recorder: h.Recorder,
|
||||
recorderOptions: h.RecorderOptions,
|
||||
recorderObject: ro,
|
||||
log: o.Log,
|
||||
log: log,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
@@ -186,12 +193,14 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
|
||||
ro.Time = time.Time{}
|
||||
|
||||
shouldClose, err := h.httpRoundTrip(ctx, conn, cc, req, &o)
|
||||
shouldClose, err := h.httpRoundTrip(ctx, conn, cc, req, ro, &pStats, log)
|
||||
if err != nil || shouldClose {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
pStats.Reset()
|
||||
|
||||
req, err := http.ReadRequest(br)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed) {
|
||||
@@ -200,35 +209,38 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
return err
|
||||
}
|
||||
|
||||
if o.Log.IsLevelEnabled(logger.TraceLevel) {
|
||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(req, false)
|
||||
o.Log.Trace(string(dump))
|
||||
log.Trace(string(dump))
|
||||
}
|
||||
|
||||
if shouldClose, err := h.httpRoundTrip(ctx, conn, cc, req, &o); err != nil || shouldClose {
|
||||
if shouldClose, err := h.httpRoundTrip(ctx, conn, cc, req, ro, &pStats, log); err != nil || shouldClose {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *http.Request, o *HandleOptions) (close bool, err error) {
|
||||
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats *stats.Stats, log logger.Logger) (close bool, err error) {
|
||||
close = true
|
||||
|
||||
ro := &xrecorder.HandlerRecorderObject{}
|
||||
*ro = *o.RecorderObject
|
||||
ro2 := &xrecorder.HandlerRecorderObject{}
|
||||
*ro2 = *ro
|
||||
ro = ro2
|
||||
|
||||
ro.Time = time.Now()
|
||||
o.Log.Infof("%s <-> %s", ro.RemoteAddr, req.Host)
|
||||
log.Infof("%s <-> %s", ro.RemoteAddr, req.Host)
|
||||
defer func() {
|
||||
ro.Duration = time.Since(ro.Time)
|
||||
if err != nil {
|
||||
ro.Err = err.Error()
|
||||
}
|
||||
ro.InputBytes = pStats.Get(stats.KindInputBytes)
|
||||
ro.OutputBytes = pStats.Get(stats.KindOutputBytes)
|
||||
ro.Duration = time.Since(ro.Time)
|
||||
if err := ro.Record(ctx, h.Recorder); err != nil {
|
||||
o.Log.Errorf("record: %v", err)
|
||||
log.Errorf("record: %v", err)
|
||||
}
|
||||
|
||||
o.Log.WithFields(map[string]any{
|
||||
log.WithFields(map[string]any{
|
||||
"duration": time.Since(ro.Time),
|
||||
}).Infof("%s >-< %s", ro.RemoteAddr, req.Host)
|
||||
}()
|
||||
@@ -281,7 +293,7 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *
|
||||
xio.SetReadDeadline(cc, time.Now().Add(h.ReadTimeout))
|
||||
resp, err := http.ReadResponse(bufio.NewReader(cc), req)
|
||||
if err != nil {
|
||||
o.Log.Errorf("read response: %v", err)
|
||||
log.Errorf("read response: %v", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
@@ -291,9 +303,9 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *
|
||||
ro.HTTP.Response.Header = resp.Header
|
||||
ro.HTTP.Response.ContentLength = resp.ContentLength
|
||||
|
||||
if o.Log.IsLevelEnabled(logger.TraceLevel) {
|
||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpResponse(resp, false)
|
||||
o.Log.Trace(string(dump))
|
||||
log.Trace(string(dump))
|
||||
}
|
||||
|
||||
// HTTP/1.0
|
||||
@@ -316,7 +328,7 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *
|
||||
}
|
||||
|
||||
if err = resp.Write(rw); err != nil {
|
||||
o.Log.Errorf("write response: %v", err)
|
||||
log.Errorf("write response: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -467,6 +479,10 @@ func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHel
|
||||
nextProtos = []string{negotiatedProtocol}
|
||||
}
|
||||
|
||||
// cache the tls server handshake record.
|
||||
wb := &bytes.Buffer{}
|
||||
conn = xnet.NewReadWriteConn(conn, io.MultiWriter(wb, conn), conn)
|
||||
|
||||
serverConn := tls.Server(conn, &tls.Config{
|
||||
NextProtos: nextProtos,
|
||||
GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
@@ -504,7 +520,13 @@ func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHel
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
if err := serverConn.HandshakeContext(ctx); err != nil {
|
||||
err := serverConn.HandshakeContext(ctx)
|
||||
if record, _ := dissector.ReadRecord(wb); record != nil {
|
||||
wb.Reset()
|
||||
record.WriteTo(wb)
|
||||
ro.TLS.ServerHello = hex.EncodeToString(wb.Bytes())
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ type HandlerRecorderObject struct {
|
||||
TLS *TLSRecorderObject `json:"tls,omitempty"`
|
||||
DNS *DNSRecorderObject `json:"dns,omitempty"`
|
||||
Route string `json:"route,omitempty"`
|
||||
InputBytes uint64 `json:"inputBytes"`
|
||||
OutputBytes uint64 `json:"outputBytes"`
|
||||
Err string `json:"err,omitempty"`
|
||||
SID string `json:"sid"`
|
||||
Duration time.Duration `json:"duration"`
|
||||
|
||||
Reference in New Issue
Block a user