mirror of
https://github.com/go-gost/gost.git
synced 2026-10-08 12:05:46 +00:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccf2989bc0 | ||
|
|
d54a896a81 | ||
|
|
6b7dbf08fa | ||
|
|
dd56308b2e | ||
|
|
eb9dbb1807 | ||
|
|
02dc900686 | ||
|
|
bb912edecc | ||
|
|
ffb61cc19f | ||
|
|
a864cbcfe5 |
@@ -3,8 +3,8 @@ module github.com/go-gost/gost
|
||||
go 1.26.3
|
||||
|
||||
require (
|
||||
github.com/go-gost/core v0.5.1
|
||||
github.com/go-gost/x v0.13.0
|
||||
github.com/go-gost/core v0.5.3
|
||||
github.com/go-gost/x v0.13.9
|
||||
github.com/judwhite/go-svc v1.2.1
|
||||
github.com/moby/moby/client v0.4.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
@@ -20,12 +20,12 @@ require (
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.15.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
@@ -42,25 +42,26 @@ require (
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
||||
github.com/gin-contrib/cors v1.7.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.10.1 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.12.0 // indirect
|
||||
github.com/go-gost/go-shadowsocks2 v0.1.3 // indirect
|
||||
github.com/go-gost/gosocks4 v0.1.0 // indirect
|
||||
github.com/go-gost/gosocks5 v0.5.0 // indirect
|
||||
github.com/go-gost/plugin v0.4.0 // indirect
|
||||
github.com/go-gost/relay v0.6.1 // indirect
|
||||
github.com/go-gost/plugin v0.5.0 // indirect
|
||||
github.com/go-gost/relay v0.6.2 // indirect
|
||||
github.com/go-gost/tls-dissector v0.2.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
@@ -72,8 +73,8 @@ require (
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.18.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/compress v1.19.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/klauspost/reedsolomon v1.11.8 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
@@ -95,7 +96,7 @@ require (
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pion/dtls/v3 v3.1.1 // indirect
|
||||
github.com/pion/logging v0.2.4 // indirect
|
||||
github.com/pion/transport/v4 v4.0.1 // indirect
|
||||
@@ -133,7 +134,7 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/vulcand/predicate v1.2.0 // indirect
|
||||
@@ -145,28 +146,29 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zalando/go-keyring v0.2.4 // indirect
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.41.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.41.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.41.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.50.0 // indirect
|
||||
golang.org/x/arch v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.53.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect
|
||||
golang.org/x/mod v0.34.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
golang.org/x/mod v0.36.0 // indirect
|
||||
golang.org/x/net v0.56.0 // indirect
|
||||
golang.org/x/sync v0.21.0 // indirect
|
||||
golang.org/x/sys v0.46.0 // indirect
|
||||
golang.org/x/term v0.44.0 // indirect
|
||||
golang.org/x/text v0.38.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.43.0 // indirect
|
||||
golang.org/x/tools v0.45.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
google.golang.org/grpc v1.79.3 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -18,20 +18,20 @@ github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
@@ -75,30 +75,30 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw=
|
||||
github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E=
|
||||
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.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-gost/core v0.5.1 h1:HbIn3naEOC661Z4SwzaSYUzffWSRbU0P6gkxiHmuG0I=
|
||||
github.com/go-gost/core v0.5.1/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
|
||||
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
|
||||
github.com/go-gost/core v0.5.3 h1:RZ/x9S2o3lDe9r9zriEpMJgxYt+1CYjrBMRs4X3bLk8=
|
||||
github.com/go-gost/core v0.5.3/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
|
||||
github.com/go-gost/go-shadowsocks2 v0.1.3 h1:6CUZLp+mTWXnKP2aK8/Z9ZP+ERMX9gSbywmPu4kGX/A=
|
||||
github.com/go-gost/go-shadowsocks2 v0.1.3/go.mod h1:866zFNNI3He6Wef1M/IvAjTal74WhcfKfBgRpTlkKys=
|
||||
github.com/go-gost/gosocks4 v0.1.0 h1:eAzev6qw4fzkFQKC9uCHLVNnnPdHyqCggbnfNN80Pmk=
|
||||
github.com/go-gost/gosocks4 v0.1.0/go.mod h1:hzVjwijJuZR1pp3GqpTj+AKcSGrx68RlWTrQMFMYBP0=
|
||||
github.com/go-gost/gosocks5 v0.5.0 h1:YE37l1MJwde8diIQdynStqogMotG5enoTdborhA5yic=
|
||||
github.com/go-gost/gosocks5 v0.5.0/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4=
|
||||
github.com/go-gost/plugin v0.4.0 h1:M7MR5PL7QAFCrdWfcXVX+5iLNTVIZlhl8FfdV/K8dZY=
|
||||
github.com/go-gost/plugin v0.4.0/go.mod h1:oN23l+yGDCIP9G3KnDl/I/0zVGOobZUDCB2Z5yYYXts=
|
||||
github.com/go-gost/relay v0.6.1 h1:7SqnHFbY8x/DzvjpK03a5zcVH9+TbJAcnW/RT6s1ecc=
|
||||
github.com/go-gost/relay v0.6.1/go.mod h1:Dku0f5sfjOClrZFiDmQUrYYJ4uof7rnkCUBfsl0PSAI=
|
||||
github.com/go-gost/plugin v0.5.0 h1:zK3Ezcv+z6bz6aUhaFZcZiJc42w44ohybzrj5tnWzcM=
|
||||
github.com/go-gost/plugin v0.5.0/go.mod h1:oN23l+yGDCIP9G3KnDl/I/0zVGOobZUDCB2Z5yYYXts=
|
||||
github.com/go-gost/relay v0.6.2 h1:0Rgm1TOZvrilAKj6zn+UMvAGWtS0H08e2wBX03Y6g+I=
|
||||
github.com/go-gost/relay v0.6.2/go.mod h1:Dku0f5sfjOClrZFiDmQUrYYJ4uof7rnkCUBfsl0PSAI=
|
||||
github.com/go-gost/tls-dissector v0.2.0 h1:9tE6WOzzpurATTBWn60DU4R8gibpGNY8/qVcc1SicVg=
|
||||
github.com/go-gost/tls-dissector v0.2.0/go.mod h1:/9QfdewqmHdaE362Hv5nDaSWLx3pCmtD870d6GaquXs=
|
||||
github.com/go-gost/x v0.13.0 h1:iQOdO7o9GHIgNRtQTeoi/1WiTZw2C+/kC/y5JsN8WjE=
|
||||
github.com/go-gost/x v0.13.0/go.mod h1:P9zH+y/4+bNN2ZcoQZJ0tD59RXdvuRhioXDNfSCVsxU=
|
||||
github.com/go-gost/x v0.13.9 h1:/pK8rOiueV239i0ntesDnU15UeYrq8vL6iVeGPJTzJo=
|
||||
github.com/go-gost/x v0.13.9/go.mod h1:etkIOM5JjH9pnb3UOvLKexodznKcK3oRNGniPk0AGxk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
@@ -112,14 +112,16 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -165,14 +167,12 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/judwhite/go-svc v1.2.1 h1:a7fsJzYUa33sfDJRF2N/WXhA+LonCEEY8BJb1tuS5tA=
|
||||
github.com/judwhite/go-svc v1.2.1/go.mod h1:mo/P2JNX8C07ywpP9YtO2gnBgnUiFTHqtsZekJrUuTk=
|
||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
|
||||
github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY=
|
||||
github.com/klauspost/reedsolomon v1.11.8/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -226,8 +226,8 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pion/dtls/v3 v3.1.1 h1:wSLMam9Kf7DL1A74hnqRvEb9OT+aXPAsQ5VS+BdXOJ0=
|
||||
github.com/pion/dtls/v3 v3.1.1/go.mod h1:7FGvVYpHsUV6+aywaFpG7aE4Vz8nBOx74odPRFue6cI=
|
||||
github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=
|
||||
@@ -308,9 +308,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
@@ -329,8 +328,8 @@ github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9R
|
||||
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54 h1:8mhqcHPqTMhSPoslhGYihEgSfc77+7La1P6kiB6+9So=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
@@ -360,6 +359,8 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
|
||||
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
@@ -374,20 +375,19 @@ go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2W
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
|
||||
go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
|
||||
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
|
||||
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
|
||||
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU=
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||
@@ -396,8 +396,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
|
||||
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
|
||||
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -406,14 +406,14 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -425,16 +425,15 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
||||
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
|
||||
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -443,8 +442,8 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
|
||||
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
|
||||
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
@@ -472,8 +471,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
@@ -493,7 +492,5 @@ gvisor.dev/gvisor v0.0.0-20250523182742-eede7a881b20 h1:0DxLu8hxI1OGp1qVRPqNd+2k
|
||||
gvisor.dev/gvisor v0.0.0-20250523182742-eede7a881b20/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
|
||||
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
type MTLSSuite struct {
|
||||
suite.Suite
|
||||
ctx context.Context
|
||||
echoC testcontainers.Container
|
||||
echoIP string
|
||||
pluginC testcontainers.Container
|
||||
certDir string
|
||||
}
|
||||
|
||||
func (s *MTLSSuite) SetupSuite() {
|
||||
s.ctx = context.Background()
|
||||
|
||||
certDir, err := os.MkdirTemp("", "gost-mtls-certs-*")
|
||||
s.Require().NoError(err)
|
||||
s.certDir = certDir
|
||||
|
||||
s.generateCerts()
|
||||
|
||||
pluginC, err := runAuthPluginContainer(s.ctx, SharedNetworkName)
|
||||
s.Require().NoError(err)
|
||||
s.pluginC = pluginC
|
||||
|
||||
echoC, err := RunEchoContainer(s.ctx, SharedNetworkName)
|
||||
s.Require().NoError(err)
|
||||
s.echoC = echoC
|
||||
|
||||
echoIP, err := echoC.ContainerIP(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.echoIP = echoIP
|
||||
}
|
||||
|
||||
func (s *MTLSSuite) TearDownSuite() {
|
||||
if s.pluginC != nil {
|
||||
s.pluginC.Terminate(s.ctx)
|
||||
}
|
||||
if s.echoC != nil {
|
||||
s.echoC.Terminate(s.ctx)
|
||||
}
|
||||
os.RemoveAll(s.certDir)
|
||||
}
|
||||
|
||||
// generateCerts creates a self-signed CA, a server cert signed by the CA,
|
||||
// and a client cert signed by the CA, writing PEM files to s.certDir.
|
||||
func (s *MTLSSuite) generateCerts() {
|
||||
// CA
|
||||
caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
caTmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "Test CA"},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
caDER, err := x509.CreateCertificate(rand.Reader, caTmpl, caTmpl, &caKey.PublicKey, caKey)
|
||||
s.Require().NoError(err)
|
||||
s.writeCertPEM(s.certDir+"/ca.pem", "CERTIFICATE", caDER)
|
||||
s.writeKeyPEM(s.certDir+"/ca-key.pem", "EC PRIVATE KEY", caKey)
|
||||
|
||||
// Server
|
||||
serverKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
serverTmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(2),
|
||||
Subject: pkix.Name{CommonName: "localhost"},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
DNSNames: []string{"localhost"},
|
||||
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
|
||||
}
|
||||
serverDER, err := x509.CreateCertificate(rand.Reader, serverTmpl, caTmpl, &serverKey.PublicKey, caKey)
|
||||
s.Require().NoError(err)
|
||||
s.writeCertPEM(s.certDir+"/server.pem", "CERTIFICATE", serverDER)
|
||||
s.writeKeyPEM(s.certDir+"/server-key.pem", "EC PRIVATE KEY", serverKey)
|
||||
|
||||
// Client
|
||||
clientKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
clientTmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(3),
|
||||
Subject: pkix.Name{CommonName: "test-client"},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
EmailAddresses: []string{"test@example.com"},
|
||||
}
|
||||
clientDER, err := x509.CreateCertificate(rand.Reader, clientTmpl, caTmpl, &clientKey.PublicKey, caKey)
|
||||
s.Require().NoError(err)
|
||||
s.writeCertPEM(s.certDir+"/client.pem", "CERTIFICATE", clientDER)
|
||||
s.writeKeyPEM(s.certDir+"/client-key.pem", "EC PRIVATE KEY", clientKey)
|
||||
}
|
||||
|
||||
// TestMTLSProxy verifies HTTP forward proxy works over an mTLS listener
|
||||
// with a valid client certificate.
|
||||
func (s *MTLSSuite) TestMTLSProxy() {
|
||||
rendered, err := RenderConfig("testdata/mtls/server.yaml",
|
||||
ConfigData{ServerAddr: "auth-plugin"})
|
||||
s.Require().NoError(err)
|
||||
defer os.Remove(rendered)
|
||||
|
||||
gostC, err := RunGostContainerWithFiles(s.ctx, SharedNetworkName, rendered,
|
||||
[]testcontainers.ContainerFile{
|
||||
{HostFilePath: s.certDir + "/ca.pem", ContainerFilePath: "/certs/ca.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/server.pem", ContainerFilePath: "/certs/server.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/server-key.pem", ContainerFilePath: "/certs/server-key.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/client.pem", ContainerFilePath: "/certs/client.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/client-key.pem", ContainerFilePath: "/certs/client-key.pem", FileMode: 0644},
|
||||
},
|
||||
"8443/tcp")
|
||||
s.Require().NoError(err)
|
||||
defer gostC.Terminate(s.ctx)
|
||||
|
||||
// Verify proxy works with valid client cert
|
||||
cmd := []string{"curl", "-v", "-s", "--connect-timeout", "5",
|
||||
"--cacert", "/certs/ca.pem",
|
||||
"--cert", "/certs/client.pem",
|
||||
"--key", "/certs/client-key.pem",
|
||||
"-x", "https://127.0.0.1:8443",
|
||||
fmt.Sprintf("http://%s:5678", s.echoIP)}
|
||||
code, out, err := gostC.Exec(s.ctx, cmd)
|
||||
body, err2 := io.ReadAll(out)
|
||||
if err != nil || err2 != nil || code != 0 || !strings.Contains(string(body), "hello-gost") {
|
||||
DumpLogs(s.T(), s.ctx, "mtls gost logs", gostC)
|
||||
DumpLogs(s.T(), s.ctx, "mtls auth-plugin logs", s.pluginC)
|
||||
}
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(err2)
|
||||
s.Require().Equal(0, code)
|
||||
s.Require().Contains(string(body), "hello-gost")
|
||||
}
|
||||
|
||||
// TestMTLSWithoutClientCert verifies that an mTLS listener rejects
|
||||
// connections from clients that do not present a certificate.
|
||||
func (s *MTLSSuite) TestMTLSWithoutClientCert() {
|
||||
rendered, err := RenderConfig("testdata/mtls/server.yaml",
|
||||
ConfigData{ServerAddr: "auth-plugin"})
|
||||
s.Require().NoError(err)
|
||||
defer os.Remove(rendered)
|
||||
|
||||
gostC, err := RunGostContainerWithFiles(s.ctx, SharedNetworkName, rendered,
|
||||
[]testcontainers.ContainerFile{
|
||||
{HostFilePath: s.certDir + "/ca.pem", ContainerFilePath: "/certs/ca.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/server.pem", ContainerFilePath: "/certs/server.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/server-key.pem", ContainerFilePath: "/certs/server-key.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/client.pem", ContainerFilePath: "/certs/client.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/client-key.pem", ContainerFilePath: "/certs/client-key.pem", FileMode: 0644},
|
||||
},
|
||||
"8443/tcp")
|
||||
s.Require().NoError(err)
|
||||
defer gostC.Terminate(s.ctx)
|
||||
|
||||
// curl without client cert should fail TLS handshake
|
||||
cmd := []string{"curl", "-v", "-s", "--connect-timeout", "5",
|
||||
"--cacert", "/certs/ca.pem",
|
||||
"-x", "https://127.0.0.1:8443",
|
||||
fmt.Sprintf("http://%s:5678", s.echoIP)}
|
||||
code, _, err := gostC.Exec(s.ctx, cmd)
|
||||
if err == nil && code == 0 {
|
||||
DumpLogs(s.T(), s.ctx, "mtls gost logs", gostC)
|
||||
}
|
||||
// Expect failure (non-zero exit code from curl)
|
||||
s.Require().NotEqual(0, code, "curl without client cert should fail with non-zero exit code")
|
||||
}
|
||||
|
||||
// TestMTLSAuthPluginLogs verifies that the HTTP auth plugin receives
|
||||
// the mTLS client certificate identity (client_cn, client_san,
|
||||
// client_cert_fingerprint) when a request passes through the mTLS listener.
|
||||
func (s *MTLSSuite) TestMTLSAuthPluginLogs() {
|
||||
rendered, err := RenderConfig("testdata/mtls/server.yaml",
|
||||
ConfigData{ServerAddr: "auth-plugin"})
|
||||
s.Require().NoError(err)
|
||||
defer os.Remove(rendered)
|
||||
|
||||
gostC, err := RunGostContainerWithFiles(s.ctx, SharedNetworkName, rendered,
|
||||
[]testcontainers.ContainerFile{
|
||||
{HostFilePath: s.certDir + "/ca.pem", ContainerFilePath: "/certs/ca.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/server.pem", ContainerFilePath: "/certs/server.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/server-key.pem", ContainerFilePath: "/certs/server-key.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/client.pem", ContainerFilePath: "/certs/client.pem", FileMode: 0644},
|
||||
{HostFilePath: s.certDir + "/client-key.pem", ContainerFilePath: "/certs/client-key.pem", FileMode: 0644},
|
||||
},
|
||||
"8443/tcp")
|
||||
s.Require().NoError(err)
|
||||
defer gostC.Terminate(s.ctx)
|
||||
|
||||
// Send a request with valid client cert through the mTLS proxy.
|
||||
cmd := []string{"curl", "-v", "-s", "--connect-timeout", "5",
|
||||
"--cacert", "/certs/ca.pem",
|
||||
"--cert", "/certs/client.pem",
|
||||
"--key", "/certs/client-key.pem",
|
||||
"-x", "https://127.0.0.1:8443",
|
||||
fmt.Sprintf("http://%s:5678", s.echoIP)}
|
||||
code, out, err := gostC.Exec(s.ctx, cmd)
|
||||
body, _ := io.ReadAll(out)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(0, code)
|
||||
s.Require().Contains(string(body), "hello-gost")
|
||||
|
||||
// Read auth plugin logs and verify PeerCert fields are present.
|
||||
logs, err := s.pluginC.Logs(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
logData, _ := io.ReadAll(logs)
|
||||
logStr := string(logData)
|
||||
s.T().Logf("auth plugin logs:\n%s", logStr)
|
||||
|
||||
s.Require().Contains(logStr, "clientCn", "auth plugin should receive client_cn")
|
||||
s.Require().Contains(logStr, "test-client", "client_cn should be 'test-client'")
|
||||
s.Require().Contains(logStr, "clientSan", "auth plugin should receive client_san")
|
||||
s.Require().Contains(logStr, "clientCertFingerprint", "auth plugin should receive client_cert_fingerprint")
|
||||
}
|
||||
|
||||
func TestMTLSSuite(t *testing.T) {
|
||||
suite.Run(t, new(MTLSSuite))
|
||||
}
|
||||
|
||||
// --- helpers ---
|
||||
|
||||
func runAuthPluginContainer(ctx context.Context, networkName string) (testcontainers.Container, error) {
|
||||
req := testcontainers.ContainerRequest{
|
||||
FromDockerfile: testcontainers.FromDockerfile{
|
||||
Context: ".",
|
||||
Dockerfile: "Dockerfile",
|
||||
Repo: "gost-e2e",
|
||||
Tag: "latest",
|
||||
KeepImage: true,
|
||||
BuildOptionsModifier: func(opts *client.ImageBuildOptions) {
|
||||
opts.NetworkMode = "host"
|
||||
},
|
||||
},
|
||||
Networks: []string{networkName},
|
||||
NetworkAliases: map[string][]string{
|
||||
networkName: {"auth-plugin"},
|
||||
},
|
||||
Files: []testcontainers.ContainerFile{
|
||||
{HostFilePath: "scripts/auth_plugin.py", ContainerFilePath: "/scripts/auth_plugin.py", FileMode: 0644},
|
||||
},
|
||||
ExposedPorts: []string{"9000/tcp"},
|
||||
Cmd: []string{"python3", "/scripts/auth_plugin.py", "9000"},
|
||||
WaitingFor: wait.ForExposedPort(),
|
||||
}
|
||||
return testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
}
|
||||
|
||||
// writeCertPEM writes a DER-encoded certificate to a PEM file.
|
||||
func (s *MTLSSuite) writeCertPEM(path, blockType string, der []byte) {
|
||||
err := os.WriteFile(path, pem.EncodeToMemory(&pem.Block{Type: blockType, Bytes: der}), 0644)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
// writeKeyPEM marshals an ECDSA private key and writes it to a PEM file.
|
||||
func (s *MTLSSuite) writeKeyPEM(path, blockType string, key *ecdsa.PrivateKey) {
|
||||
b, err := x509.MarshalECPrivateKey(key)
|
||||
s.Require().NoError(err)
|
||||
err = os.WriteFile(path, pem.EncodeToMemory(&pem.Block{Type: blockType, Bytes: b}), 0600)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
)
|
||||
|
||||
type PHTSuite struct {
|
||||
suite.Suite
|
||||
ctx context.Context
|
||||
echoC testcontainers.Container
|
||||
echoIP string
|
||||
}
|
||||
|
||||
func (s *PHTSuite) SetupSuite() {
|
||||
s.ctx = context.Background()
|
||||
|
||||
s.T().Logf("start tcp echo container...")
|
||||
echoC, err := RunEchoContainer(s.ctx, SharedNetworkName)
|
||||
s.Require().NoError(err)
|
||||
s.echoC = echoC
|
||||
|
||||
echoIP, err := echoC.ContainerIP(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.echoIP = echoIP
|
||||
}
|
||||
|
||||
func (s *PHTSuite) TearDownSuite() {
|
||||
if s.echoC != nil {
|
||||
s.echoC.Terminate(s.ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPHTTunnel verifies a basic PHT tunnel: a client HTTP proxy chains
|
||||
// through a PHT dialer to reach a PHT server, which forwards the request
|
||||
// to the echo server.
|
||||
func (s *PHTSuite) TestPHTTunnel() {
|
||||
serverC, err := RunGostContainerWithOptions(s.ctx, SharedNetworkName,
|
||||
"testdata/pht/server.yaml",
|
||||
[]string{"pht-server"}, []string{"8443/tcp"})
|
||||
s.Require().NoError(err)
|
||||
defer serverC.Terminate(s.ctx)
|
||||
|
||||
rendered, err := RenderConfig("testdata/pht/client_connector.yaml",
|
||||
ConfigData{ServerAddr: "pht-server:8443"})
|
||||
s.Require().NoError(err)
|
||||
defer os.Remove(rendered)
|
||||
|
||||
clientC, err := RunGostContainerWithPorts(s.ctx, SharedNetworkName,
|
||||
rendered, "8080/tcp")
|
||||
s.Require().NoError(err)
|
||||
defer clientC.Terminate(s.ctx)
|
||||
|
||||
cmd := []string{"curl", "-v", "-s", "-x", "http://127.0.0.1:8080",
|
||||
fmt.Sprintf("http://%s:5678", s.echoIP)}
|
||||
code, out, err := clientC.Exec(s.ctx, cmd)
|
||||
s.Require().NoError(err)
|
||||
|
||||
body, err := io.ReadAll(out)
|
||||
s.Require().NoError(err)
|
||||
if code != 0 || !strings.Contains(string(body), "hello-gost") {
|
||||
DumpLogs(s.T(), s.ctx, "pht client logs", clientC)
|
||||
DumpLogs(s.T(), s.ctx, "pht server logs", serverC)
|
||||
}
|
||||
s.Require().Equal(0, code)
|
||||
s.Require().Contains(string(body), "hello-gost")
|
||||
}
|
||||
|
||||
// TestPHTSTunnel verifies PHT over TLS. The PHTs listener auto-generates a
|
||||
// self-signed cert; the PHTs dialer defaults to InsecureSkipVerify so the
|
||||
// handshake succeeds without explicit cert configuration.
|
||||
func (s *PHTSuite) TestPHTSTunnel() {
|
||||
serverC, err := RunGostContainerWithOptions(s.ctx, SharedNetworkName,
|
||||
"testdata/pht/server_phts.yaml",
|
||||
[]string{"phts-server"}, []string{"8443/tcp"})
|
||||
s.Require().NoError(err)
|
||||
defer serverC.Terminate(s.ctx)
|
||||
|
||||
rendered, err := RenderConfig("testdata/pht/client_connector_phts.yaml",
|
||||
ConfigData{ServerAddr: "phts-server:8443"})
|
||||
s.Require().NoError(err)
|
||||
defer os.Remove(rendered)
|
||||
|
||||
clientC, err := RunGostContainerWithPorts(s.ctx, SharedNetworkName,
|
||||
rendered, "8080/tcp")
|
||||
s.Require().NoError(err)
|
||||
defer clientC.Terminate(s.ctx)
|
||||
|
||||
cmd := []string{"curl", "-v", "-s", "-x", "http://127.0.0.1:8080",
|
||||
fmt.Sprintf("http://%s:5678", s.echoIP)}
|
||||
code, out, err := clientC.Exec(s.ctx, cmd)
|
||||
s.Require().NoError(err)
|
||||
|
||||
body, err := io.ReadAll(out)
|
||||
s.Require().NoError(err)
|
||||
if code != 0 || !strings.Contains(string(body), "hello-gost") {
|
||||
DumpLogs(s.T(), s.ctx, "phts client logs", clientC)
|
||||
DumpLogs(s.T(), s.ctx, "phts server logs", serverC)
|
||||
}
|
||||
s.Require().Equal(0, code)
|
||||
s.Require().Contains(string(body), "hello-gost")
|
||||
}
|
||||
|
||||
// TestPHTHeartbeat verifies that the PHT tunnel stays alive across idle
|
||||
// periods. Sends a request, waits >readTimeout (default 10s), and sends
|
||||
// another request to confirm the heartbeat kept the connection open.
|
||||
func (s *PHTSuite) TestPHTHeartbeat() {
|
||||
serverC, err := RunGostContainerWithOptions(s.ctx, SharedNetworkName,
|
||||
"testdata/pht/server.yaml",
|
||||
[]string{"pht-server"}, []string{"8443/tcp"})
|
||||
s.Require().NoError(err)
|
||||
defer serverC.Terminate(s.ctx)
|
||||
|
||||
rendered, err := RenderConfig("testdata/pht/client_connector.yaml",
|
||||
ConfigData{ServerAddr: "pht-server:8443"})
|
||||
s.Require().NoError(err)
|
||||
defer os.Remove(rendered)
|
||||
|
||||
clientC, err := RunGostContainerWithPorts(s.ctx, SharedNetworkName,
|
||||
rendered, "8080/tcp")
|
||||
s.Require().NoError(err)
|
||||
defer clientC.Terminate(s.ctx)
|
||||
|
||||
// First request: establish the tunnel.
|
||||
cmd := []string{"curl", "-v", "-s", "-x", "http://127.0.0.1:8080",
|
||||
fmt.Sprintf("http://%s:5678", s.echoIP)}
|
||||
code, out, err := clientC.Exec(s.ctx, cmd)
|
||||
s.Require().NoError(err)
|
||||
body, _ := io.ReadAll(out)
|
||||
s.Require().Equal(0, code)
|
||||
s.Require().Contains(string(body), "hello-gost")
|
||||
|
||||
// Wait longer than readTimeout to trigger heartbeat.
|
||||
// The PHT server's default read timeout is 10s. We wait 12s.
|
||||
cmd = []string{"sh", "-c",
|
||||
fmt.Sprintf("sleep 12 && curl -s -x http://127.0.0.1:8080 http://%s:5678", s.echoIP)}
|
||||
code, out, err = clientC.Exec(s.ctx, cmd)
|
||||
s.Require().NoError(err)
|
||||
body, _ = io.ReadAll(out)
|
||||
if code != 0 || !strings.Contains(string(body), "hello-gost") {
|
||||
DumpLogs(s.T(), s.ctx, "pht heartbeat client logs", clientC)
|
||||
DumpLogs(s.T(), s.ctx, "pht heartbeat server logs", serverC)
|
||||
}
|
||||
s.Require().Equal(0, code)
|
||||
s.Require().Contains(string(body), "hello-gost")
|
||||
}
|
||||
|
||||
func TestPHTSuite(t *testing.T) {
|
||||
suite.Run(t, new(PHTSuite))
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import http.server
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
class AuthHandler(http.server.BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
length = int(self.headers.get('Content-Length', 0))
|
||||
body = self.rfile.read(length)
|
||||
data = json.loads(body)
|
||||
print(f"AUTH_REQUEST: {json.dumps(data)}", flush=True)
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.end_headers()
|
||||
self.wfile.write(
|
||||
json.dumps(
|
||||
{"ok": True, "id": data.get("username", "anonymous")}
|
||||
).encode()
|
||||
)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
pass # silence default logging, we use our own AUTH_REQUEST line
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = int(sys.argv[1]) if len(sys.argv) > 1 else 9000
|
||||
http.server.HTTPServer(("0.0.0.0", port), AuthHandler).serve_forever()
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
- name: https-mtls
|
||||
addr: :8443
|
||||
handler:
|
||||
type: http
|
||||
auther: auther-0
|
||||
listener:
|
||||
type: tls
|
||||
tls:
|
||||
certFile: /certs/server.pem
|
||||
keyFile: /certs/server-key.pem
|
||||
caFile: /certs/ca.pem
|
||||
authers:
|
||||
- name: auther-0
|
||||
plugin:
|
||||
type: http
|
||||
addr: http://{{.ServerAddr}}:9000/auth
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
services:
|
||||
- name: pht-proxy
|
||||
addr: :8080
|
||||
handler:
|
||||
type: http
|
||||
chain: pht-chain
|
||||
listener:
|
||||
type: tcp
|
||||
|
||||
chains:
|
||||
- name: pht-chain
|
||||
hops:
|
||||
- name: pht-hop
|
||||
nodes:
|
||||
- name: pht-node
|
||||
addr: {{.ServerAddr}}
|
||||
connector:
|
||||
type: http
|
||||
dialer:
|
||||
type: pht
|
||||
@@ -0,0 +1,20 @@
|
||||
services:
|
||||
- name: phts-proxy
|
||||
addr: :8080
|
||||
handler:
|
||||
type: http
|
||||
chain: phts-chain
|
||||
listener:
|
||||
type: tcp
|
||||
|
||||
chains:
|
||||
- name: phts-chain
|
||||
hops:
|
||||
- name: phts-hop
|
||||
nodes:
|
||||
- name: phts-node
|
||||
addr: {{.ServerAddr}}
|
||||
connector:
|
||||
type: http
|
||||
dialer:
|
||||
type: phts
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
- name: pht-server
|
||||
addr: :8443
|
||||
handler:
|
||||
type: http
|
||||
listener:
|
||||
type: pht
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
- name: phts-server
|
||||
addr: :8443
|
||||
handler:
|
||||
type: http
|
||||
listener:
|
||||
type: phts
|
||||
Reference in New Issue
Block a user