added impersonate

Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
Ronni Skansing
2025-11-06 21:59:22 +01:00
parent 8a63af4977
commit acdff38814
84 changed files with 2438 additions and 2365 deletions
+32 -9
View File
@@ -11,28 +11,31 @@ require (
github.com/charmbracelet/bubbles v0.20.0
github.com/charmbracelet/bubbletea v1.3.4
github.com/charmbracelet/lipgloss v1.1.0
github.com/enetx/surf v1.0.141
github.com/exaring/ja4plus v0.0.2
github.com/fatih/color v1.15.0
github.com/gin-contrib/zap v1.1.4
github.com/gin-gonic/gin v1.10.0
github.com/go-errors/errors v1.5.1
github.com/google/uuid v1.3.0
github.com/google/uuid v1.3.1
github.com/oapi-codegen/nullable v1.1.0
github.com/pquerna/otp v1.4.0
github.com/stretchr/testify v1.9.0
github.com/wneessen/go-mail v0.7.2
github.com/yeqown/go-qrcode/v2 v2.2.4
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.41.0
golang.org/x/mod v0.27.0
golang.org/x/net v0.43.0
golang.org/x/time v0.3.0
golang.org/x/crypto v0.43.0
golang.org/x/mod v0.29.0
golang.org/x/net v0.46.0
golang.org/x/time v0.14.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/sqlite v1.6.0
gorm.io/gorm v1.30.1
)
require (
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
@@ -42,20 +45,33 @@ require (
github.com/charmbracelet/x/ansi v0.8.0 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/enetx/g v1.0.194 // indirect
github.com/enetx/http v1.0.19 // indirect
github.com/enetx/http2 v1.0.20 // indirect
github.com/enetx/iter v0.0.0-20250912135656-f1583323588f // indirect
github.com/enetx/uquic v0.0.0-20250922085439-3a2249d297c9 // indirect
github.com/enetx/utls v0.0.0-20251024090823-efbd194d7328 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/gaukas/clienthellod v0.4.2 // indirect
github.com/gaukas/godicttls v0.0.4 // indirect
github.com/gin-contrib/sse v0.1.0 // 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.22.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.1 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
@@ -73,20 +89,27 @@ require (
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/onsi/ginkgo/v2 v2.27.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.39.0 // indirect
github.com/refraction-networking/utls v1.5.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/wzshiming/socks5 v0.6.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yeqown/reedsolomon v1.0.0 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/mock v0.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.9.0 // indirect
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/tools v0.36.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.38.0 // indirect
google.golang.org/protobuf v1.36.7 // indirect
)
+111 -23
View File
@@ -1,7 +1,11 @@
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ=
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
@@ -34,6 +38,8 @@ github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0G
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
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=
@@ -41,6 +47,20 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/enetx/g v1.0.194 h1:lI/eicj+Qdcdt1xBUhaHv3M/ujN4v+WXYZDZYD1Dxuo=
github.com/enetx/g v1.0.194/go.mod h1:B3YULbT/hAx9+p2Q8GHrsTmjjM19iz1Rcdz3Y9+kSg4=
github.com/enetx/http v1.0.19 h1:4W97CyqKrPiR16wEm6UOesqNrt8l4RsVMjZHz6+I84E=
github.com/enetx/http v1.0.19/go.mod h1:1f4mytfF/SfjATEJnynpwGS6aa1ALjb8DtmYgFVblY0=
github.com/enetx/http2 v1.0.20 h1:181A9wyzQOxvj+LqIJ/oGGx6Vl0Ry1wTLOfX+zTnaS0=
github.com/enetx/http2 v1.0.20/go.mod h1:t54ex5HIS8V1+2j6cvEOv6umlrHsbUPFKQ54nYB58Nk=
github.com/enetx/iter v0.0.0-20250912135656-f1583323588f h1:GUW+4AWfECIEJ9oAxgEAVGCpaozMCjRiUYnuR6Q0bCQ=
github.com/enetx/iter v0.0.0-20250912135656-f1583323588f/go.mod h1:oMZN8hGLUpi7QBlMEUqailocNy0NFAO/7Lu+Nwh9HMM=
github.com/enetx/surf v1.0.141 h1:IEFRySO/2AjXtE3J0jPQmRWBqwTM3KTonrf9iCJ3Y+A=
github.com/enetx/surf v1.0.141/go.mod h1:taI3kiTjMQPh7phIK0VN3Nz+sOJf5Gkam1tJ5UDy1Q0=
github.com/enetx/uquic v0.0.0-20250922085439-3a2249d297c9 h1:jAuNOIRE/Lk2vpSRgbzSDup34J3Ay5cGRtwKoeZUDGg=
github.com/enetx/uquic v0.0.0-20250922085439-3a2249d297c9/go.mod h1:Yt1e0NLtImehclHlurlZ6Pji7PqHuNZpjAgjwuATsQw=
github.com/enetx/utls v0.0.0-20251024090823-efbd194d7328 h1:C1RHsl1CKSDiXumSHpJzk2jSIhvPn2x2MFGeg2ZnQIQ=
github.com/enetx/utls v0.0.0-20251024090823-efbd194d7328/go.mod h1:oeYX2NTbsqs75GBc4Vv56KlItghZAveDkb4dGUwRtkM=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/exaring/ja4plus v0.0.2 h1:lfLUicnWFuIlAVHPaq9t0PfSC++AOt1vt+PXg3+Hz5w=
@@ -49,14 +69,26 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
github.com/gaukas/clienthellod v0.4.2 h1:LPJ+LSeqt99pqeCV4C0cllk+pyWmERisP7w6qWr7eqE=
github.com/gaukas/clienthellod v0.4.2/go.mod h1:M57+dsu0ZScvmdnNxaxsDPM46WhSEdPYAOdNgfL7IKA=
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
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-contrib/zap v1.1.4 h1:xvxTybg6XBdNtcQLH3Tf0lFr4vhDkwzgLLrIGlNTqIo=
github.com/gin-contrib/zap v1.1.4/go.mod h1:7lgEpe91kLbeJkwBTPgtVBy4zMa6oSBEcvj662diqKQ=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -65,26 +97,42 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
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=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
@@ -93,6 +141,8 @@ github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@@ -104,6 +154,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
@@ -121,15 +173,27 @@ github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs=
github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY=
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.39.0 h1:AgP40iThFMY0bj8jGxROhw3S0FMGa8ryqsmi9tBH3So=
github.com/quic-go/quic-go v0.39.0/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
github.com/refraction-networking/utls v1.5.4 h1:9k6EO2b8TaOGsQ7Pl7p9w6PUhx18/ZCeT0WNTZ7Uw4o=
github.com/refraction-networking/utls v1.5.4/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -143,14 +207,26 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
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/wneessen/go-mail v0.7.2 h1:xxPnhZ6IZLSgxShebmZ6DPKh1b6OJcoHfzy7UjOkzS8=
github.com/wneessen/go-mail v0.7.2/go.mod h1:+TkW6QP3EVkgTEqHtVmnAE/1MRhmzb8Y9/W3pweuS+k=
github.com/wzshiming/socks5 v0.6.0 h1:p5RFNs21Byv+Tnc7chYRFtz0SzK8TcqKV7xFkXSeZvw=
github.com/wzshiming/socks5 v0.6.0/go.mod h1:BvCAqlzocQN5xwLjBZDBbvWlrx8sCYSSbHEOf2wZgT0=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yeqown/go-qrcode/v2 v2.2.4 h1:cXdYlrhzHzVAnJHiwr/T6lAUmS9MtEStjEZBjArrvnc=
github.com/yeqown/go-qrcode/v2 v2.2.4/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
@@ -164,33 +240,42 @@ 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.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
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=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
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=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -200,8 +285,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -210,20 +295,23 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+85 -30
View File
@@ -5,7 +5,6 @@ import (
"compress/flate"
"compress/gzip"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io"
@@ -204,8 +203,8 @@ func (m *ProxyHandler) HandleHTTPRequest(w http.ResponseWriter, req *http.Reques
}
}
// create http client
client, err := m.createHTTPClient(req, reqCtx.ProxyConfig)
// create http client with optional browser impersonation
client, err := m.createHTTPClientWithImpersonation(req, reqCtx, reqCtx.ProxyConfig)
if err != nil {
return errors.Errorf("failed to create proxy HTTP client: %w", err)
}
@@ -247,25 +246,10 @@ func (m *ProxyHandler) extractTargetDomain(domain *database.Domain) string {
return targetDomain
}
// deprecated: use createHTTPClientWithImpersonation instead
// kept for backward compatibility if needed
func (m *ProxyHandler) createHTTPClient(req *http.Request, proxyConfig *service.ProxyServiceConfigYAML) (*http.Client, error) {
client := &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{},
}
if proxyConfig.Proxy != "" {
proxyURL, err := url.Parse("http://" + proxyConfig.Proxy)
if err != nil {
return nil, err
}
client.Transport = &http.Transport{
Proxy: http.ProxyURL(proxyURL),
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
}
return client, nil
return m.createStandardHTTPClient(proxyConfig)
}
// initializeRequestContext creates and populates the request context with all necessary data
@@ -778,10 +762,11 @@ func (m *ProxyHandler) captureResponseDataWithContext(resp *http.Response, reqCt
contentType := resp.Header.Get("Content-Type")
if m.shouldProcessContent(contentType) {
body, _, err := m.readAndDecompressBody(resp)
body, wasCompressed, err := m.readAndDecompressBody(resp)
if err == nil {
m.onResponseBody(resp, body, reqCtx.Session)
resp.Body = io.NopCloser(bytes.NewReader(body))
// properly restore the body with compression handling
m.updateResponseBody(resp, body, wasCompressed)
}
}
}
@@ -1211,6 +1196,14 @@ func (m *ProxyHandler) createNewSession(
// create session configuration
sessionConfig := m.buildSessionConfig(reqCtx.TargetDomain, reqCtx.Domain.Name, reqCtx.ProxyConfig)
// capture client user-agent for analytics and logging
userAgent := req.Header.Get("User-Agent")
m.logger.Debugw("creating session with user-agent",
"userAgent", userAgent,
"campaignRecipientID", campaignRecipientID.String(),
)
// create session
session := &service.ProxySession{
ID: uuid.New().String(),
@@ -1220,8 +1213,8 @@ func (m *ProxyHandler) createNewSession(
Campaign: campaign,
Domain: reqCtx.Domain,
TargetDomain: reqCtx.TargetDomain,
CreatedAt: time.Now(),
UserAgent: userAgent,
CreatedAt: time.Now(),
}
// initialize session data
@@ -2146,28 +2139,58 @@ func (m *ProxyHandler) readAndDecompressBody(resp *http.Response) ([]byte, bool,
return nil, false, err
}
m.logger.Debugw("read response body",
"bodySize", len(body),
"contentLength", resp.ContentLength,
"contentEncoding", resp.Header.Get("Content-Encoding"),
)
encoding := resp.Header.Get("Content-Encoding")
switch strings.ToLower(encoding) {
case "gzip":
gzipReader, err := gzip.NewReader(bytes.NewBuffer(body))
if err != nil {
return body, false, err
// body is already decompressed (e.g., by surf's decodeBodyMW middleware)
// remove the Content-Encoding header and send uncompressed to client
m.logger.Debugw("gzip decompression failed, body already decompressed - removing content-encoding header",
"error", err,
"content-encoding", encoding,
"bodySize", len(body),
)
resp.Header.Del("Content-Encoding")
return body, false, nil
}
defer gzipReader.Close()
decompressed, err := io.ReadAll(gzipReader)
if err != nil {
return body, false, err
// if reading fails, body might be already decompressed
m.logger.Debugw("gzip read failed, body already decompressed - removing content-encoding header",
"error", err,
"bodySize", len(body),
)
resp.Header.Del("Content-Encoding")
return body, false, nil
}
m.logger.Debugw("successfully decompressed gzip body",
"compressedSize", len(body),
"decompressedSize", len(decompressed),
)
return decompressed, true, nil
case "deflate":
deflateReader := flate.NewReader(bytes.NewBuffer(body))
defer deflateReader.Close()
decompressed, err := io.ReadAll(deflateReader)
if err != nil {
return body, false, err
// body is already decompressed - remove header and send uncompressed
m.logger.Debugw("deflate decompression failed, body already decompressed - removing content-encoding header",
"error", err,
)
resp.Header.Del("Content-Encoding")
return body, false, nil
}
return decompressed, true, nil
case "br":
// brotli not supported yet, return as-is
return body, false, nil
default:
return body, false, nil
@@ -2175,8 +2198,23 @@ func (m *ProxyHandler) readAndDecompressBody(resp *http.Response) ([]byte, bool,
}
func (m *ProxyHandler) updateResponseBody(resp *http.Response, body []byte, wasCompressed bool) {
m.logger.Debugw("updateResponseBody called",
"bodySize", len(body),
"wasCompressed", wasCompressed,
"contentEncoding", resp.Header.Get("Content-Encoding"),
)
if wasCompressed {
encoding := resp.Header.Get("Content-Encoding")
if encoding == "" {
// encoding was removed because body was already decompressed
// don't try to recompress, just set uncompressed body
m.logger.Debugw("no content-encoding header, sending uncompressed body")
resp.Body = io.NopCloser(bytes.NewReader(body))
resp.ContentLength = int64(len(body))
resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(body)))
return
}
switch strings.ToLower(encoding) {
case "gzip":
var compressedBuffer bytes.Buffer
@@ -2188,6 +2226,10 @@ func (m *ProxyHandler) updateResponseBody(resp *http.Response, body []byte, wasC
m.logger.Errorw("failed to close gzip writer", "error", err)
}
body = compressedBuffer.Bytes()
m.logger.Debugw("recompressed body with gzip",
"decompressedSize", len(body),
"compressedSize", compressedBuffer.Len(),
)
case "deflate":
var compressedBuffer bytes.Buffer
deflateWriter, err := flate.NewWriter(&compressedBuffer, flate.DefaultCompression)
@@ -2208,6 +2250,18 @@ func (m *ProxyHandler) updateResponseBody(resp *http.Response, body []byte, wasC
resp.Body = io.NopCloser(bytes.NewReader(body))
resp.ContentLength = int64(len(body))
resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(body)))
// ensure Content-Encoding is removed if we're sending uncompressed
if !wasCompressed && resp.Header.Get("Content-Encoding") != "" {
m.logger.Debugw("removing content-encoding header for uncompressed body")
resp.Header.Del("Content-Encoding")
}
m.logger.Debugw("updated response body",
"finalBodySize", len(body),
"contentLength", resp.ContentLength,
"contentEncoding", resp.Header.Get("Content-Encoding"),
)
}
func (m *ProxyHandler) shouldProcessContent(contentType string) bool {
@@ -3631,8 +3685,9 @@ func (m *ProxyHandler) registerEvasionPageVisitEventDirect(req *http.Request, re
}
}
// checkIPFilter checks if the IP and JA4 are allowed for proxy requests
// returns (blocked, response) where blocked=true means the IP should be blocked
// checkIPFilter checks if the client IP and JA4 fingerprint are allowed for proxy requests
// JA4 fingerprint is extracted from request context (set by middleware, not from session)
// returns (blocked, response) where blocked=true means the request should be blocked
func (m *ProxyHandler) checkIPFilter(req *http.Request, reqCtx *RequestContext) (bool, *http.Response) {
// use cached campaign info
if reqCtx.Campaign == nil || reqCtx.CampaignID == nil {
+202
View File
@@ -0,0 +1,202 @@
package proxy
import (
"crypto/tls"
"net/http"
"net/url"
"strings"
"time"
"github.com/enetx/surf"
"github.com/phishingclub/phishingclub/service"
)
// browserProfile represents detected browser and platform information
type browserProfile struct {
isChrome bool
isFirefox bool
isSafari bool
isEdge bool
// platform
isWindows bool
isMacOS bool
isLinux bool
isAndroid bool
isIOS bool
}
// detectBrowserFromUserAgent analyzes user-agent to determine browser type and platform
func (m *ProxyHandler) detectBrowserFromUserAgent(userAgent string) *browserProfile {
profile := &browserProfile{}
// normalize user-agent for comparison
ua := strings.ToLower(userAgent)
// detect browser from user-agent
// note: order matters - edge and chrome both contain "chrome" in ua
if strings.Contains(ua, "edg/") || strings.Contains(ua, "edge/") {
profile.isEdge = true
} else if strings.Contains(ua, "chrome/") || strings.Contains(ua, "crios/") {
profile.isChrome = true
} else if strings.Contains(ua, "firefox/") || strings.Contains(ua, "fxios/") {
profile.isFirefox = true
} else if strings.Contains(ua, "safari/") && !strings.Contains(ua, "chrome") && strings.Contains(ua, "version/") {
profile.isSafari = true
}
// detect operating system from user-agent
// note: order matters - android contains "linux", so check mobile platforms first
switch {
case strings.Contains(ua, "android"):
profile.isAndroid = true
case strings.Contains(ua, "iphone") || strings.Contains(ua, "ipad"):
profile.isIOS = true
case strings.Contains(ua, "windows nt"):
profile.isWindows = true
case strings.Contains(ua, "macintosh") || strings.Contains(ua, "mac os x"):
profile.isMacOS = true
case strings.Contains(ua, "x11") || strings.Contains(ua, "linux"):
profile.isLinux = true
}
return profile
}
// createSurfClient creates a surf http client with browser impersonation
func (m *ProxyHandler) createSurfClient(userAgent string, proxyConfig *service.ProxyServiceConfigYAML, acceptLanguage string, retainUA bool) (*http.Client, error) {
// detect browser profile from user-agent
profile := m.detectBrowserFromUserAgent(userAgent)
// build surf client with impersonation
builder := surf.NewClient().Builder()
// apply platform (OS) impersonation first
impersonate := builder.Impersonate()
switch {
case profile.isWindows:
impersonate = impersonate.Windows()
m.logger.Debugw("applying windows platform impersonation", "userAgent", userAgent)
case profile.isMacOS:
impersonate = impersonate.MacOS()
m.logger.Debugw("applying macos platform impersonation", "userAgent", userAgent)
case profile.isLinux:
impersonate = impersonate.Linux()
m.logger.Debugw("applying linux platform impersonation", "userAgent", userAgent)
case profile.isAndroid:
impersonate = impersonate.Android()
m.logger.Debugw("applying android platform impersonation", "userAgent", userAgent)
case profile.isIOS:
impersonate = impersonate.IOS()
m.logger.Debugw("applying ios platform impersonation", "userAgent", userAgent)
default:
// default to windows as most common platform
impersonate = impersonate.Windows()
m.logger.Debugw("applying default windows platform impersonation", "userAgent", userAgent)
}
// apply browser impersonation based on detected profile
switch {
case profile.isChrome || profile.isEdge:
// chrome impersonation (edge uses chromium engine)
builder = impersonate.Chrome()
m.logger.Debugw("applying chrome browser impersonation")
case profile.isFirefox:
// firefox impersonation
builder = impersonate.FireFox()
m.logger.Debugw("applying firefox browser impersonation")
case profile.isSafari:
// safari uses webkit - default to chrome for now as surf doesn't have safari profile
builder = impersonate.Chrome()
m.logger.Debugw("applying chrome browser impersonation for safari")
default:
// default to chrome as most common browser
builder = impersonate.Chrome()
m.logger.Debugw("applying default chrome browser impersonation")
}
// configure timeout
builder = builder.Timeout(30 * time.Second)
// note: surf automatically decompresses response bodies via decodeBodyMW middleware
// even when using .Std(), but keeps the Content-Encoding header
// our proxy code will detect this and remove the header before sending to client
// retain original user-agent if configured
if retainUA && userAgent != "" {
builder = builder.UserAgent(userAgent)
}
// preserve client's accept-language header if provided
if acceptLanguage != "" {
builder = builder.AddHeaders("Accept-Language", acceptLanguage)
}
// configure proxy if specified
if proxyConfig.Proxy != "" {
builder = builder.Proxy("http://" + proxyConfig.Proxy)
m.logger.Debugw("configured surf client with proxy",
"proxy", proxyConfig.Proxy,
)
}
// build the client
client := builder.Build()
// convert surf client to standard http.Client for compatibility
return client.Std(), nil
}
// createHTTPClientWithImpersonation creates http client with optional surf impersonation
func (m *ProxyHandler) createHTTPClientWithImpersonation(req *http.Request, reqCtx *RequestContext, proxyConfig *service.ProxyServiceConfigYAML) (*http.Client, error) {
// check if impersonation is enabled in config
impersonateEnabled := false
retainUA := false
if proxyConfig.Global != nil && proxyConfig.Global.Impersonate != nil {
impersonateEnabled = proxyConfig.Global.Impersonate.Enabled
retainUA = proxyConfig.Global.Impersonate.RetainUA
}
if !impersonateEnabled {
return m.createStandardHTTPClient(proxyConfig)
}
// extract user-agent and accept-language from current request headers
userAgent := req.Header.Get("User-Agent")
acceptLanguage := req.Header.Get("Accept-Language")
m.logger.Debugw("impersonation enabled, using surf client",
"userAgent", userAgent,
"retainUA", retainUA,
)
client, err := m.createSurfClient(userAgent, proxyConfig, acceptLanguage, retainUA)
if err != nil {
m.logger.Warnw("failed to create surf client, falling back to standard client",
"error", err,
)
return m.createStandardHTTPClient(proxyConfig)
}
return client, nil
}
// createStandardHTTPClient creates a standard http client without impersonation
func (m *ProxyHandler) createStandardHTTPClient(proxyConfig *service.ProxyServiceConfigYAML) (*http.Client, error) {
client := &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{},
}
if proxyConfig.Proxy != "" {
proxyURL, err := url.Parse("http://" + proxyConfig.Proxy)
if err != nil {
return nil, err
}
client.Transport = &http.Transport{
Proxy: http.ProxyURL(proxyURL),
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
}
return client, nil
}
+33 -6
View File
@@ -53,12 +53,13 @@ type ProxyServiceDomainConfig struct {
// ProxyServiceRules represents capture and replace rules
// ProxyServiceRules represents global rules that apply to all hosts
type ProxyServiceRules struct {
TLS *ProxyServiceTLSConfig `yaml:"tls,omitempty"`
Access *ProxyServiceAccessControl `yaml:"access,omitempty"`
Capture []ProxyServiceCaptureRule `yaml:"capture,omitempty"`
Rewrite []ProxyServiceReplaceRule `yaml:"rewrite,omitempty"`
Response []ProxyServiceResponseRule `yaml:"response,omitempty"`
RewriteURLs []ProxyServiceURLRewriteRule `yaml:"rewrite_urls,omitempty"`
TLS *ProxyServiceTLSConfig `yaml:"tls,omitempty"`
Access *ProxyServiceAccessControl `yaml:"access,omitempty"`
Impersonate *ProxyServiceImpersonateConfig `yaml:"impersonate,omitempty"`
Capture []ProxyServiceCaptureRule `yaml:"capture,omitempty"`
Rewrite []ProxyServiceReplaceRule `yaml:"rewrite,omitempty"`
Response []ProxyServiceResponseRule `yaml:"response,omitempty"`
RewriteURLs []ProxyServiceURLRewriteRule `yaml:"rewrite_urls,omitempty"`
}
// ProxyServiceTLSConfig represents TLS configuration for proxy domains
@@ -79,6 +80,12 @@ type ProxyServiceTLSConfig struct {
Mode string `yaml:"mode"` // "managed" | "self-signed"
}
// ProxyServiceImpersonateConfig represents client impersonation configuration
type ProxyServiceImpersonateConfig struct {
Enabled bool `yaml:"enabled"` // enable surf browser impersonation based on ja4 fingerprint
RetainUA bool `yaml:"retain_ua"` // retain client's original user-agent instead of using surf's impersonated one
}
// ProxyServiceAccessControl represents access control configuration
type ProxyServiceAccessControl struct {
Mode string `yaml:"mode"` // "public" | "private"
@@ -329,6 +336,26 @@ type ProxyServiceResponseRule struct {
// path: "/login"
// find: "password=(.*?)&"
// from: "request_body"
//
// Example proxy configuration with client impersonation:
//
// version: "0.0"
// proxy: "proxy.example.com:8080" # optional upstream proxy
// global:
// tls:
// mode: "managed"
// impersonate:
// enabled: true # enable surf browser impersonation (default: false)
// retain_ua: false # retain client's original user-agent (default: false)
// example.com:
// to: "target.com"
//
// When impersonate.enabled is true, the proxy will:
// - capture the client's ja4 tls fingerprint
// - detect the client's browser (chrome, firefox, safari, edge) and platform (windows, macos, linux, android, ios)
// - use surf library to replicate the exact tls fingerprint, http/2 settings, and header ordering
// - this makes proxied requests appear identical to the original client's browser
// When impersonate.retain_ua is true, the original client user-agent is preserved instead of using surf's impersonated one
type ProxyServiceConfigYAML struct {
Version string `yaml:"version,omitempty"`
Proxy string `yaml:"proxy,omitempty"`
+3
View File
@@ -27,6 +27,9 @@ type ProxySession struct {
NextPageType atomic.Value // string - accessed concurrently by multiple requests
IsComplete atomic.Bool // accessed concurrently when checking capture completion
CookieBundleSubmitted atomic.Bool // accessed concurrently to prevent duplicate submissions
// client user-agent stored for analytics and logging
UserAgent string
}
// ProxySessionManager manages proxy session lifecycle and storage
-9
View File
@@ -1,9 +0,0 @@
language: go
go:
- 1.4.3
- 1.5.3
- tip
script:
- go test -v ./...
+16
View File
@@ -2,6 +2,22 @@
We definitely welcome patches and contribution to this project!
### Tips
Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org).
Always try to include a test case! If it is not possible or not necessary,
please explain why in the pull request description.
### Releasing
Commits that would precipitate a SemVer change, as desrcibed in the Conventional
Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action)
to create a release candidate pull request. Once submitted, `release-please`
will create a release.
For tips on how to work with `release-please`, see its documentation.
### Legal requirements
In order to protect both you and ourselves, you will need to sign the
+6 -4
View File
@@ -1,6 +1,6 @@
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
# uuid
The uuid package generates and inspects UUIDs based on
[RFC 4122](http://tools.ietf.org/html/rfc4122)
[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)
and DCE 1.1: Authentication and Security Services.
This package is based on the github.com/pborman/uuid package (previously named
@@ -9,10 +9,12 @@ a UUID is a 16 byte array rather than a byte slice. One loss due to this
change is the ability to represent an invalid UUID (vs a NIL UUID).
###### Install
`go get github.com/google/uuid`
```sh
go get github.com/google/uuid
```
###### Documentation
[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)
[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid)
Full `go doc` style documentation for the package can be viewed online without
installing this package by using the GoDoc site here:
+1 -1
View File
@@ -7,6 +7,6 @@
package uuid
// getHardwareInterface returns nil values for the JS version of the code.
// This remvoves the "net" dependency, because it is not used in the browser.
// This removes the "net" dependency, because it is not used in the browser.
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
func getHardwareInterface(name string) (string, []byte) { return "", nil }
+6 -4
View File
@@ -69,7 +69,7 @@ func Parse(s string) (UUID, error) {
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
case 36 + 9:
if strings.ToLower(s[:9]) != "urn:uuid:" {
if !strings.EqualFold(s[:9], "urn:uuid:") {
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
}
s = s[9:]
@@ -101,7 +101,8 @@ func Parse(s string) (UUID, error) {
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
24, 26, 28, 30, 32, 34,
} {
v, ok := xtob(s[x], s[x+1])
if !ok {
return uuid, errors.New("invalid UUID format")
@@ -117,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) {
switch len(b) {
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) {
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
}
b = b[9:]
@@ -145,7 +146,8 @@ func ParseBytes(b []byte) (UUID, error) {
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
24, 26, 28, 30, 32, 34,
} {
v, ok := xtob(b[x], b[x+1])
if !ok {
return uuid, errors.New("invalid UUID format")
+21 -14
View File
@@ -6,7 +6,7 @@
// cancellation signals, and other request-scoped values across API boundaries
// and between processes.
// As of Go 1.7 this package is available in the standard library under the
// name [context], and migrating to it can be done automatically with [go fix].
// name [context].
//
// Incoming requests to a server should create a [Context], and outgoing
// calls to servers should accept a Context. The chain of function
@@ -38,8 +38,6 @@
//
// See https://go.dev/blog/context for example code for a server that uses
// Contexts.
//
// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs
package context
import (
@@ -51,36 +49,37 @@ import (
// API boundaries.
//
// Context's methods may be called by multiple goroutines simultaneously.
//
//go:fix inline
type Context = context.Context
// Canceled is the error returned by [Context.Err] when the context is canceled
// for some reason other than its deadline passing.
//
//go:fix inline
var Canceled = context.Canceled
// DeadlineExceeded is the error returned by [Context.Err] when the context is canceled
// due to its deadline passing.
//
//go:fix inline
var DeadlineExceeded = context.DeadlineExceeded
// Background returns a non-nil, empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
// requests.
func Background() Context {
return background
}
//
//go:fix inline
func Background() Context { return context.Background() }
// TODO returns a non-nil, empty Context. Code should use context.TODO when
// it's unclear which Context to use or it is not yet available (because the
// surrounding function has not yet been extended to accept a Context
// parameter).
func TODO() Context {
return todo
}
var (
background = context.Background()
todo = context.TODO()
)
//
//go:fix inline
func TODO() Context { return context.TODO() }
// A CancelFunc tells an operation to abandon its work.
// A CancelFunc does not wait for the work to stop.
@@ -95,6 +94,8 @@ type CancelFunc = context.CancelFunc
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this [Context] complete.
//
//go:fix inline
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
return context.WithCancel(parent)
}
@@ -108,6 +109,8 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this [Context] complete.
//
//go:fix inline
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
return context.WithDeadline(parent, d)
}
@@ -122,6 +125,8 @@ func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
// defer cancel() // releases resources if slowOperation completes before timeout elapses
// return slowOperation(ctx)
// }
//
//go:fix inline
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
return context.WithTimeout(parent, timeout)
}
@@ -139,6 +144,8 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
// interface{}, context keys often have concrete type
// struct{}. Alternatively, exported context key variables' static
// type should be a pointer or interface.
//
//go:fix inline
func WithValue(parent Context, key, val interface{}) Context {
return context.WithValue(parent, key, val)
}
+1 -1
View File
@@ -299,7 +299,7 @@ func escape(w writer, s string) error {
case '\r':
esc = "&#13;"
default:
panic("unrecognized escape character")
panic("html: unrecognized escape character")
}
s = s[i+1:]
if _, err := w.WriteString(esc); err != nil {
+41 -16
View File
@@ -136,7 +136,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
return -1
}
default:
panic("unreachable")
panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s))
}
}
switch s {
@@ -179,7 +179,7 @@ func (p *parser) clearStackToContext(s scope) {
return
}
default:
panic("unreachable")
panic(fmt.Sprintf("html: internal error: clearStackToContext unknown scope: %d", s))
}
}
}
@@ -231,7 +231,14 @@ func (p *parser) addChild(n *Node) {
}
if n.Type == ElementNode {
p.oe = append(p.oe, n)
p.insertOpenElement(n)
}
}
func (p *parser) insertOpenElement(n *Node) {
p.oe = append(p.oe, n)
if len(p.oe) > 512 {
panic("html: open stack of elements exceeds 512 nodes")
}
}
@@ -810,7 +817,7 @@ func afterHeadIM(p *parser) bool {
p.im = inFramesetIM
return true
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
p.oe = append(p.oe, p.head)
p.insertOpenElement(p.head)
defer p.oe.remove(p.head)
return inHeadIM(p)
case a.Head:
@@ -1678,7 +1685,7 @@ func inTableBodyIM(p *parser) bool {
return inTableIM(p)
}
// Section 12.2.6.4.14.
// Section 13.2.6.4.14.
func inRowIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@@ -1690,7 +1697,9 @@ func inRowIM(p *parser) bool {
p.im = inCellIM
return true
case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr:
if p.popUntil(tableScope, a.Tr) {
if p.elementInScope(tableScope, a.Tr) {
p.clearStackToContext(tableRowScope)
p.oe.pop()
p.im = inTableBodyIM
return false
}
@@ -1700,22 +1709,28 @@ func inRowIM(p *parser) bool {
case EndTagToken:
switch p.tok.DataAtom {
case a.Tr:
if p.popUntil(tableScope, a.Tr) {
if p.elementInScope(tableScope, a.Tr) {
p.clearStackToContext(tableRowScope)
p.oe.pop()
p.im = inTableBodyIM
return true
}
// Ignore the token.
return true
case a.Table:
if p.popUntil(tableScope, a.Tr) {
if p.elementInScope(tableScope, a.Tr) {
p.clearStackToContext(tableRowScope)
p.oe.pop()
p.im = inTableBodyIM
return false
}
// Ignore the token.
return true
case a.Tbody, a.Tfoot, a.Thead:
if p.elementInScope(tableScope, p.tok.DataAtom) {
p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String())
if p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) {
p.clearStackToContext(tableRowScope)
p.oe.pop()
p.im = inTableBodyIM
return false
}
// Ignore the token.
@@ -2222,16 +2237,20 @@ func parseForeignContent(p *parser) bool {
p.acknowledgeSelfClosingTag()
}
case EndTagToken:
if strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) {
p.oe = p.oe[:len(p.oe)-1]
return true
}
for i := len(p.oe) - 1; i >= 0; i-- {
if p.oe[i].Namespace == "" {
return p.im(p)
}
if strings.EqualFold(p.oe[i].Data, p.tok.Data) {
p.oe = p.oe[:i]
return true
}
if i > 0 && p.oe[i-1].Namespace == "" {
break
}
}
return true
return p.im(p)
default:
// Ignore the token.
}
@@ -2312,9 +2331,13 @@ func (p *parser) parseCurrentToken() {
}
}
func (p *parser) parse() error {
func (p *parser) parse() (err error) {
defer func() {
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s", panicErr)
}
}()
// Iterate until EOF. Any other error will cause an early return.
var err error
for err != io.EOF {
// CDATA sections are allowed only in foreign content.
n := p.oe.top()
@@ -2343,6 +2366,8 @@ func (p *parser) parse() error {
// <tag>s. Conversely, explicit <tag>s in r's data can be silently dropped,
// with no corresponding node in the resulting tree.
//
// Parse will reject HTML that is nested deeper than 512 elements.
//
// The input is assumed to be UTF-8 encoded.
func Parse(r io.Reader) (*Node, error) {
return ParseWithOptions(r)
+1 -1
View File
@@ -184,7 +184,7 @@ func render1(w writer, n *Node) error {
return err
}
// Add initial newline where there is danger of a newline beging ignored.
// Add initial newline where there is danger of a newline being ignored.
if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") {
switch n.Data {
case "pre", "listing", "textarea":
+55 -8
View File
@@ -27,6 +27,7 @@ import (
// - If the resulting value is zero or out of range, use a default.
type http2Config struct {
MaxConcurrentStreams uint32
StrictMaxConcurrentRequests bool
MaxDecoderHeaderTableSize uint32
MaxEncoderHeaderTableSize uint32
MaxReadFrameSize uint32
@@ -55,7 +56,7 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config {
PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites,
CountError: h2.CountError,
}
fillNetHTTPServerConfig(&conf, h1)
fillNetHTTPConfig(&conf, h1.HTTP2)
setConfigDefaults(&conf, true)
return conf
}
@@ -64,12 +65,13 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config {
// (the net/http Transport).
func configFromTransport(h2 *Transport) http2Config {
conf := http2Config{
MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize,
MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize,
MaxReadFrameSize: h2.MaxReadFrameSize,
SendPingTimeout: h2.ReadIdleTimeout,
PingTimeout: h2.PingTimeout,
WriteByteTimeout: h2.WriteByteTimeout,
StrictMaxConcurrentRequests: h2.StrictMaxConcurrentStreams,
MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize,
MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize,
MaxReadFrameSize: h2.MaxReadFrameSize,
SendPingTimeout: h2.ReadIdleTimeout,
PingTimeout: h2.PingTimeout,
WriteByteTimeout: h2.WriteByteTimeout,
}
// Unlike most config fields, where out-of-range values revert to the default,
@@ -81,7 +83,7 @@ func configFromTransport(h2 *Transport) http2Config {
}
if h2.t1 != nil {
fillNetHTTPTransportConfig(&conf, h2.t1)
fillNetHTTPConfig(&conf, h2.t1.HTTP2)
}
setConfigDefaults(&conf, false)
return conf
@@ -120,3 +122,48 @@ func adjustHTTP1MaxHeaderSize(n int64) int64 {
const typicalHeaders = 10 // conservative
return n + typicalHeaders*perFieldOverhead
}
func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) {
if h2 == nil {
return
}
if h2.MaxConcurrentStreams != 0 {
conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)
}
if http2ConfigStrictMaxConcurrentRequests(h2) {
conf.StrictMaxConcurrentRequests = true
}
if h2.MaxEncoderHeaderTableSize != 0 {
conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize)
}
if h2.MaxDecoderHeaderTableSize != 0 {
conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize)
}
if h2.MaxConcurrentStreams != 0 {
conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)
}
if h2.MaxReadFrameSize != 0 {
conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize)
}
if h2.MaxReceiveBufferPerConnection != 0 {
conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection)
}
if h2.MaxReceiveBufferPerStream != 0 {
conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream)
}
if h2.SendPingTimeout != 0 {
conf.SendPingTimeout = h2.SendPingTimeout
}
if h2.PingTimeout != 0 {
conf.PingTimeout = h2.PingTimeout
}
if h2.WriteByteTimeout != 0 {
conf.WriteByteTimeout = h2.WriteByteTimeout
}
if h2.PermitProhibitedCipherSuites {
conf.PermitProhibitedCipherSuites = true
}
if h2.CountError != nil {
conf.CountError = h2.CountError
}
}
-61
View File
@@ -1,61 +0,0 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.24
package http2
import "net/http"
// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2.
func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {
fillNetHTTPConfig(conf, srv.HTTP2)
}
// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2.
func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {
fillNetHTTPConfig(conf, tr.HTTP2)
}
func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) {
if h2 == nil {
return
}
if h2.MaxConcurrentStreams != 0 {
conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)
}
if h2.MaxEncoderHeaderTableSize != 0 {
conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize)
}
if h2.MaxDecoderHeaderTableSize != 0 {
conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize)
}
if h2.MaxConcurrentStreams != 0 {
conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)
}
if h2.MaxReadFrameSize != 0 {
conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize)
}
if h2.MaxReceiveBufferPerConnection != 0 {
conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection)
}
if h2.MaxReceiveBufferPerStream != 0 {
conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream)
}
if h2.SendPingTimeout != 0 {
conf.SendPingTimeout = h2.SendPingTimeout
}
if h2.PingTimeout != 0 {
conf.PingTimeout = h2.PingTimeout
}
if h2.WriteByteTimeout != 0 {
conf.WriteByteTimeout = h2.WriteByteTimeout
}
if h2.PermitProhibitedCipherSuites {
conf.PermitProhibitedCipherSuites = true
}
if h2.CountError != nil {
conf.CountError = h2.CountError
}
}
-16
View File
@@ -1,16 +0,0 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.24
package http2
import "net/http"
// Pre-Go 1.24 fallback.
// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24.
func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {}
func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {}
+24 -1
View File
@@ -347,7 +347,7 @@ func (fr *Framer) maxHeaderListSize() uint32 {
func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
// Write the FrameHeader.
f.wbuf = append(f.wbuf[:0],
0, // 3 bytes of length, filled in in endWrite
0, // 3 bytes of length, filled in endWrite
0,
0,
byte(ftype),
@@ -1152,6 +1152,15 @@ type PriorityFrame struct {
PriorityParam
}
var defaultRFC9218Priority = PriorityParam{
incremental: 0,
urgency: 3,
}
// Note that HTTP/2 has had two different prioritization schemes, and
// PriorityParam struct below is a superset of both schemes. The exported
// symbols are from RFC 7540 and the non-exported ones are from RFC 9218.
// PriorityParam are the stream prioritzation parameters.
type PriorityParam struct {
// StreamDep is a 31-bit stream identifier for the
@@ -1167,6 +1176,20 @@ type PriorityParam struct {
// the spec, "Add one to the value to obtain a weight between
// 1 and 256."
Weight uint8
// "The urgency (u) parameter value is Integer (see Section 3.3.1 of
// [STRUCTURED-FIELDS]), between 0 and 7 inclusive, in descending order of
// priority. The default is 3."
urgency uint8
// "The incremental (i) parameter value is Boolean (see Section 3.3.6 of
// [STRUCTURED-FIELDS]). It indicates if an HTTP response can be processed
// incrementally, i.e., provide some meaningful output as chunks of the
// response arrive."
//
// We use uint8 (i.e. 0 is false, 1 is true) instead of bool so we can
// avoid unnecessary type conversions and because either type takes 1 byte.
incremental uint8
}
func (p PriorityParam) IsZero() bool {
+14 -3
View File
@@ -15,21 +15,32 @@ import (
"runtime"
"strconv"
"sync"
"sync/atomic"
)
var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
// Setting DebugGoroutines to false during a test to disable goroutine debugging
// results in race detector complaints when a test leaves goroutines running before
// returning. Tests shouldn't do this, of course, but when they do it generally shows
// up as infrequent, hard-to-debug flakes. (See #66519.)
//
// Disable goroutine debugging during individual tests with an atomic bool.
// (Note that it's safe to enable/disable debugging mid-test, so the actual race condition
// here is harmless.)
var disableDebugGoroutines atomic.Bool
type goroutineLock uint64
func newGoroutineLock() goroutineLock {
if !DebugGoroutines {
if !DebugGoroutines || disableDebugGoroutines.Load() {
return 0
}
return goroutineLock(curGoroutineID())
}
func (g goroutineLock) check() {
if !DebugGoroutines {
if !DebugGoroutines || disableDebugGoroutines.Load() {
return
}
if curGoroutineID() != uint64(g) {
@@ -38,7 +49,7 @@ func (g goroutineLock) check() {
}
func (g goroutineLock) checkNotOn() {
if !DebugGoroutines {
if !DebugGoroutines || disableDebugGoroutines.Load() {
return
}
if curGoroutineID() == uint64(g) {
+7 -28
View File
@@ -15,7 +15,6 @@ package http2 // import "golang.org/x/net/http2"
import (
"bufio"
"context"
"crypto/tls"
"errors"
"fmt"
@@ -35,7 +34,6 @@ var (
VerboseLogs bool
logFrameWrites bool
logFrameReads bool
inTests bool
// Enabling extended CONNECT by causes browsers to attempt to use
// WebSockets-over-HTTP/2. This results in problems when the server's websocket
@@ -255,15 +253,13 @@ func (cw closeWaiter) Wait() {
// idle memory usage with many connections.
type bufferedWriter struct {
_ incomparable
group synctestGroupInterface // immutable
conn net.Conn // immutable
bw *bufio.Writer // non-nil when data is buffered
byteTimeout time.Duration // immutable, WriteByteTimeout
conn net.Conn // immutable
bw *bufio.Writer // non-nil when data is buffered
byteTimeout time.Duration // immutable, WriteByteTimeout
}
func newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter {
func newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter {
return &bufferedWriter{
group: group,
conn: conn,
byteTimeout: timeout,
}
@@ -314,24 +310,18 @@ func (w *bufferedWriter) Flush() error {
type bufferedWriterTimeoutWriter bufferedWriter
func (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) {
return writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p)
return writeWithByteTimeout(w.conn, w.byteTimeout, p)
}
// writeWithByteTimeout writes to conn.
// If more than timeout passes without any bytes being written to the connection,
// the write fails.
func writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) {
func writeWithByteTimeout(conn net.Conn, timeout time.Duration, p []byte) (n int, err error) {
if timeout <= 0 {
return conn.Write(p)
}
for {
var now time.Time
if group == nil {
now = time.Now()
} else {
now = group.Now()
}
conn.SetWriteDeadline(now.Add(timeout))
conn.SetWriteDeadline(time.Now().Add(timeout))
nn, err := conn.Write(p[n:])
n += nn
if n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) {
@@ -417,14 +407,3 @@ func (s *sorter) SortStrings(ss []string) {
// makes that struct also non-comparable, and generally doesn't add
// any size (as long as it's first).
type incomparable [0]func()
// synctestGroupInterface is the methods of synctestGroup used by Server and Transport.
// It's defined as an interface here to let us keep synctestGroup entirely test-only
// and not a part of non-test builds.
type synctestGroupInterface interface {
Join()
Now() time.Time
NewTimer(d time.Duration) timer
AfterFunc(d time.Duration, f func()) timer
ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc)
}
+67 -76
View File
@@ -176,44 +176,15 @@ type Server struct {
// so that we don't embed a Mutex in this struct, which will make the
// struct non-copyable, which might break some callers.
state *serverInternalState
// Synchronization group used for testing.
// Outside of tests, this is nil.
group synctestGroupInterface
}
func (s *Server) markNewGoroutine() {
if s.group != nil {
s.group.Join()
}
}
func (s *Server) now() time.Time {
if s.group != nil {
return s.group.Now()
}
return time.Now()
}
// newTimer creates a new time.Timer, or a synthetic timer in tests.
func (s *Server) newTimer(d time.Duration) timer {
if s.group != nil {
return s.group.NewTimer(d)
}
return timeTimer{time.NewTimer(d)}
}
// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
func (s *Server) afterFunc(d time.Duration, f func()) timer {
if s.group != nil {
return s.group.AfterFunc(d, f)
}
return timeTimer{time.AfterFunc(d, f)}
}
type serverInternalState struct {
mu sync.Mutex
activeConns map[*serverConn]struct{}
// Pool of error channels. This is per-Server rather than global
// because channels can't be reused across synctest bubbles.
errChanPool sync.Pool
}
func (s *serverInternalState) registerConn(sc *serverConn) {
@@ -245,6 +216,27 @@ func (s *serverInternalState) startGracefulShutdown() {
s.mu.Unlock()
}
// Global error channel pool used for uninitialized Servers.
// We use a per-Server pool when possible to avoid using channels across synctest bubbles.
var errChanPool = sync.Pool{
New: func() any { return make(chan error, 1) },
}
func (s *serverInternalState) getErrChan() chan error {
if s == nil {
return errChanPool.Get().(chan error) // Server used without calling ConfigureServer
}
return s.errChanPool.Get().(chan error)
}
func (s *serverInternalState) putErrChan(ch chan error) {
if s == nil {
errChanPool.Put(ch) // Server used without calling ConfigureServer
return
}
s.errChanPool.Put(ch)
}
// ConfigureServer adds HTTP/2 support to a net/http Server.
//
// The configuration conf may be nil.
@@ -257,7 +249,10 @@ func ConfigureServer(s *http.Server, conf *Server) error {
if conf == nil {
conf = new(Server)
}
conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
conf.state = &serverInternalState{
activeConns: make(map[*serverConn]struct{}),
errChanPool: sync.Pool{New: func() any { return make(chan error, 1) }},
}
if h1, h2 := s, conf; h2.IdleTimeout == 0 {
if h1.IdleTimeout != 0 {
h2.IdleTimeout = h1.IdleTimeout
@@ -423,6 +418,9 @@ func (o *ServeConnOpts) handler() http.Handler {
//
// The opts parameter is optional. If nil, default values are used.
func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
if opts == nil {
opts = &ServeConnOpts{}
}
s.serveConn(c, opts, nil)
}
@@ -438,7 +436,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon
conn: c,
baseCtx: baseCtx,
remoteAddrStr: c.RemoteAddr().String(),
bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout),
bw: newBufferedWriter(c, conf.WriteByteTimeout),
handler: opts.handler(),
streams: make(map[uint32]*stream),
readFrameCh: make(chan readFrameResult),
@@ -638,11 +636,11 @@ type serverConn struct {
pingSent bool
sentPingData [8]byte
goAwayCode ErrCode
shutdownTimer timer // nil until used
idleTimer timer // nil if unused
shutdownTimer *time.Timer // nil until used
idleTimer *time.Timer // nil if unused
readIdleTimeout time.Duration
pingTimeout time.Duration
readIdleTimer timer // nil if unused
readIdleTimer *time.Timer // nil if unused
// Owned by the writeFrameAsync goroutine:
headerWriteBuf bytes.Buffer
@@ -687,12 +685,12 @@ type stream struct {
flow outflow // limits writing from Handler to client
inflow inflow // what the client is allowed to POST/etc to us
state streamState
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
gotTrailerHeader bool // HEADER frame for trailers was seen
wroteHeaders bool // whether we wrote headers (not status 100)
readDeadline timer // nil if unused
writeDeadline timer // nil if unused
closeErr error // set before cw is closed
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
gotTrailerHeader bool // HEADER frame for trailers was seen
wroteHeaders bool // whether we wrote headers (not status 100)
readDeadline *time.Timer // nil if unused
writeDeadline *time.Timer // nil if unused
closeErr error // set before cw is closed
trailer http.Header // accumulated trailers
reqTrailer http.Header // handler's Request.Trailer
@@ -848,7 +846,6 @@ type readFrameResult struct {
// consumer is done with the frame.
// It's run on its own goroutine.
func (sc *serverConn) readFrames() {
sc.srv.markNewGoroutine()
gate := make(chan struct{})
gateDone := func() { gate <- struct{}{} }
for {
@@ -881,7 +878,6 @@ type frameWriteResult struct {
// At most one goroutine can be running writeFrameAsync at a time per
// serverConn.
func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) {
sc.srv.markNewGoroutine()
var err error
if wd == nil {
err = wr.write.writeFrame(sc)
@@ -965,22 +961,22 @@ func (sc *serverConn) serve(conf http2Config) {
sc.setConnState(http.StateIdle)
if sc.srv.IdleTimeout > 0 {
sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
defer sc.idleTimer.Stop()
}
if conf.SendPingTimeout > 0 {
sc.readIdleTimeout = conf.SendPingTimeout
sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer)
sc.readIdleTimer = time.AfterFunc(conf.SendPingTimeout, sc.onReadIdleTimer)
defer sc.readIdleTimer.Stop()
}
go sc.readFrames() // closed by defer sc.conn.Close above
settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer)
settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
defer settingsTimer.Stop()
lastFrameTime := sc.srv.now()
lastFrameTime := time.Now()
loopNum := 0
for {
loopNum++
@@ -994,7 +990,7 @@ func (sc *serverConn) serve(conf http2Config) {
case res := <-sc.wroteFrameCh:
sc.wroteFrame(res)
case res := <-sc.readFrameCh:
lastFrameTime = sc.srv.now()
lastFrameTime = time.Now()
// Process any written frames before reading new frames from the client since a
// written frame could have triggered a new stream to be started.
if sc.writingFrameAsync {
@@ -1077,7 +1073,7 @@ func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) {
}
pingAt := lastFrameReadTime.Add(sc.readIdleTimeout)
now := sc.srv.now()
now := time.Now()
if pingAt.After(now) {
// We received frames since arming the ping timer.
// Reset it for the next possible timeout.
@@ -1141,10 +1137,10 @@ func (sc *serverConn) readPreface() error {
errc <- nil
}
}()
timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server?
timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
defer timer.Stop()
select {
case <-timer.C():
case <-timer.C:
return errPrefaceTimeout
case err := <-errc:
if err == nil {
@@ -1156,10 +1152,6 @@ func (sc *serverConn) readPreface() error {
}
}
var errChanPool = sync.Pool{
New: func() interface{} { return make(chan error, 1) },
}
var writeDataPool = sync.Pool{
New: func() interface{} { return new(writeData) },
}
@@ -1167,7 +1159,7 @@ var writeDataPool = sync.Pool{
// writeDataFromHandler writes DATA response frames from a handler on
// the given stream.
func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
ch := errChanPool.Get().(chan error)
ch := sc.srv.state.getErrChan()
writeArg := writeDataPool.Get().(*writeData)
*writeArg = writeData{stream.id, data, endStream}
err := sc.writeFrameFromHandler(FrameWriteRequest{
@@ -1199,7 +1191,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea
return errStreamClosed
}
}
errChanPool.Put(ch)
sc.srv.state.putErrChan(ch)
if frameWriteDone {
writeDataPool.Put(writeArg)
}
@@ -1513,7 +1505,7 @@ func (sc *serverConn) goAway(code ErrCode) {
func (sc *serverConn) shutDownIn(d time.Duration) {
sc.serveG.check()
sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer)
sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
}
func (sc *serverConn) resetStream(se StreamError) {
@@ -2118,7 +2110,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
// (in Go 1.8), though. That's a more sane option anyway.
if sc.hs.ReadTimeout > 0 {
sc.conn.SetReadDeadline(time.Time{})
st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
}
return sc.scheduleHandler(id, rw, req, handler)
@@ -2216,7 +2208,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
st.flow.add(sc.initialStreamSendWindowSize)
st.inflow.init(sc.initialStreamRecvWindowSize)
if sc.hs.WriteTimeout > 0 {
st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
}
sc.streams[id] = st
@@ -2405,7 +2397,6 @@ func (sc *serverConn) handlerDone() {
// Run on its own goroutine.
func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
sc.srv.markNewGoroutine()
defer sc.sendServeMsg(handlerDoneMsg)
didPanic := true
defer func() {
@@ -2454,7 +2445,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro
// waiting for this frame to be written, so an http.Flush mid-handler
// writes out the correct value of keys, before a handler later potentially
// mutates it.
errc = errChanPool.Get().(chan error)
errc = sc.srv.state.getErrChan()
}
if err := sc.writeFrameFromHandler(FrameWriteRequest{
write: headerData,
@@ -2466,7 +2457,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro
if errc != nil {
select {
case err := <-errc:
errChanPool.Put(errc)
sc.srv.state.putErrChan(errc)
return err
case <-sc.doneServing:
return errClientDisconnected
@@ -2573,7 +2564,7 @@ func (b *requestBody) Read(p []byte) (n int, err error) {
if err == io.EOF {
b.sawEOF = true
}
if b.conn == nil && inTests {
if b.conn == nil {
return
}
b.conn.noteBodyReadFromHandler(b.stream, n, err)
@@ -2702,7 +2693,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
var date string
if _, ok := rws.snapHeader["Date"]; !ok {
// TODO(bradfitz): be faster here, like net/http? measure.
date = rws.conn.srv.now().UTC().Format(http.TimeFormat)
date = time.Now().UTC().Format(http.TimeFormat)
}
for _, v := range rws.snapHeader["Trailer"] {
@@ -2824,7 +2815,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
st := w.rws.stream
if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
if !deadline.IsZero() && deadline.Before(time.Now()) {
// If we're setting a deadline in the past, reset the stream immediately
// so writes after SetWriteDeadline returns will fail.
st.onReadTimeout()
@@ -2840,9 +2831,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
if deadline.IsZero() {
st.readDeadline = nil
} else if st.readDeadline == nil {
st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout)
st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
} else {
st.readDeadline.Reset(deadline.Sub(sc.srv.now()))
st.readDeadline.Reset(deadline.Sub(time.Now()))
}
})
return nil
@@ -2850,7 +2841,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
st := w.rws.stream
if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
if !deadline.IsZero() && deadline.Before(time.Now()) {
// If we're setting a deadline in the past, reset the stream immediately
// so writes after SetWriteDeadline returns will fail.
st.onWriteTimeout()
@@ -2866,9 +2857,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
if deadline.IsZero() {
st.writeDeadline = nil
} else if st.writeDeadline == nil {
st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout)
st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
} else {
st.writeDeadline.Reset(deadline.Sub(sc.srv.now()))
st.writeDeadline.Reset(deadline.Sub(time.Now()))
}
})
return nil
@@ -3147,7 +3138,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
method: opts.Method,
url: u,
header: cloneHeader(opts.Header),
done: errChanPool.Get().(chan error),
done: sc.srv.state.getErrChan(),
}
select {
@@ -3164,7 +3155,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
case <-st.cw:
return errStreamClosed
case err := <-msg.done:
errChanPool.Put(msg.done)
sc.srv.state.putErrChan(msg.done)
return err
}
}
-20
View File
@@ -1,20 +0,0 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import "time"
// A timer is a time.Timer, as an interface which can be replaced in tests.
type timer = interface {
C() <-chan time.Time
Reset(d time.Duration) bool
Stop() bool
}
// timeTimer adapts a time.Timer to the timer interface.
type timeTimer struct {
*time.Timer
}
func (t timeTimer) C() <-chan time.Time { return t.Timer.C }
+24 -76
View File
@@ -193,50 +193,6 @@ type Transport struct {
type transportTestHooks struct {
newclientconn func(*ClientConn)
group synctestGroupInterface
}
func (t *Transport) markNewGoroutine() {
if t != nil && t.transportTestHooks != nil {
t.transportTestHooks.group.Join()
}
}
func (t *Transport) now() time.Time {
if t != nil && t.transportTestHooks != nil {
return t.transportTestHooks.group.Now()
}
return time.Now()
}
func (t *Transport) timeSince(when time.Time) time.Duration {
if t != nil && t.transportTestHooks != nil {
return t.now().Sub(when)
}
return time.Since(when)
}
// newTimer creates a new time.Timer, or a synthetic timer in tests.
func (t *Transport) newTimer(d time.Duration) timer {
if t.transportTestHooks != nil {
return t.transportTestHooks.group.NewTimer(d)
}
return timeTimer{time.NewTimer(d)}
}
// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
func (t *Transport) afterFunc(d time.Duration, f func()) timer {
if t.transportTestHooks != nil {
return t.transportTestHooks.group.AfterFunc(d, f)
}
return timeTimer{time.AfterFunc(d, f)}
}
func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
if t.transportTestHooks != nil {
return t.transportTestHooks.group.ContextWithTimeout(ctx, d)
}
return context.WithTimeout(ctx, d)
}
func (t *Transport) maxHeaderListSize() uint32 {
@@ -366,7 +322,7 @@ type ClientConn struct {
readerErr error // set before readerDone is closed
idleTimeout time.Duration // or 0 for never
idleTimer timer
idleTimer *time.Timer
mu sync.Mutex // guards following
cond *sync.Cond // hold mu; broadcast on flow/closed changes
@@ -399,6 +355,7 @@ type ClientConn struct {
readIdleTimeout time.Duration
pingTimeout time.Duration
extendedConnectAllowed bool
strictMaxConcurrentStreams bool
// rstStreamPingsBlocked works around an unfortunate gRPC behavior.
// gRPC strictly limits the number of PING frames that it will receive.
@@ -534,14 +491,12 @@ func (cs *clientStream) closeReqBodyLocked() {
cs.reqBodyClosed = make(chan struct{})
reqBodyClosed := cs.reqBodyClosed
go func() {
cs.cc.t.markNewGoroutine()
cs.reqBody.Close()
close(reqBodyClosed)
}()
}
type stickyErrWriter struct {
group synctestGroupInterface
conn net.Conn
timeout time.Duration
err *error
@@ -551,7 +506,7 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
if *sew.err != nil {
return 0, *sew.err
}
n, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p)
n, err = writeWithByteTimeout(sew.conn, sew.timeout, p)
*sew.err = err
return n, err
}
@@ -650,9 +605,9 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
backoff := float64(uint(1) << (uint(retry) - 1))
backoff += backoff * (0.1 * mathrand.Float64())
d := time.Second * time.Duration(backoff)
tm := t.newTimer(d)
tm := time.NewTimer(d)
select {
case <-tm.C():
case <-tm.C:
t.vlogf("RoundTrip retrying after failure: %v", roundTripErr)
continue
case <-req.Context().Done():
@@ -699,6 +654,7 @@ var (
errClientConnUnusable = errors.New("http2: client conn not usable")
errClientConnNotEstablished = errors.New("http2: client conn could not be established")
errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
errClientConnForceClosed = errors.New("http2: client connection force closed via ClientConn.Close")
)
// shouldRetryRequest is called by RoundTrip when a request fails to get
@@ -829,7 +785,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
initialWindowSize: 65535, // spec default
initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream,
maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings.
peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
strictMaxConcurrentStreams: conf.StrictMaxConcurrentRequests,
peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
streams: make(map[uint32]*clientStream),
singleUse: singleUse,
seenSettingsChan: make(chan struct{}),
@@ -838,14 +795,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
pingTimeout: conf.PingTimeout,
pings: make(map[[8]byte]chan struct{}),
reqHeaderMu: make(chan struct{}, 1),
lastActive: t.now(),
lastActive: time.Now(),
}
var group synctestGroupInterface
if t.transportTestHooks != nil {
t.markNewGoroutine()
t.transportTestHooks.newclientconn(cc)
c = cc.tconn
group = t.group
}
if VerboseLogs {
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
@@ -857,7 +811,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
// TODO: adjust this writer size to account for frame size +
// MTU + crypto/tls record padding.
cc.bw = bufio.NewWriter(stickyErrWriter{
group: group,
conn: c,
timeout: conf.WriteByteTimeout,
err: &cc.werr,
@@ -906,7 +859,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
// Start the idle timer after the connection is fully initialized.
if d := t.idleConnTimeout(); d != 0 {
cc.idleTimeout = d
cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout)
cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
}
go cc.readLoop()
@@ -917,7 +870,7 @@ func (cc *ClientConn) healthCheck() {
pingTimeout := cc.pingTimeout
// We don't need to periodically ping in the health check, because the readLoop of ClientConn will
// trigger the healthCheck again if there is no frame received.
ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout)
ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
defer cancel()
cc.vlogf("http2: Transport sending health check")
err := cc.Ping(ctx)
@@ -1067,7 +1020,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
return
}
var maxConcurrentOkay bool
if cc.t.StrictMaxConcurrentStreams {
if cc.strictMaxConcurrentStreams {
// We'll tell the caller we can take a new request to
// prevent the caller from dialing a new TCP
// connection, but then we'll block later before
@@ -1120,7 +1073,7 @@ func (cc *ClientConn) tooIdleLocked() bool {
// times are compared based on their wall time. We don't want
// to reuse a connection that's been sitting idle during
// VM/laptop suspend if monotonic time was also frozen.
return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout
return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout
}
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
@@ -1186,7 +1139,6 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
done := make(chan struct{})
cancelled := false // guarded by cc.mu
go func() {
cc.t.markNewGoroutine()
cc.mu.Lock()
defer cc.mu.Unlock()
for {
@@ -1257,8 +1209,7 @@ func (cc *ClientConn) closeForError(err error) {
//
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
func (cc *ClientConn) Close() error {
err := errors.New("http2: client connection force closed via ClientConn.Close")
cc.closeForError(err)
cc.closeForError(errClientConnForceClosed)
return nil
}
@@ -1427,7 +1378,6 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
//
// It sends the request and performs post-request cleanup (closing Request.Body, etc.).
func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) {
cs.cc.t.markNewGoroutine()
err := cs.writeRequest(req, streamf)
cs.cleanupWriteRequest(err)
}
@@ -1558,9 +1508,9 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre
var respHeaderTimer <-chan time.Time
var respHeaderRecv chan struct{}
if d := cc.responseHeaderTimeout(); d != 0 {
timer := cc.t.newTimer(d)
timer := time.NewTimer(d)
defer timer.Stop()
respHeaderTimer = timer.C()
respHeaderTimer = timer.C
respHeaderRecv = cs.respHeaderRecv
}
// Wait until the peer half-closes its end of the stream,
@@ -1753,7 +1703,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error {
// Return a fatal error which aborts the retry loop.
return errClientConnNotEstablished
}
cc.lastActive = cc.t.now()
cc.lastActive = time.Now()
if cc.closed || !cc.canTakeNewRequestLocked() {
return errClientConnUnusable
}
@@ -2092,10 +2042,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
if len(cc.streams) != slen-1 {
panic("forgetting unknown stream id")
}
cc.lastActive = cc.t.now()
cc.lastActive = time.Now()
if len(cc.streams) == 0 && cc.idleTimer != nil {
cc.idleTimer.Reset(cc.idleTimeout)
cc.lastIdle = cc.t.now()
cc.lastIdle = time.Now()
}
// Wake up writeRequestBody via clientStream.awaitFlowControl and
// wake up RoundTrip if there is a pending request.
@@ -2121,7 +2071,6 @@ type clientConnReadLoop struct {
// readLoop runs in its own goroutine and reads and dispatches frames.
func (cc *ClientConn) readLoop() {
cc.t.markNewGoroutine()
rl := &clientConnReadLoop{cc: cc}
defer rl.cleanup()
cc.readerErr = rl.run()
@@ -2188,9 +2137,9 @@ func (rl *clientConnReadLoop) cleanup() {
if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout {
unusedWaitTime = cc.idleTimeout
}
idleTime := cc.t.now().Sub(cc.lastActive)
idleTime := time.Now().Sub(cc.lastActive)
if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle {
cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() {
cc.idleTimer = time.AfterFunc(unusedWaitTime-idleTime, func() {
cc.t.connPool().MarkDead(cc)
})
} else {
@@ -2250,9 +2199,9 @@ func (rl *clientConnReadLoop) run() error {
cc := rl.cc
gotSettings := false
readIdleTimeout := cc.readIdleTimeout
var t timer
var t *time.Timer
if readIdleTimeout != 0 {
t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck)
t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
}
for {
f, err := cc.fr.ReadFrame()
@@ -2998,7 +2947,6 @@ func (cc *ClientConn) Ping(ctx context.Context) error {
var pingError error
errc := make(chan struct{})
go func() {
cc.t.markNewGoroutine()
cc.wmu.Lock()
defer cc.wmu.Unlock()
if pingError = cc.fr.WritePing(false, p); pingError != nil {
@@ -3228,7 +3176,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) {
cc.mu.Lock()
ci.WasIdle = len(cc.streams) == 0 && reused
if ci.WasIdle && !cc.lastActive.IsZero() {
ci.IdleTime = cc.t.timeSince(cc.lastActive)
ci.IdleTime = time.Since(cc.lastActive)
}
cc.mu.Unlock()
+2
View File
@@ -42,6 +42,8 @@ type OpenStreamOptions struct {
// PusherID is zero if the stream was initiated by the client. Otherwise,
// PusherID names the stream that pushed the newly opened stream.
PusherID uint32
// priority is used to set the priority of the newly opened stream.
priority PriorityParam
}
// FrameWriteRequest is a request to write a frame.
-451
View File
@@ -1,451 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import (
"fmt"
"math"
"sort"
)
// RFC 7540, Section 5.3.5: the default weight is 16.
const priorityDefaultWeight = 15 // 16 = 15 + 1
// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
type PriorityWriteSchedulerConfig struct {
// MaxClosedNodesInTree controls the maximum number of closed streams to
// retain in the priority tree. Setting this to zero saves a small amount
// of memory at the cost of performance.
//
// See RFC 7540, Section 5.3.4:
// "It is possible for a stream to become closed while prioritization
// information ... is in transit. ... This potentially creates suboptimal
// prioritization, since the stream could be given a priority that is
// different from what is intended. To avoid these problems, an endpoint
// SHOULD retain stream prioritization state for a period after streams
// become closed. The longer state is retained, the lower the chance that
// streams are assigned incorrect or default priority values."
MaxClosedNodesInTree int
// MaxIdleNodesInTree controls the maximum number of idle streams to
// retain in the priority tree. Setting this to zero saves a small amount
// of memory at the cost of performance.
//
// See RFC 7540, Section 5.3.4:
// Similarly, streams that are in the "idle" state can be assigned
// priority or become a parent of other streams. This allows for the
// creation of a grouping node in the dependency tree, which enables
// more flexible expressions of priority. Idle streams begin with a
// default priority (Section 5.3.5).
MaxIdleNodesInTree int
// ThrottleOutOfOrderWrites enables write throttling to help ensure that
// data is delivered in priority order. This works around a race where
// stream B depends on stream A and both streams are about to call Write
// to queue DATA frames. If B wins the race, a naive scheduler would eagerly
// write as much data from B as possible, but this is suboptimal because A
// is a higher-priority stream. With throttling enabled, we write a small
// amount of data from B to minimize the amount of bandwidth that B can
// steal from A.
ThrottleOutOfOrderWrites bool
}
// NewPriorityWriteScheduler constructs a WriteScheduler that schedules
// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
// If cfg is nil, default options are used.
func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
if cfg == nil {
// For justification of these defaults, see:
// https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
cfg = &PriorityWriteSchedulerConfig{
MaxClosedNodesInTree: 10,
MaxIdleNodesInTree: 10,
ThrottleOutOfOrderWrites: false,
}
}
ws := &priorityWriteScheduler{
nodes: make(map[uint32]*priorityNode),
maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
maxIdleNodesInTree: cfg.MaxIdleNodesInTree,
enableWriteThrottle: cfg.ThrottleOutOfOrderWrites,
}
ws.nodes[0] = &ws.root
if cfg.ThrottleOutOfOrderWrites {
ws.writeThrottleLimit = 1024
} else {
ws.writeThrottleLimit = math.MaxInt32
}
return ws
}
type priorityNodeState int
const (
priorityNodeOpen priorityNodeState = iota
priorityNodeClosed
priorityNodeIdle
)
// priorityNode is a node in an HTTP/2 priority tree.
// Each node is associated with a single stream ID.
// See RFC 7540, Section 5.3.
type priorityNode struct {
q writeQueue // queue of pending frames to write
id uint32 // id of the stream, or 0 for the root of the tree
weight uint8 // the actual weight is weight+1, so the value is in [1,256]
state priorityNodeState // open | closed | idle
bytes int64 // number of bytes written by this node, or 0 if closed
subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree
// These links form the priority tree.
parent *priorityNode
kids *priorityNode // start of the kids list
prev, next *priorityNode // doubly-linked list of siblings
}
func (n *priorityNode) setParent(parent *priorityNode) {
if n == parent {
panic("setParent to self")
}
if n.parent == parent {
return
}
// Unlink from current parent.
if parent := n.parent; parent != nil {
if n.prev == nil {
parent.kids = n.next
} else {
n.prev.next = n.next
}
if n.next != nil {
n.next.prev = n.prev
}
}
// Link to new parent.
// If parent=nil, remove n from the tree.
// Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
n.parent = parent
if parent == nil {
n.next = nil
n.prev = nil
} else {
n.next = parent.kids
n.prev = nil
if n.next != nil {
n.next.prev = n
}
parent.kids = n
}
}
func (n *priorityNode) addBytes(b int64) {
n.bytes += b
for ; n != nil; n = n.parent {
n.subtreeBytes += b
}
}
// walkReadyInOrder iterates over the tree in priority order, calling f for each node
// with a non-empty write queue. When f returns true, this function returns true and the
// walk halts. tmp is used as scratch space for sorting.
//
// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
// if any ancestor p of n is still open (ignoring the root node).
func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool {
if !n.q.empty() && f(n, openParent) {
return true
}
if n.kids == nil {
return false
}
// Don't consider the root "open" when updating openParent since
// we can't send data frames on the root stream (only control frames).
if n.id != 0 {
openParent = openParent || (n.state == priorityNodeOpen)
}
// Common case: only one kid or all kids have the same weight.
// Some clients don't use weights; other clients (like web browsers)
// use mostly-linear priority trees.
w := n.kids.weight
needSort := false
for k := n.kids.next; k != nil; k = k.next {
if k.weight != w {
needSort = true
break
}
}
if !needSort {
for k := n.kids; k != nil; k = k.next {
if k.walkReadyInOrder(openParent, tmp, f) {
return true
}
}
return false
}
// Uncommon case: sort the child nodes. We remove the kids from the parent,
// then re-insert after sorting so we can reuse tmp for future sort calls.
*tmp = (*tmp)[:0]
for n.kids != nil {
*tmp = append(*tmp, n.kids)
n.kids.setParent(nil)
}
sort.Sort(sortPriorityNodeSiblings(*tmp))
for i := len(*tmp) - 1; i >= 0; i-- {
(*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
}
for k := n.kids; k != nil; k = k.next {
if k.walkReadyInOrder(openParent, tmp, f) {
return true
}
}
return false
}
type sortPriorityNodeSiblings []*priorityNode
func (z sortPriorityNodeSiblings) Len() int { return len(z) }
func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
func (z sortPriorityNodeSiblings) Less(i, k int) bool {
// Prefer the subtree that has sent fewer bytes relative to its weight.
// See sections 5.3.2 and 5.3.4.
wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)
if bi == 0 && bk == 0 {
return wi >= wk
}
if bk == 0 {
return false
}
return bi/bk <= wi/wk
}
type priorityWriteScheduler struct {
// root is the root of the priority tree, where root.id = 0.
// The root queues control frames that are not associated with any stream.
root priorityNode
// nodes maps stream ids to priority tree nodes.
nodes map[uint32]*priorityNode
// maxID is the maximum stream id in nodes.
maxID uint32
// lists of nodes that have been closed or are idle, but are kept in
// the tree for improved prioritization. When the lengths exceed either
// maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
closedNodes, idleNodes []*priorityNode
// From the config.
maxClosedNodesInTree int
maxIdleNodesInTree int
writeThrottleLimit int32
enableWriteThrottle bool
// tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
tmp []*priorityNode
// pool of empty queues for reuse.
queuePool writeQueuePool
}
func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
// The stream may be currently idle but cannot be opened or closed.
if curr := ws.nodes[streamID]; curr != nil {
if curr.state != priorityNodeIdle {
panic(fmt.Sprintf("stream %d already opened", streamID))
}
curr.state = priorityNodeOpen
return
}
// RFC 7540, Section 5.3.5:
// "All streams are initially assigned a non-exclusive dependency on stream 0x0.
// Pushed streams initially depend on their associated stream. In both cases,
// streams are assigned a default weight of 16."
parent := ws.nodes[options.PusherID]
if parent == nil {
parent = &ws.root
}
n := &priorityNode{
q: *ws.queuePool.get(),
id: streamID,
weight: priorityDefaultWeight,
state: priorityNodeOpen,
}
n.setParent(parent)
ws.nodes[streamID] = n
if streamID > ws.maxID {
ws.maxID = streamID
}
}
func (ws *priorityWriteScheduler) CloseStream(streamID uint32) {
if streamID == 0 {
panic("violation of WriteScheduler interface: cannot close stream 0")
}
if ws.nodes[streamID] == nil {
panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
}
if ws.nodes[streamID].state != priorityNodeOpen {
panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
}
n := ws.nodes[streamID]
n.state = priorityNodeClosed
n.addBytes(-n.bytes)
q := n.q
ws.queuePool.put(&q)
n.q.s = nil
if ws.maxClosedNodesInTree > 0 {
ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)
} else {
ws.removeNode(n)
}
}
func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
if streamID == 0 {
panic("adjustPriority on root")
}
// If streamID does not exist, there are two cases:
// - A closed stream that has been removed (this will have ID <= maxID)
// - An idle stream that is being used for "grouping" (this will have ID > maxID)
n := ws.nodes[streamID]
if n == nil {
if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {
return
}
ws.maxID = streamID
n = &priorityNode{
q: *ws.queuePool.get(),
id: streamID,
weight: priorityDefaultWeight,
state: priorityNodeIdle,
}
n.setParent(&ws.root)
ws.nodes[streamID] = n
ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)
}
// Section 5.3.1: A dependency on a stream that is not currently in the tree
// results in that stream being given a default priority (Section 5.3.5).
parent := ws.nodes[priority.StreamDep]
if parent == nil {
n.setParent(&ws.root)
n.weight = priorityDefaultWeight
return
}
// Ignore if the client tries to make a node its own parent.
if n == parent {
return
}
// Section 5.3.3:
// "If a stream is made dependent on one of its own dependencies, the
// formerly dependent stream is first moved to be dependent on the
// reprioritized stream's previous parent. The moved dependency retains
// its weight."
//
// That is: if parent depends on n, move parent to depend on n.parent.
for x := parent.parent; x != nil; x = x.parent {
if x == n {
parent.setParent(n.parent)
break
}
}
// Section 5.3.3: The exclusive flag causes the stream to become the sole
// dependency of its parent stream, causing other dependencies to become
// dependent on the exclusive stream.
if priority.Exclusive {
k := parent.kids
for k != nil {
next := k.next
if k != n {
k.setParent(n)
}
k = next
}
}
n.setParent(parent)
n.weight = priority.Weight
}
func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
var n *priorityNode
if wr.isControl() {
n = &ws.root
} else {
id := wr.StreamID()
n = ws.nodes[id]
if n == nil {
// id is an idle or closed stream. wr should not be a HEADERS or
// DATA frame. In other case, we push wr onto the root, rather
// than creating a new priorityNode.
if wr.DataSize() > 0 {
panic("add DATA on non-open stream")
}
n = &ws.root
}
}
n.q.push(wr)
}
func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {
ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool {
limit := int32(math.MaxInt32)
if openParent {
limit = ws.writeThrottleLimit
}
wr, ok = n.q.consume(limit)
if !ok {
return false
}
n.addBytes(int64(wr.DataSize()))
// If B depends on A and B continuously has data available but A
// does not, gradually increase the throttling limit to allow B to
// steal more and more bandwidth from A.
if openParent {
ws.writeThrottleLimit += 1024
if ws.writeThrottleLimit < 0 {
ws.writeThrottleLimit = math.MaxInt32
}
} else if ws.enableWriteThrottle {
ws.writeThrottleLimit = 1024
}
return true
})
return wr, ok
}
func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) {
if maxSize == 0 {
return
}
if len(*list) == maxSize {
// Remove the oldest node, then shift left.
ws.removeNode((*list)[0])
x := (*list)[1:]
copy(*list, x)
*list = (*list)[:len(x)]
}
*list = append(*list, n)
}
func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
for n.kids != nil {
n.kids.setParent(n.parent)
}
n.setParent(nil)
delete(ws.nodes, n.id)
}
+1 -1
View File
@@ -25,7 +25,7 @@ type roundRobinWriteScheduler struct {
}
// newRoundRobinWriteScheduler constructs a new write scheduler.
// The round robin scheduler priorizes control frames
// The round robin scheduler prioritizes control frames
// like SETTINGS and PING over DATA frames.
// When there are no control frames to send, it performs a round-robin
// selection from the ready streams.
+2 -2
View File
@@ -51,7 +51,7 @@ type EncodeHeadersParam struct {
DefaultUserAgent string
}
// EncodeHeadersParam is the result of EncodeHeaders.
// EncodeHeadersResult is the result of EncodeHeaders.
type EncodeHeadersResult struct {
HasBody bool
HasTrailers bool
@@ -399,7 +399,7 @@ type ServerRequestResult struct {
// If the request should be rejected, this is a short string suitable for passing
// to the http2 package's CountError function.
// It might be a bit odd to return errors this way rather than returing an error,
// It might be a bit odd to return errors this way rather than returning an error,
// but this ensures we don't forget to include a CountError reason.
InvalidReason string
}
+8 -1
View File
@@ -38,8 +38,15 @@ func SchedSetaffinity(pid int, set *CPUSet) error {
// Zero clears the set s, so that it contains no CPUs.
func (s *CPUSet) Zero() {
clear(s[:])
}
// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]
// will silently ignore any invalid CPU bits in [CPUSet] so this is an
// efficient way of resetting the CPU affinity of a process.
func (s *CPUSet) Fill() {
for i := range s {
s[i] = 0
s[i] = ^cpuMask(0)
}
}
+1 -3
View File
@@ -23,7 +23,5 @@ func (fds *FdSet) IsSet(fd int) bool {
// Zero clears the set fds.
func (fds *FdSet) Zero() {
for i := range fds.Bits {
fds.Bits[i] = 0
}
clear(fds.Bits[:])
}
+1 -3
View File
@@ -111,9 +111,7 @@ func (ifr *Ifreq) SetUint32(v uint32) {
// clear zeroes the ifreq's union field to prevent trailing garbage data from
// being sent to the kernel if an ifreq is reused.
func (ifr *Ifreq) clear() {
for i := range ifr.raw.Ifru {
ifr.raw.Ifru[i] = 0
}
clear(ifr.raw.Ifru[:])
}
// TODO(mdlayher): export as IfreqData? For now we can provide helpers such as
+1
View File
@@ -49,6 +49,7 @@ esac
if [[ "$GOOS" = "linux" ]]; then
# Use the Docker-based build system
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
set -e
$cmd docker build --tag generate:$GOOS $GOOS
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS
exit
+1 -3
View File
@@ -801,9 +801,7 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
// one. The kernel expects SID to be in network byte order.
binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
copy(sa.raw[8:14], sa.Remote)
for i := 14; i < 14+IFNAMSIZ; i++ {
sa.raw[i] = 0
}
clear(sa.raw[14 : 14+IFNAMSIZ])
copy(sa.raw[14:], sa.Dev)
return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
}
+17
View File
@@ -248,6 +248,23 @@ func Statvfs(path string, buf *Statvfs_t) (err error) {
return Statvfs1(path, buf, ST_WAIT)
}
func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) {
var (
_p0 unsafe.Pointer
bufsize uintptr
)
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
/*
* Exposed directly
*/
+1 -1
View File
@@ -629,7 +629,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Kill(pid int, signum syscall.Signal) (err error)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Link(path string, link string) (err error)
//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_llisten
//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_listen
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Madvise(b []byte, advice int) (err error)
//sys Mkdir(path string, mode uint32) (err error)
+4 -4
View File
@@ -72,7 +72,7 @@ import (
//go:cgo_import_dynamic libc_kill kill "libc.so"
//go:cgo_import_dynamic libc_lchown lchown "libc.so"
//go:cgo_import_dynamic libc_link link "libc.so"
//go:cgo_import_dynamic libc___xnet_llisten __xnet_llisten "libsocket.so"
//go:cgo_import_dynamic libc___xnet_listen __xnet_listen "libsocket.so"
//go:cgo_import_dynamic libc_lstat lstat "libc.so"
//go:cgo_import_dynamic libc_madvise madvise "libc.so"
//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
@@ -221,7 +221,7 @@ import (
//go:linkname procKill libc_kill
//go:linkname procLchown libc_lchown
//go:linkname procLink libc_link
//go:linkname proc__xnet_llisten libc___xnet_llisten
//go:linkname proc__xnet_listen libc___xnet_listen
//go:linkname procLstat libc_lstat
//go:linkname procMadvise libc_madvise
//go:linkname procMkdir libc_mkdir
@@ -371,7 +371,7 @@ var (
procKill,
procLchown,
procLink,
proc__xnet_llisten,
proc__xnet_listen,
procLstat,
procMadvise,
procMkdir,
@@ -1178,7 +1178,7 @@ func Link(path string, link string) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Listen(s int, backlog int) (err error) {
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_llisten)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0)
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_listen)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
+41
View File
@@ -632,6 +632,8 @@ const (
IFA_FLAGS = 0x8
IFA_RT_PRIORITY = 0x9
IFA_TARGET_NETNSID = 0xa
IFAL_LABEL = 0x2
IFAL_ADDRESS = 0x1
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -689,6 +691,7 @@ const (
SizeofRtAttr = 0x4
SizeofIfInfomsg = 0x10
SizeofIfAddrmsg = 0x8
SizeofIfAddrlblmsg = 0xc
SizeofIfaCacheinfo = 0x10
SizeofRtMsg = 0xc
SizeofRtNexthop = 0x8
@@ -740,6 +743,15 @@ type IfAddrmsg struct {
Index uint32
}
type IfAddrlblmsg struct {
Family uint8
_ uint8
Prefixlen uint8
Flags uint8
Index uint32
Seq uint32
}
type IfaCacheinfo struct {
Prefered uint32
Valid uint32
@@ -3052,6 +3064,23 @@ const (
)
const (
TCA_UNSPEC = 0x0
TCA_KIND = 0x1
TCA_OPTIONS = 0x2
TCA_STATS = 0x3
TCA_XSTATS = 0x4
TCA_RATE = 0x5
TCA_FCNT = 0x6
TCA_STATS2 = 0x7
TCA_STAB = 0x8
TCA_PAD = 0x9
TCA_DUMP_INVISIBLE = 0xa
TCA_CHAIN = 0xb
TCA_HW_OFFLOAD = 0xc
TCA_INGRESS_BLOCK = 0xd
TCA_EGRESS_BLOCK = 0xe
TCA_DUMP_FLAGS = 0xf
TCA_EXT_WARN_MSG = 0x10
RTNLGRP_NONE = 0x0
RTNLGRP_LINK = 0x1
RTNLGRP_NOTIFY = 0x2
@@ -3086,6 +3115,18 @@ const (
RTNLGRP_IPV6_MROUTE_R = 0x1f
RTNLGRP_NEXTHOP = 0x20
RTNLGRP_BRVLAN = 0x21
RTNLGRP_MCTP_IFADDR = 0x22
RTNLGRP_TUNNEL = 0x23
RTNLGRP_STATS = 0x24
RTNLGRP_IPV4_MCADDR = 0x25
RTNLGRP_IPV6_MCADDR = 0x26
RTNLGRP_IPV6_ACADDR = 0x27
TCA_ROOT_UNSPEC = 0x0
TCA_ROOT_TAB = 0x1
TCA_ROOT_FLAGS = 0x2
TCA_ROOT_COUNT = 0x3
TCA_ROOT_TIME_DELTA = 0x4
TCA_ROOT_EXT_WARN_MSG = 0x5
)
type CapUserHeader struct {
+2
View File
@@ -321,6 +321,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents
//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
//sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
+22
View File
@@ -65,6 +65,22 @@ var signals = [...]string{
15: "terminated",
}
// File flags for [os.OpenFile]. The O_ prefix is used to indicate
// that these flags are specific to the OpenFile function.
const (
O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL
O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT
O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE
O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS
O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS
O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE
O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN
O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS
O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING
O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED
O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH
)
const (
FILE_READ_DATA = 0x00000001
FILE_READ_ATTRIBUTES = 0x00000080
@@ -1976,6 +1992,12 @@ const (
SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1
)
// FILE_ZERO_DATA_INFORMATION from winioctl.h
type FileZeroDataInformation struct {
FileOffset int64
BeyondFinalZero int64
}
const (
ComputerNameNetBIOS = 0
ComputerNameDnsHostname = 1
File diff suppressed because it is too large Load Diff
+2 -9
View File
@@ -427,13 +427,6 @@ type isolatingRunSequence struct {
func (i *isolatingRunSequence) Len() int { return len(i.indexes) }
func maxLevel(a, b level) level {
if a > b {
return a
}
return b
}
// Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types,
// either L or R, for each isolating run sequence.
func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence {
@@ -474,8 +467,8 @@ func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence {
indexes: indexes,
types: types,
level: level,
sos: typeForLevel(maxLevel(prevLevel, level)),
eos: typeForLevel(maxLevel(succLevel, level)),
sos: typeForLevel(max(prevLevel, level)),
eos: typeForLevel(max(succLevel, level)),
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Copyright 2009 The Go Authors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
* Neither the name of Google LLC nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
+24 -25
View File
@@ -52,6 +52,8 @@ func Every(interval time.Duration) Limit {
// or its associated context.Context is canceled.
//
// The methods AllowN, ReserveN, and WaitN consume n tokens.
//
// Limiter is safe for simultaneous use by multiple goroutines.
type Limiter struct {
mu sync.Mutex
limit Limit
@@ -83,7 +85,7 @@ func (lim *Limiter) Burst() int {
// TokensAt returns the number of tokens available at time t.
func (lim *Limiter) TokensAt(t time.Time) float64 {
lim.mu.Lock()
_, tokens := lim.advance(t) // does not mutate lim
tokens := lim.advance(t) // does not mutate lim
lim.mu.Unlock()
return tokens
}
@@ -97,8 +99,9 @@ func (lim *Limiter) Tokens() float64 {
// bursts of at most b tokens.
func NewLimiter(r Limit, b int) *Limiter {
return &Limiter{
limit: r,
burst: b,
limit: r,
burst: b,
tokens: float64(b),
}
}
@@ -183,7 +186,7 @@ func (r *Reservation) CancelAt(t time.Time) {
return
}
// advance time to now
t, tokens := r.lim.advance(t)
tokens := r.lim.advance(t)
// calculate new number of tokens
tokens += restoreTokens
if burst := float64(r.lim.burst); tokens > burst {
@@ -192,7 +195,7 @@ func (r *Reservation) CancelAt(t time.Time) {
// update state
r.lim.last = t
r.lim.tokens = tokens
if r.timeToAct == r.lim.lastEvent {
if r.timeToAct.Equal(r.lim.lastEvent) {
prevEvent := r.timeToAct.Add(r.limit.durationFromTokens(float64(-r.tokens)))
if !prevEvent.Before(t) {
r.lim.lastEvent = prevEvent
@@ -304,7 +307,7 @@ func (lim *Limiter) SetLimitAt(t time.Time, newLimit Limit) {
lim.mu.Lock()
defer lim.mu.Unlock()
t, tokens := lim.advance(t)
tokens := lim.advance(t)
lim.last = t
lim.tokens = tokens
@@ -321,7 +324,7 @@ func (lim *Limiter) SetBurstAt(t time.Time, newBurst int) {
lim.mu.Lock()
defer lim.mu.Unlock()
t, tokens := lim.advance(t)
tokens := lim.advance(t)
lim.last = t
lim.tokens = tokens
@@ -342,21 +345,9 @@ func (lim *Limiter) reserveN(t time.Time, n int, maxFutureReserve time.Duration)
tokens: n,
timeToAct: t,
}
} else if lim.limit == 0 {
var ok bool
if lim.burst >= n {
ok = true
lim.burst -= n
}
return Reservation{
ok: ok,
lim: lim,
tokens: lim.burst,
timeToAct: t,
}
}
t, tokens := lim.advance(t)
tokens := lim.advance(t)
// Calculate the remaining number of tokens resulting from the request.
tokens -= float64(n)
@@ -389,10 +380,11 @@ func (lim *Limiter) reserveN(t time.Time, n int, maxFutureReserve time.Duration)
return r
}
// advance calculates and returns an updated state for lim resulting from the passage of time.
// advance calculates and returns an updated number of tokens for lim
// resulting from the passage of time.
// lim is not changed.
// advance requires that lim.mu is held.
func (lim *Limiter) advance(t time.Time) (newT time.Time, newTokens float64) {
func (lim *Limiter) advance(t time.Time) (newTokens float64) {
last := lim.last
if t.Before(last) {
last = t
@@ -405,7 +397,7 @@ func (lim *Limiter) advance(t time.Time) (newT time.Time, newTokens float64) {
if burst := float64(lim.burst); tokens > burst {
tokens = burst
}
return t, tokens
return tokens
}
// durationFromTokens is a unit conversion function from the number of tokens to the duration
@@ -414,8 +406,15 @@ func (limit Limit) durationFromTokens(tokens float64) time.Duration {
if limit <= 0 {
return InfDuration
}
seconds := tokens / float64(limit)
return time.Duration(float64(time.Second) * seconds)
duration := (tokens / float64(limit)) * float64(time.Second)
// Cap the duration to the maximum representable int64 value, to avoid overflow.
if duration > float64(math.MaxInt64) {
return InfDuration
}
return time.Duration(duration)
}
// tokensFromDuration is a unit conversion function from a time duration to the number of tokens
+3 -1
View File
@@ -61,7 +61,9 @@ func (s *Sometimes) Do(f func()) {
(s.Every > 0 && s.count%s.Every == 0) ||
(s.Interval > 0 && time.Since(s.last) >= s.Interval) {
f()
s.last = time.Now()
if s.Interval > 0 {
s.last = time.Now()
}
}
s.count++
}
-6
View File
@@ -364,12 +364,6 @@ type jsonPackage struct {
DepsErrors []*packagesinternal.PackageError
}
type jsonPackageError struct {
ImportStack []string
Pos string
Err string
}
func otherFiles(p *jsonPackage) [][]string {
return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
}
+75 -10
View File
@@ -5,9 +5,11 @@
package packages
import (
"cmp"
"fmt"
"iter"
"os"
"sort"
"slices"
)
// Visit visits all the packages in the import graph whose roots are
@@ -16,6 +18,20 @@ import (
// package's dependencies have been visited (postorder).
// The boolean result of pre(pkg) determines whether
// the imports of package pkg are visited.
//
// Example:
//
// pkgs, err := Load(...)
// if err != nil { ... }
// Visit(pkgs, nil, func(pkg *Package) {
// log.Println(pkg)
// })
//
// In most cases, it is more convenient to use [Postorder]:
//
// for pkg := range Postorder(pkgs) {
// log.Println(pkg)
// }
func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
seen := make(map[*Package]bool)
var visit func(*Package)
@@ -24,13 +40,8 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
seen[pkg] = true
if pre == nil || pre(pkg) {
paths := make([]string, 0, len(pkg.Imports))
for path := range pkg.Imports {
paths = append(paths, path)
}
sort.Strings(paths) // Imports is a map, this makes visit stable
for _, path := range paths {
visit(pkg.Imports[path])
for _, imp := range sorted(pkg.Imports) { // for determinism
visit(imp)
}
}
@@ -50,7 +61,7 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
func PrintErrors(pkgs []*Package) int {
var n int
errModules := make(map[*Module]bool)
Visit(pkgs, nil, func(pkg *Package) {
for pkg := range Postorder(pkgs) {
for _, err := range pkg.Errors {
fmt.Fprintln(os.Stderr, err)
n++
@@ -63,6 +74,60 @@ func PrintErrors(pkgs []*Package) int {
fmt.Fprintln(os.Stderr, mod.Error.Err)
n++
}
})
}
return n
}
// Postorder returns an iterator over the the packages in
// the import graph whose roots are pkg.
// Packages are enumerated in dependencies-first order.
func Postorder(pkgs []*Package) iter.Seq[*Package] {
return func(yield func(*Package) bool) {
seen := make(map[*Package]bool)
var visit func(*Package) bool
visit = func(pkg *Package) bool {
if !seen[pkg] {
seen[pkg] = true
for _, imp := range sorted(pkg.Imports) { // for determinism
if !visit(imp) {
return false
}
}
if !yield(pkg) {
return false
}
}
return true
}
for _, pkg := range pkgs {
if !visit(pkg) {
break
}
}
}
}
// -- copied from golang.org.x/tools/gopls/internal/util/moremaps --
// sorted returns an iterator over the entries of m in key order.
func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
// TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
return func(yield func(K, V) bool) {
keys := keySlice(m)
slices.Sort(keys)
for _, k := range keys {
if !yield(k, m[k]) {
break
}
}
}
}
// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
func keySlice[M ~map[K]V, K comparable, V any](m M) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}
+4 -1
View File
@@ -698,7 +698,10 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
} else if false && aliases.Enabled() {
// The Enabled check is too expensive, so for now we
// simply assume that aliases are not enabled.
// TODO(adonovan): replace with "if true {" when go1.24 is assured.
//
// Now that go1.24 is assured, we should be able to
// replace this with "if true {", but it causes tests
// to fail. TODO(adonovan): investigate.
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t)
}
+2 -17
View File
@@ -11,7 +11,6 @@ import (
"fmt"
"go/types"
"hash/maphash"
"unsafe"
"golang.org/x/tools/internal/typeparams"
)
@@ -380,22 +379,8 @@ var theSeed = maphash.MakeSeed()
func (hasher) hashTypeName(tname *types.TypeName) uint32 {
// Since types.Identical uses == to compare TypeNames,
// the Hash function uses maphash.Comparable.
// TODO(adonovan): or will, when it becomes available in go1.24.
// In the meantime we use the pointer's numeric value.
//
// hash := maphash.Comparable(theSeed, tname)
//
// (Another approach would be to hash the name and package
// path, and whether or not it is a package-level typename. It
// is rare for a package to define multiple local types with
// the same name.)
ptr := uintptr(unsafe.Pointer(tname))
if unsafe.Sizeof(ptr) == 8 {
hash := uint64(ptr)
return uint32(hash ^ (hash >> 32))
} else {
return uint32(ptr)
}
hash := maphash.Comparable(theSeed, tname)
return uint32(hash ^ (hash >> 32))
}
// shallowHash computes a hash of t without looking at any of its
-5
View File
@@ -28,11 +28,6 @@ type Event struct {
dynamic []label.Label // dynamically sized storage for remaining labels
}
// eventLabelMap implements label.Map for a the labels of an Event.
type eventLabelMap struct {
event Event
}
func (ev Event) At() time.Time { return ev.at }
func (ev Event) Format(f fmt.State, r rune) {
-1
View File
@@ -569,7 +569,6 @@ func (p *iexporter) exportName(obj types.Object) (res string) {
type iexporter struct {
fset *token.FileSet
out *bytes.Buffer
version int
shallow bool // don't put types from other packages in the index
-53
View File
@@ -1,53 +0,0 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.22 && !go1.24
package gcimporter
import (
"go/token"
"go/types"
"unsafe"
)
// TODO(rfindley): delete this workaround once go1.24 is assured.
func init() {
// Update markBlack so that it correctly sets the color
// of imported TypeNames.
//
// See the doc comment for markBlack for details.
type color uint32
const (
white color = iota
black
grey
)
type object struct {
_ *types.Scope
_ token.Pos
_ *types.Package
_ string
_ types.Type
_ uint32
color_ color
_ token.Pos
}
type typeName struct {
object
}
// If the size of types.TypeName changes, this will fail to compile.
const delta = int64(unsafe.Sizeof(typeName{})) - int64(unsafe.Sizeof(types.TypeName{}))
var _ [-delta * delta]int
markBlack = func(obj *types.TypeName) {
type uP = unsafe.Pointer
var ptr *typeName
*(*uP)(uP(&ptr)) = uP(obj)
ptr.color_ = black
}
}
+301 -295
View File
@@ -12,348 +12,354 @@ type pkginfo struct {
}
var deps = [...]pkginfo{
{"archive/tar", "\x03j\x03E5\x01\v\x01#\x01\x01\x02\x05\n\x02\x01\x02\x02\v"},
{"archive/zip", "\x02\x04`\a\x16\x0205\x01+\x05\x01\x11\x03\x02\r\x04"},
{"bufio", "\x03j}F\x13"},
{"bytes", "m+R\x03\fH\x02\x02"},
{"archive/tar", "\x03k\x03E;\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\f"},
{"archive/zip", "\x02\x04a\a\x03\x12\x021;\x01+\x05\x01\x0f\x03\x02\x0e\x04"},
{"bufio", "\x03k\x83\x01D\x14"},
{"bytes", "n*Y\x03\fG\x02\x02"},
{"cmp", ""},
{"compress/bzip2", "\x02\x02\xe6\x01C"},
{"compress/flate", "\x02k\x03z\r\x025\x01\x03"},
{"compress/gzip", "\x02\x04`\a\x03\x15eU"},
{"compress/lzw", "\x02k\x03z"},
{"compress/zlib", "\x02\x04`\a\x03\x13\x01f"},
{"container/heap", "\xae\x02"},
{"compress/bzip2", "\x02\x02\xed\x01A"},
{"compress/flate", "\x02l\x03\x80\x01\f\x033\x01\x03"},
{"compress/gzip", "\x02\x04a\a\x03\x14lT"},
{"compress/lzw", "\x02l\x03\x80\x01"},
{"compress/zlib", "\x02\x04a\a\x03\x12\x01m"},
{"container/heap", "\xb3\x02"},
{"container/list", ""},
{"container/ring", ""},
{"context", "m\\i\x01\f"},
{"crypto", "\x83\x01gE"},
{"crypto/aes", "\x10\n\a\x8e\x02"},
{"crypto/cipher", "\x03\x1e\x01\x01\x1d\x11\x1c,Q"},
{"crypto/des", "\x10\x13\x1d-,\x96\x01\x03"},
{"crypto/dsa", "@\x04)}\x0e"},
{"crypto/ecdh", "\x03\v\f\x0e\x04\x14\x04\r\x1c}"},
{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\x16\x01\x04\f\x01\x1c}\x0e\x04L\x01"},
{"crypto/ed25519", "\x0e\x1c\x16\n\a\x1c}E"},
{"crypto/elliptic", "0=}\x0e:"},
{"crypto/fips140", " \x05\x90\x01"},
{"crypto/hkdf", "-\x12\x01-\x16"},
{"crypto/hmac", "\x1a\x14\x11\x01\x112"},
{"context", "n\\m\x01\r"},
{"crypto", "\x83\x01nC"},
{"crypto/aes", "\x10\n\a\x93\x02"},
{"crypto/cipher", "\x03\x1e\x01\x01\x1e\x11\x1c+X"},
{"crypto/des", "\x10\x13\x1e-+\x9b\x01\x03"},
{"crypto/dsa", "A\x04)\x83\x01\r"},
{"crypto/ecdh", "\x03\v\f\x0e\x04\x15\x04\r\x1c\x83\x01"},
{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\a\v\x05\x01\x04\f\x01\x1c\x83\x01\r\x05K\x01"},
{"crypto/ed25519", "\x0e\x1c\x11\x06\n\a\x1c\x83\x01C"},
{"crypto/elliptic", "0>\x83\x01\r9"},
{"crypto/fips140", " \x05"},
{"crypto/hkdf", "-\x13\x01-\x15"},
{"crypto/hmac", "\x1a\x14\x12\x01\x111"},
{"crypto/internal/boring", "\x0e\x02\rf"},
{"crypto/internal/boring/bbig", "\x1a\xde\x01M"},
{"crypto/internal/boring/bcache", "\xb3\x02\x12"},
{"crypto/internal/boring/bbig", "\x1a\xe4\x01M"},
{"crypto/internal/boring/bcache", "\xb8\x02\x13"},
{"crypto/internal/boring/sig", ""},
{"crypto/internal/cryptotest", "\x03\r\n)\x0e\x19\x06\x13\x12#\a\t\x11\x11\x11\x1b\x01\f\r\x05\n"},
{"crypto/internal/entropy", "E"},
{"crypto/internal/fips140", ">/}9\r\x15"},
{"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x04\x01\x01\x05*\x8c\x016"},
{"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x04\x01\x06*\x8a\x01"},
{"crypto/internal/fips140/alias", "\xc5\x02"},
{"crypto/internal/fips140/bigmod", "%\x17\x01\x06*\x8c\x01"},
{"crypto/internal/fips140/check", " \x0e\x06\b\x02\xac\x01["},
{"crypto/internal/fips140/check/checktest", "%\xfe\x01\""},
{"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x04\b\x01(}\x0f9"},
{"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\f1}\x0f9"},
{"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x067}H"},
{"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v7\xc2\x01\x03"},
{"crypto/internal/fips140/edwards25519", "%\a\f\x041\x8c\x019"},
{"crypto/internal/fips140/edwards25519/field", "%\x13\x041\x8c\x01"},
{"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x069"},
{"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x017"},
{"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x041"},
{"crypto/internal/fips140/nistec", "%\f\a\x041\x8c\x01*\x0f\x13"},
{"crypto/internal/fips140/nistec/fiat", "%\x135\x8c\x01"},
{"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x069"},
{"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x025}H"},
{"crypto/internal/fips140/sha256", "\x03\x1d\x1c\x01\x06*\x8c\x01"},
{"crypto/internal/fips140/sha3", "\x03\x1d\x18\x04\x010\x8c\x01L"},
{"crypto/internal/fips140/sha512", "\x03\x1d\x1c\x01\x06*\x8c\x01"},
{"crypto/internal/fips140/ssh", " \x05"},
{"crypto/internal/fips140/subtle", "#"},
{"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x027"},
{"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\b1"},
{"crypto/internal/cryptotest", "\x03\r\n\x06$\x0e\x19\x06\x12\x12 \x04\a\t\x16\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\v"},
{"crypto/internal/entropy", "F"},
{"crypto/internal/fips140", "?/\x15\xa7\x01\v\x16"},
{"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x05\x01\x01\x05*\x92\x014"},
{"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x05\x01\x06*\x8f\x01"},
{"crypto/internal/fips140/alias", "\xcb\x02"},
{"crypto/internal/fips140/bigmod", "%\x18\x01\x06*\x92\x01"},
{"crypto/internal/fips140/check", " \x0e\x06\t\x02\xb2\x01Z"},
{"crypto/internal/fips140/check/checktest", "%\x85\x02!"},
{"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x05\b\x01(\x83\x01\x0f7"},
{"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\r1\x83\x01\x0f7"},
{"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x068\x15nF"},
{"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v8\xc6\x01\x03"},
{"crypto/internal/fips140/edwards25519", "%\a\f\x051\x92\x017"},
{"crypto/internal/fips140/edwards25519/field", "%\x13\x051\x92\x01"},
{"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x06:\x15"},
{"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x018\x15"},
{"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x051"},
{"crypto/internal/fips140/nistec", "%\f\a\x051\x92\x01*\r\x14"},
{"crypto/internal/fips140/nistec/fiat", "%\x136\x92\x01"},
{"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x06:\x15"},
{"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x026\x15nF"},
{"crypto/internal/fips140/sha256", "\x03\x1d\x1d\x01\x06*\x15}"},
{"crypto/internal/fips140/sha3", "\x03\x1d\x18\x05\x010\x92\x01K"},
{"crypto/internal/fips140/sha512", "\x03\x1d\x1d\x01\x06*\x15}"},
{"crypto/internal/fips140/ssh", "%^"},
{"crypto/internal/fips140/subtle", "#\x1a\xc3\x01"},
{"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x028\x15"},
{"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\t1\x15"},
{"crypto/internal/fips140cache", "\xaa\x02\r&"},
{"crypto/internal/fips140deps", ""},
{"crypto/internal/fips140deps/byteorder", "\x99\x01"},
{"crypto/internal/fips140deps/cpu", "\xad\x01\a"},
{"crypto/internal/fips140deps/godebug", "\xb5\x01"},
{"crypto/internal/fips140hash", "5\x1a4\xc2\x01"},
{"crypto/internal/fips140only", "'\r\x01\x01M25"},
{"crypto/internal/fips140deps/cpu", "\xae\x01\a"},
{"crypto/internal/fips140deps/godebug", "\xb6\x01"},
{"crypto/internal/fips140hash", "5\x1b3\xc8\x01"},
{"crypto/internal/fips140only", "'\r\x01\x01M3;"},
{"crypto/internal/fips140test", ""},
{"crypto/internal/hpke", "\x0e\x01\x01\x03\x1a\x1d#,`N"},
{"crypto/internal/impl", "\xb0\x02"},
{"crypto/internal/randutil", "\xea\x01\x12"},
{"crypto/internal/sysrand", "mi!\x1f\r\x0f\x01\x01\v\x06"},
{"crypto/internal/sysrand/internal/seccomp", "m"},
{"crypto/md5", "\x0e2-\x16\x16`"},
{"crypto/internal/hpke", "\x0e\x01\x01\x03\x053#+gM"},
{"crypto/internal/impl", "\xb5\x02"},
{"crypto/internal/randutil", "\xf1\x01\x12"},
{"crypto/internal/sysrand", "nn! \r\r\x01\x01\f\x06"},
{"crypto/internal/sysrand/internal/seccomp", "n"},
{"crypto/md5", "\x0e3-\x15\x16g"},
{"crypto/mlkem", "/"},
{"crypto/pbkdf2", "2\r\x01-\x16"},
{"crypto/rand", "\x1a\x06\a\x19\x04\x01(}\x0eM"},
{"crypto/rc4", "#\x1d-\xc2\x01"},
{"crypto/rsa", "\x0e\f\x01\t\x0f\f\x01\x04\x06\a\x1c\x03\x1325\r\x01"},
{"crypto/sha1", "\x0e\f&-\x16\x16\x14L"},
{"crypto/pbkdf2", "2\x0e\x01-\x15"},
{"crypto/rand", "\x1a\x06\a\x1a\x04\x01(\x83\x01\rM"},
{"crypto/rc4", "#\x1e-\xc6\x01"},
{"crypto/rsa", "\x0e\f\x01\t\x0f\r\x01\x04\x06\a\x1c\x03\x123;\f\x01"},
{"crypto/sha1", "\x0e\f'\x03*\x15\x16\x15R"},
{"crypto/sha256", "\x0e\f\x1aO"},
{"crypto/sha3", "\x0e'N\xc2\x01"},
{"crypto/sha3", "\x0e'N\xc8\x01"},
{"crypto/sha512", "\x0e\f\x1cM"},
{"crypto/subtle", "8\x96\x01U"},
{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x03\x01\a\x01\v\x02\n\x01\b\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x14\b5\x16\x16\r\n\x01\x01\x01\x02\x01\f\x06\x02\x01"},
{"crypto/tls/internal/fips140tls", " \x93\x02"},
{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x011\x03\x02\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x032\x01\x02\t\x01\x01\x01\a\x10\x05\x01\x06\x02\x05\f\x01\x02\r\x02\x01\x01\x02\x03\x01"},
{"crypto/x509/pkix", "c\x06\a\x88\x01G"},
{"database/sql", "\x03\nJ\x16\x03z\f\x06\"\x05\n\x02\x03\x01\f\x02\x02\x02"},
{"database/sql/driver", "\r`\x03\xae\x01\x11\x10"},
{"debug/buildinfo", "\x03W\x02\x01\x01\b\a\x03`\x18\x02\x01+\x0f "},
{"debug/dwarf", "\x03c\a\x03z1\x13\x01\x01"},
{"debug/elf", "\x03\x06P\r\a\x03`\x19\x01,\x19\x01\x15"},
{"debug/gosym", "\x03c\n\xbe\x01\x01\x01\x02"},
{"debug/macho", "\x03\x06P\r\n`\x1a,\x19\x01"},
{"debug/pe", "\x03\x06P\r\a\x03`\x1a,\x19\x01\x15"},
{"debug/plan9obj", "f\a\x03`\x1a,"},
{"embed", "m+:\x18\x01T"},
{"crypto/subtle", "8\x9b\x01W"},
{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\a\x01\r\n\x01\t\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x12\x16\x15\b;\x16\x16\r\b\x01\x01\x01\x02\x01\r\x06\x02\x01\x0f"},
{"crypto/tls/internal/fips140tls", "\x17\xa1\x02"},
{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x012\x05\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x038\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\x02\x05\n\x01\x02\x0e\x02\x01\x01\x02\x03\x01"},
{"crypto/x509/pkix", "d\x06\a\x8d\x01G"},
{"database/sql", "\x03\nK\x16\x03\x80\x01\v\a\"\x05\b\x02\x03\x01\r\x02\x02\x02"},
{"database/sql/driver", "\ra\x03\xb4\x01\x0f\x11"},
{"debug/buildinfo", "\x03X\x02\x01\x01\b\a\x03e\x19\x02\x01+\x0f\x1f"},
{"debug/dwarf", "\x03d\a\x03\x80\x011\x11\x01\x01"},
{"debug/elf", "\x03\x06Q\r\a\x03e\x1a\x01,\x17\x01\x16"},
{"debug/gosym", "\x03d\n\xc2\x01\x01\x01\x02"},
{"debug/macho", "\x03\x06Q\r\ne\x1b,\x17\x01"},
{"debug/pe", "\x03\x06Q\r\a\x03e\x1b,\x17\x01\x16"},
{"debug/plan9obj", "g\a\x03e\x1b,"},
{"embed", "n*@\x19\x01S"},
{"embed/internal/embedtest", ""},
{"encoding", ""},
{"encoding/ascii85", "\xea\x01E"},
{"encoding/asn1", "\x03j\x03\x87\x01\x01&\x0f\x02\x01\x0f\x03\x01"},
{"encoding/base32", "\xea\x01C\x02"},
{"encoding/base64", "\x99\x01QC\x02"},
{"encoding/binary", "m}\r'\x0f\x05"},
{"encoding/csv", "\x02\x01j\x03zF\x11\x02"},
{"encoding/gob", "\x02_\x05\a\x03`\x1a\f\x01\x02\x1d\b\x14\x01\x0e\x02"},
{"encoding/hex", "m\x03zC\x03"},
{"encoding/json", "\x03\x01]\x04\b\x03z\r'\x0f\x02\x01\x02\x0f\x01\x01\x02"},
{"encoding/pem", "\x03b\b}C\x03"},
{"encoding/xml", "\x02\x01^\f\x03z4\x05\f\x01\x02\x0f\x02"},
{"errors", "\xc9\x01|"},
{"expvar", "jK9\t\n\x15\r\n\x02\x03\x01\x10"},
{"flag", "a\f\x03z,\b\x05\n\x02\x01\x0f"},
{"fmt", "mE8\r\x1f\b\x0f\x02\x03\x11"},
{"go/ast", "\x03\x01l\x0f\x01j\x03)\b\x0f\x02\x01"},
{"go/ast/internal/tests", ""},
{"go/build", "\x02\x01j\x03\x01\x03\x02\a\x02\x01\x17\x1e\x04\x02\t\x14\x12\x01+\x01\x04\x01\a\n\x02\x01\x11\x02\x02"},
{"go/build/constraint", "m\xc2\x01\x01\x11\x02"},
{"go/constant", "p\x10w\x01\x016\x01\x02\x11"},
{"go/doc", "\x04l\x01\x06\t=-1\x12\x02\x01\x11\x02"},
{"go/doc/comment", "\x03m\xbd\x01\x01\x01\x01\x11\x02"},
{"go/format", "\x03m\x01\f\x01\x02jF"},
{"go/importer", "s\a\x01\x01\x04\x01i9"},
{"go/internal/gccgoimporter", "\x02\x01W\x13\x03\x05\v\x01g\x02,\x01\x05\x13\x01\v\b"},
{"go/internal/gcimporter", "\x02n\x10\x01/\x05\x0e',\x17\x03\x02"},
{"go/internal/srcimporter", "p\x01\x02\n\x03\x01i,\x01\x05\x14\x02\x13"},
{"go/parser", "\x03j\x03\x01\x03\v\x01j\x01+\x06\x14"},
{"go/printer", "p\x01\x03\x03\tj\r\x1f\x17\x02\x01\x02\n\x05\x02"},
{"go/scanner", "\x03m\x10j2\x12\x01\x12\x02"},
{"go/token", "\x04l\xbd\x01\x02\x03\x01\x0e\x02"},
{"go/types", "\x03\x01\x06c\x03\x01\x04\b\x03\x02\x15\x1e\x06+\x04\x03\n%\a\n\x01\x01\x01\x02\x01\x0e\x02\x02"},
{"go/version", "\xba\x01v"},
{"hash", "\xea\x01"},
{"hash/adler32", "m\x16\x16"},
{"hash/crc32", "m\x16\x16\x14\x85\x01\x01\x12"},
{"hash/crc64", "m\x16\x16\x99\x01"},
{"hash/fnv", "m\x16\x16`"},
{"hash/maphash", "\x94\x01\x05\x1b\x03@N"},
{"html", "\xb0\x02\x02\x11"},
{"html/template", "\x03g\x06\x19,5\x01\v \x05\x01\x02\x03\x0e\x01\x02\v\x01\x03\x02"},
{"image", "\x02k\x1f^\x0f6\x03\x01"},
{"encoding/ascii85", "\xf1\x01C"},
{"encoding/asn1", "\x03k\x03\x8c\x01\x01'\r\x02\x01\x10\x03\x01"},
{"encoding/base32", "\xf1\x01A\x02"},
{"encoding/base64", "\x99\x01XA\x02"},
{"encoding/binary", "n\x83\x01\f(\r\x05"},
{"encoding/csv", "\x02\x01k\x03\x80\x01D\x12\x02"},
{"encoding/gob", "\x02`\x05\a\x03e\x1b\v\x01\x03\x1d\b\x12\x01\x0f\x02"},
{"encoding/hex", "n\x03\x80\x01A\x03"},
{"encoding/json", "\x03\x01^\x04\b\x03\x80\x01\f(\r\x02\x01\x02\x10\x01\x01\x02"},
{"encoding/pem", "\x03c\b\x83\x01A\x03"},
{"encoding/xml", "\x02\x01_\f\x03\x80\x014\x05\n\x01\x02\x10\x02"},
{"errors", "\xca\x01\x81\x01"},
{"expvar", "kK?\b\v\x15\r\b\x02\x03\x01\x11"},
{"flag", "b\f\x03\x80\x01,\b\x05\b\x02\x01\x10"},
{"fmt", "nE>\f \b\r\x02\x03\x12"},
{"go/ast", "\x03\x01m\x0e\x01q\x03)\b\r\x02\x01"},
{"go/build", "\x02\x01k\x03\x01\x02\x02\a\x02\x01\x17\x1f\x04\x02\t\x19\x13\x01+\x01\x04\x01\a\b\x02\x01\x12\x02\x02"},
{"go/build/constraint", "n\xc6\x01\x01\x12\x02"},
{"go/constant", "q\x0f}\x01\x024\x01\x02\x12"},
{"go/doc", "\x04m\x01\x05\t>31\x10\x02\x01\x12\x02"},
{"go/doc/comment", "\x03n\xc1\x01\x01\x01\x01\x12\x02"},
{"go/format", "\x03n\x01\v\x01\x02qD"},
{"go/importer", "s\a\x01\x01\x04\x01p9"},
{"go/internal/gccgoimporter", "\x02\x01X\x13\x03\x04\v\x01n\x02,\x01\x05\x11\x01\f\b"},
{"go/internal/gcimporter", "\x02o\x0f\x010\x05\x0e-,\x15\x03\x02"},
{"go/internal/srcimporter", "q\x01\x01\n\x03\x01p,\x01\x05\x12\x02\x14"},
{"go/parser", "\x03k\x03\x01\x02\v\x01q\x01+\x06\x12"},
{"go/printer", "q\x01\x02\x03\tq\f \x15\x02\x01\x02\v\x05\x02"},
{"go/scanner", "\x03n\x0fq2\x10\x01\x13\x02"},
{"go/token", "\x04m\x83\x01>\x02\x03\x01\x0f\x02"},
{"go/types", "\x03\x01\x06d\x03\x01\x03\b\x03\x02\x15\x1f\x061\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x0f\x02\x02"},
{"go/version", "\xbb\x01z"},
{"hash", "\xf1\x01"},
{"hash/adler32", "n\x15\x16"},
{"hash/crc32", "n\x15\x16\x15\x89\x01\x01\x13"},
{"hash/crc64", "n\x15\x16\x9e\x01"},
{"hash/fnv", "n\x15\x16g"},
{"hash/maphash", "\x83\x01\x11!\x03\x93\x01"},
{"html", "\xb5\x02\x02\x12"},
{"html/template", "\x03h\x06\x18-;\x01\n!\x05\x01\x02\x03\f\x01\x02\f\x01\x03\x02"},
{"image", "\x02l\x1ee\x0f4\x03\x01"},
{"image/color", ""},
{"image/color/palette", "\x8c\x01"},
{"image/draw", "\x8b\x01\x01\x04"},
{"image/gif", "\x02\x01\x05e\x03\x1b\x01\x01\x01\vQ"},
{"image/gif", "\x02\x01\x05f\x03\x1a\x01\x01\x01\vX"},
{"image/internal/imageutil", "\x8b\x01"},
{"image/jpeg", "\x02k\x1e\x01\x04Z"},
{"image/png", "\x02\a]\n\x13\x02\x06\x01^E"},
{"index/suffixarray", "\x03c\a}\r*\f\x01"},
{"internal/abi", "\xb4\x01\x91\x01"},
{"internal/asan", "\xc5\x02"},
{"internal/bisect", "\xa3\x02\x0f\x01"},
{"internal/buildcfg", "pG_\x06\x02\x05\f\x01"},
{"internal/bytealg", "\xad\x01\x98\x01"},
{"image/jpeg", "\x02l\x1d\x01\x04a"},
{"image/png", "\x02\a^\n\x12\x02\x06\x01eC"},
{"index/suffixarray", "\x03d\a\x83\x01\f+\n\x01"},
{"internal/abi", "\xb5\x01\x96\x01"},
{"internal/asan", "\xcb\x02"},
{"internal/bisect", "\xaa\x02\r\x01"},
{"internal/buildcfg", "qGe\x06\x02\x05\n\x01"},
{"internal/bytealg", "\xae\x01\x9d\x01"},
{"internal/byteorder", ""},
{"internal/cfg", ""},
{"internal/chacha8rand", "\x99\x01\x1b\x91\x01"},
{"internal/cgrouptest", "q[Q\x06\x0f\x02\x01\x04\x01"},
{"internal/chacha8rand", "\x99\x01\x15\a\x96\x01"},
{"internal/copyright", ""},
{"internal/coverage", ""},
{"internal/coverage/calloc", ""},
{"internal/coverage/cfile", "j\x06\x17\x16\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x01\x1f,\x06\a\f\x01\x03\f\x06"},
{"internal/coverage/cformat", "\x04l-\x04I\f7\x01\x02\f"},
{"internal/coverage/cmerge", "p-Z"},
{"internal/coverage/decodecounter", "f\n-\v\x02@,\x19\x16"},
{"internal/coverage/decodemeta", "\x02d\n\x17\x16\v\x02@,"},
{"internal/coverage/encodecounter", "\x02d\n-\f\x01\x02>\f \x17"},
{"internal/coverage/encodemeta", "\x02\x01c\n\x13\x04\x16\r\x02>,/"},
{"internal/coverage/pods", "\x04l-y\x06\x05\f\x02\x01"},
{"internal/coverage/rtcov", "\xc5\x02"},
{"internal/coverage/slicereader", "f\nz["},
{"internal/coverage/slicewriter", "pz"},
{"internal/coverage/stringtab", "p8\x04>"},
{"internal/coverage/cfile", "k\x06\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x02$,\x06\a\n\x01\x03\r\x06"},
{"internal/coverage/cformat", "\x04m-\x04O\v6\x01\x02\r"},
{"internal/coverage/cmerge", "q-_"},
{"internal/coverage/decodecounter", "g\n-\v\x02F,\x17\x17"},
{"internal/coverage/decodemeta", "\x02e\n\x16\x17\v\x02F,"},
{"internal/coverage/encodecounter", "\x02e\n-\f\x01\x02D\v!\x15"},
{"internal/coverage/encodemeta", "\x02\x01d\n\x12\x04\x17\r\x02D,."},
{"internal/coverage/pods", "\x04m-\x7f\x06\x05\n\x02\x01"},
{"internal/coverage/rtcov", "\xcb\x02"},
{"internal/coverage/slicereader", "g\n\x80\x01Z"},
{"internal/coverage/slicewriter", "q\x80\x01"},
{"internal/coverage/stringtab", "q8\x04D"},
{"internal/coverage/test", ""},
{"internal/coverage/uleb128", ""},
{"internal/cpu", "\xc5\x02"},
{"internal/dag", "\x04l\xbd\x01\x03"},
{"internal/diff", "\x03m\xbe\x01\x02"},
{"internal/exportdata", "\x02\x01j\x03\x03]\x1a,\x01\x05\x13\x01\x02"},
{"internal/filepathlite", "m+:\x19B"},
{"internal/fmtsort", "\x04\x9a\x02\x0f"},
{"internal/fuzz", "\x03\nA\x18\x04\x03\x03\x01\f\x0355\r\x02\x1d\x01\x05\x02\x05\f\x01\x02\x01\x01\v\x04\x02"},
{"internal/cpu", "\xcb\x02"},
{"internal/dag", "\x04m\xc1\x01\x03"},
{"internal/diff", "\x03n\xc2\x01\x02"},
{"internal/exportdata", "\x02\x01k\x03\x02c\x1b,\x01\x05\x11\x01\x02"},
{"internal/filepathlite", "n*@\x1a@"},
{"internal/fmtsort", "\x04\xa1\x02\r"},
{"internal/fuzz", "\x03\nB\x18\x04\x03\x03\x01\v\x036;\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\f\x04\x02"},
{"internal/goarch", ""},
{"internal/godebug", "\x96\x01 |\x01\x12"},
{"internal/godebug", "\x96\x01!\x80\x01\x01\x13"},
{"internal/godebugs", ""},
{"internal/goexperiment", ""},
{"internal/goos", ""},
{"internal/goroot", "\x96\x02\x01\x05\x14\x02"},
{"internal/goroot", "\x9d\x02\x01\x05\x12\x02"},
{"internal/gover", "\x04"},
{"internal/goversion", ""},
{"internal/itoa", ""},
{"internal/lazyregexp", "\x96\x02\v\x0f\x02"},
{"internal/lazytemplate", "\xea\x01,\x1a\x02\v"},
{"internal/msan", "\xc5\x02"},
{"internal/lazyregexp", "\x9d\x02\v\r\x02"},
{"internal/lazytemplate", "\xf1\x01,\x18\x02\f"},
{"internal/msan", "\xcb\x02"},
{"internal/nettrace", ""},
{"internal/obscuretestdata", "e\x85\x01,"},
{"internal/oserror", "m"},
{"internal/pkgbits", "\x03K\x18\a\x03\x05\vj\x0e\x1e\r\f\x01"},
{"internal/obscuretestdata", "f\x8b\x01,"},
{"internal/oserror", "n"},
{"internal/pkgbits", "\x03L\x18\a\x03\x04\vq\r\x1f\r\n\x01"},
{"internal/platform", ""},
{"internal/poll", "mO\x1a\x149\x0f\x01\x01\v\x06"},
{"internal/profile", "\x03\x04f\x03z7\r\x01\x01\x0f"},
{"internal/poll", "nO\x1f\x159\r\x01\x01\f\x06"},
{"internal/profile", "\x03\x04g\x03\x80\x017\v\x01\x01\x10"},
{"internal/profilerecord", ""},
{"internal/race", "\x94\x01\xb1\x01"},
{"internal/reflectlite", "\x94\x01 3<\""},
{"internal/runtime/atomic", "\xc5\x02"},
{"internal/runtime/exithook", "\xca\x01{"},
{"internal/runtime/maps", "\x94\x01\x01\x1f\v\t\x05\x01w"},
{"internal/runtime/math", "\xb4\x01"},
{"internal/runtime/sys", "\xb4\x01\x04"},
{"internal/runtime/syscall", "\xc5\x02"},
{"internal/saferio", "\xea\x01["},
{"internal/singleflight", "\xb2\x02"},
{"internal/stringslite", "\x98\x01\xad\x01"},
{"internal/sync", "\x94\x01 \x14k\x12"},
{"internal/synctest", "\xc5\x02"},
{"internal/syscall/execenv", "\xb4\x02"},
{"internal/syscall/unix", "\xa3\x02\x10\x01\x11"},
{"internal/sysinfo", "\x02\x01\xaa\x01=,\x1a\x02"},
{"internal/race", "\x94\x01\xb7\x01"},
{"internal/reflectlite", "\x94\x01!9<!"},
{"internal/runtime/atomic", "\xb5\x01\x96\x01"},
{"internal/runtime/cgroup", "\x98\x01:\x02w"},
{"internal/runtime/exithook", "\xcb\x01\x80\x01"},
{"internal/runtime/gc", "\xb5\x01"},
{"internal/runtime/maps", "\x94\x01\x01 \v\t\a\x03x"},
{"internal/runtime/math", "\xb5\x01"},
{"internal/runtime/startlinetest", ""},
{"internal/runtime/strconv", "\xd0\x01"},
{"internal/runtime/sys", "\xb5\x01\x04"},
{"internal/runtime/syscall", "\xb5\x01\x96\x01"},
{"internal/runtime/wasitest", ""},
{"internal/saferio", "\xf1\x01Z"},
{"internal/singleflight", "\xb7\x02"},
{"internal/stringslite", "\x98\x01\xb3\x01"},
{"internal/sync", "\x94\x01!\x14o\x13"},
{"internal/synctest", "\x94\x01\xb7\x01"},
{"internal/syscall/execenv", "\xb9\x02"},
{"internal/syscall/unix", "\xaa\x02\x0e\x01\x12"},
{"internal/sysinfo", "\x02\x01\xab\x01C,\x18\x02"},
{"internal/syslist", ""},
{"internal/testenv", "\x03\n`\x02\x01*\x1a\x10'+\x01\x05\a\f\x01\x02\x02\x01\n"},
{"internal/testlog", "\xb2\x02\x01\x12"},
{"internal/testpty", "m\x03\xa6\x01"},
{"internal/trace", "\x02\x01\x01\x06\\\a\x03n\x03\x03\x06\x03\n6\x01\x02\x0f\x06"},
{"internal/trace/internal/testgen", "\x03c\nl\x03\x02\x03\x011\v\x0f"},
{"internal/trace/internal/tracev1", "\x03\x01b\a\x03t\x06\r6\x01"},
{"internal/trace/raw", "\x02d\nq\x03\x06E\x01\x11"},
{"internal/trace/testtrace", "\x02\x01j\x03l\x03\x06\x057\f\x02\x01"},
{"internal/testenv", "\x03\na\x02\x01)\x1b\x10-+\x01\x05\a\n\x01\x02\x02\x01\v"},
{"internal/testhash", "\x03\x80\x01n\x118\v"},
{"internal/testlog", "\xb7\x02\x01\x13"},
{"internal/testpty", "n\x03\xac\x01"},
{"internal/trace", "\x02\x01\x01\x06]\a\x03t\x03\x03\x06\x03\t5\x01\x01\x01\x10\x06"},
{"internal/trace/internal/testgen", "\x03d\nr\x03\x02\x03\x011\v\r\x10"},
{"internal/trace/internal/tracev1", "\x03\x01c\a\x03z\x06\f5\x01"},
{"internal/trace/raw", "\x02e\nw\x03\x06C\x01\x12"},
{"internal/trace/testtrace", "\x02\x01k\x03r\x03\x05\x01\x057\n\x02\x01"},
{"internal/trace/tracev2", ""},
{"internal/trace/traceviewer", "\x02]\v\x06\x1a<\x16\a\a\x04\t\n\x15\x01\x05\a\f\x01\x02\r"},
{"internal/trace/traceviewer", "\x02^\v\x06\x19=\x1c\a\a\x04\b\v\x15\x01\x05\a\n\x01\x02\x0e"},
{"internal/trace/traceviewer/format", ""},
{"internal/trace/version", "pq\t"},
{"internal/txtar", "\x03m\xa6\x01\x1a"},
{"internal/types/errors", "\xaf\x02"},
{"internal/unsafeheader", "\xc5\x02"},
{"internal/xcoff", "Y\r\a\x03`\x1a,\x19\x01"},
{"internal/zstd", "f\a\x03z\x0f"},
{"io", "m\xc5\x01"},
{"io/fs", "m+*(1\x12\x12\x04"},
{"io/ioutil", "\xea\x01\x01+\x17\x03"},
{"iter", "\xc8\x01[\""},
{"log", "pz\x05'\r\x0f\x01\f"},
{"internal/trace/version", "qw\t"},
{"internal/txtar", "\x03n\xac\x01\x18"},
{"internal/types/errors", "\xb4\x02"},
{"internal/unsafeheader", "\xcb\x02"},
{"internal/xcoff", "Z\r\a\x03e\x1b,\x17\x01"},
{"internal/zstd", "g\a\x03\x80\x01\x0f"},
{"io", "n\xc9\x01"},
{"io/fs", "n*+.1\x10\x13\x04"},
{"io/ioutil", "\xf1\x01\x01+\x15\x03"},
{"iter", "\xc9\x01a!"},
{"log", "q\x80\x01\x05'\r\r\x01\r"},
{"log/internal", ""},
{"log/slog", "\x03\nT\t\x03\x03z\x04\x01\x02\x02\x04'\x05\n\x02\x01\x02\x01\f\x02\x02\x02"},
{"log/slog", "\x03\nU\t\x03\x03\x80\x01\x04\x01\x02\x02\x03(\x05\b\x02\x01\x02\x01\r\x02\x02\x02"},
{"log/slog/internal", ""},
{"log/slog/internal/benchmarks", "\r`\x03z\x06\x03<\x10"},
{"log/slog/internal/buffer", "\xb2\x02"},
{"log/slog/internal/slogtest", "\xf0\x01"},
{"log/syslog", "m\x03~\x12\x16\x1a\x02\r"},
{"maps", "\xed\x01X"},
{"math", "\xad\x01LL"},
{"math/big", "\x03j\x03)\x14=\r\x02\x024\x01\x02\x13"},
{"math/bits", "\xc5\x02"},
{"math/cmplx", "\xf7\x01\x02"},
{"math/rand", "\xb5\x01B;\x01\x12"},
{"math/rand/v2", "m,\x02\\\x02L"},
{"mime", "\x02\x01b\b\x03z\f \x17\x03\x02\x0f\x02"},
{"mime/multipart", "\x02\x01G#\x03E5\f\x01\x06\x02\x15\x02\x06\x11\x02\x01\x15"},
{"mime/quotedprintable", "\x02\x01mz"},
{"net", "\x04\t`+\x1d\a\x04\x05\f\x01\x04\x14\x01%\x06\r\n\x05\x01\x01\v\x06\a"},
{"net/http", "\x02\x01\x04\x04\x02=\b\x13\x01\a\x03E5\x01\x03\b\x01\x02\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\n\x01\x01\x01\x02\x01\x01\v\x02\x02\x02\b\x01\x01\x01"},
{"net/http/cgi", "\x02P\x1b\x03z\x04\b\n\x01\x13\x01\x01\x01\x04\x01\x05\x02\n\x02\x01\x0f\x0e"},
{"net/http/cookiejar", "\x04i\x03\x90\x01\x01\b\f\x18\x03\x02\r\x04"},
{"net/http/fcgi", "\x02\x01\nY\a\x03z\x16\x01\x01\x14\x1a\x02\r"},
{"net/http/httptest", "\x02\x01\nE\x02\x1b\x01z\x04\x12\x01\n\t\x02\x19\x01\x02\r\x0e"},
{"net/http/httptrace", "\rEn@\x14\n!"},
{"net/http/httputil", "\x02\x01\n`\x03z\x04\x0f\x03\x01\x05\x02\x01\v\x01\x1b\x02\r\x0e"},
{"net/http/internal", "\x02\x01j\x03z"},
{"net/http/internal/ascii", "\xb0\x02\x11"},
{"net/http/internal/httpcommon", "\r`\x03\x96\x01\x0e\x01\x19\x01\x01\x02\x1b\x02"},
{"net/http/internal/testcert", "\xb0\x02"},
{"net/http/pprof", "\x02\x01\nc\x19,\x11$\x04\x13\x14\x01\r\x06\x03\x01\x02\x01\x0f"},
{"log/slog/internal/benchmarks", "\ra\x03\x80\x01\x06\x03:\x11"},
{"log/slog/internal/buffer", "\xb7\x02"},
{"log/syslog", "n\x03\x84\x01\x12\x16\x18\x02\x0e"},
{"maps", "\xf4\x01W"},
{"math", "\xae\x01RK"},
{"math/big", "\x03k\x03(\x15C\f\x03\x020\x02\x01\x02\x14"},
{"math/big/internal/asmgen", "\x03\x01m\x8f\x012\x03"},
{"math/bits", "\xcb\x02"},
{"math/cmplx", "\xfd\x01\x03"},
{"math/rand", "\xb6\x01G:\x01\x13"},
{"math/rand/v2", "n+\x03a\x03K"},
{"mime", "\x02\x01c\b\x03\x80\x01\v!\x15\x03\x02\x10\x02"},
{"mime/multipart", "\x02\x01H#\x03E;\v\x01\a\x02\x15\x02\x06\x0f\x02\x01\x16"},
{"mime/quotedprintable", "\x02\x01n\x80\x01"},
{"net", "\x04\ta*\x1e\a\x04\x05\x11\x01\x04\x15\x01%\x06\r\b\x05\x01\x01\f\x06\a"},
{"net/http", "\x02\x01\x04\x04\x02>\b\x13\x01\a\x03E;\x01\x03\a\x01\x03\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\r\x02\x02\x02\b\x01\x01\x01"},
{"net/http/cgi", "\x02Q\x1b\x03\x80\x01\x04\a\v\x01\x13\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x10\x0e"},
{"net/http/cookiejar", "\x04j\x03\x96\x01\x01\b\f\x16\x03\x02\x0e\x04"},
{"net/http/fcgi", "\x02\x01\nZ\a\x03\x80\x01\x16\x01\x01\x14\x18\x02\x0e"},
{"net/http/httptest", "\x02\x01\nF\x02\x1b\x01\x80\x01\x04\x12\x01\n\t\x02\x17\x01\x02\x0e\x0e"},
{"net/http/httptrace", "\rFnF\x14\n "},
{"net/http/httputil", "\x02\x01\na\x03\x80\x01\x04\x0f\x03\x01\x05\x02\x01\v\x01\x19\x02\x0e\x0e"},
{"net/http/internal", "\x02\x01k\x03\x80\x01"},
{"net/http/internal/ascii", "\xb5\x02\x12"},
{"net/http/internal/httpcommon", "\ra\x03\x9c\x01\x0e\x01\x17\x01\x01\x02\x1c\x02"},
{"net/http/internal/testcert", "\xb5\x02"},
{"net/http/pprof", "\x02\x01\nd\x18-\x11*\x04\x13\x14\x01\r\x04\x03\x01\x02\x01\x10"},
{"net/internal/cgotest", ""},
{"net/internal/socktest", "p\xc2\x01\x02"},
{"net/mail", "\x02k\x03z\x04\x0f\x03\x14\x1c\x02\r\x04"},
{"net/netip", "\x04i+\x01#;\x026\x15"},
{"net/rpc", "\x02f\x05\x03\x10\n`\x04\x12\x01\x1d\x0f\x03\x02"},
{"net/rpc/jsonrpc", "j\x03\x03z\x16\x11!"},
{"net/smtp", "\x19.\v\x13\b\x03z\x16\x14\x1c"},
{"net/textproto", "\x02\x01j\x03z\r\t/\x01\x02\x13"},
{"net/url", "m\x03\x86\x01%\x12\x02\x01\x15"},
{"os", "m+\x01\x18\x03\b\t\r\x03\x01\x04\x10\x018\n\x05\x01\x01\v\x06"},
{"os/exec", "\x03\n`H \x01\x14\x01+\x06\a\f\x01\x04\v"},
{"os/exec/internal/fdtest", "\xb4\x02"},
{"os/signal", "\r\x89\x02\x17\x05\x02"},
{"os/user", "\x02\x01j\x03z,\r\f\x01\x02"},
{"path", "m+\xab\x01"},
{"path/filepath", "m+\x19:+\r\n\x03\x04\x0f"},
{"plugin", "m"},
{"reflect", "m'\x04\x1c\b\f\x04\x02\x19\x10,\f\x03\x0f\x02\x02"},
{"net/internal/socktest", "q\xc6\x01\x02"},
{"net/mail", "\x02l\x03\x80\x01\x04\x0f\x03\x14\x1a\x02\x0e\x04"},
{"net/netip", "\x04j*\x01$@\x034\x16"},
{"net/rpc", "\x02g\x05\x03\x0f\ng\x04\x12\x01\x1d\r\x03\x02"},
{"net/rpc/jsonrpc", "k\x03\x03\x80\x01\x16\x11\x1f"},
{"net/smtp", "\x19/\v\x13\b\x03\x80\x01\x16\x14\x1a"},
{"net/textproto", "\x02\x01k\x03\x80\x01\f\n-\x01\x02\x14"},
{"net/url", "n\x03\x8b\x01&\x10\x02\x01\x16"},
{"os", "n*\x01\x19\x03\b\t\x12\x03\x01\x05\x10\x018\b\x05\x01\x01\f\x06"},
{"os/exec", "\x03\naH%\x01\x15\x01+\x06\a\n\x01\x04\f"},
{"os/exec/internal/fdtest", "\xb9\x02"},
{"os/signal", "\r\x90\x02\x15\x05\x02"},
{"os/user", "\x02\x01k\x03\x80\x01,\r\n\x01\x02"},
{"path", "n*\xb1\x01"},
{"path/filepath", "n*\x1a@+\r\b\x03\x04\x10"},
{"plugin", "n"},
{"reflect", "n&\x04\x1d\b\f\x06\x04\x1b\x06\t-\n\x03\x10\x02\x02"},
{"reflect/internal/example1", ""},
{"reflect/internal/example2", ""},
{"regexp", "\x03\xe7\x018\v\x02\x01\x02\x0f\x02"},
{"regexp/syntax", "\xad\x02\x01\x01\x01\x11\x02"},
{"runtime", "\x94\x01\x04\x01\x02\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x03\x0fd"},
{"runtime/coverage", "\x9f\x01K"},
{"runtime/debug", "pUQ\r\n\x02\x01\x0f\x06"},
{"runtime/internal/startlinetest", ""},
{"runtime/internal/wasitest", ""},
{"runtime/metrics", "\xb6\x01A,\""},
{"runtime/pprof", "\x02\x01\x01\x03\x06Y\a\x03$3#\r\x1f\r\n\x01\x01\x01\x02\x02\b\x03\x06"},
{"runtime/race", "\xab\x02"},
{"regexp", "\x03\xee\x018\t\x02\x01\x02\x10\x02"},
{"regexp/syntax", "\xb2\x02\x01\x01\x01\x02\x10\x02"},
{"runtime", "\x94\x01\x04\x01\x03\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x02\x01\x01\x04\x10c"},
{"runtime/coverage", "\xa0\x01Q"},
{"runtime/debug", "qUW\r\b\x02\x01\x10\x06"},
{"runtime/metrics", "\xb7\x01F-!"},
{"runtime/pprof", "\x02\x01\x01\x03\x06Z\a\x03#4)\f \r\b\x01\x01\x01\x02\x02\t\x03\x06"},
{"runtime/race", "\xb0\x02"},
{"runtime/race/internal/amd64v1", ""},
{"runtime/trace", "\rcz9\x0f\x01\x12"},
{"slices", "\x04\xe9\x01\fL"},
{"sort", "\xc9\x0104"},
{"strconv", "m+:%\x02J"},
{"strings", "m'\x04:\x18\x03\f9\x0f\x02\x02"},
{"runtime/trace", "\ra\x03w\t9\b\x05\x01\r\x06"},
{"slices", "\x04\xf0\x01\fK"},
{"sort", "\xca\x0162"},
{"strconv", "n*@%\x03I"},
{"strings", "n&\x04@\x19\x03\f7\x10\x02\x02"},
{"structs", ""},
{"sync", "\xc8\x01\vP\x10\x12"},
{"sync/atomic", "\xc5\x02"},
{"syscall", "m(\x03\x01\x1b\b\x03\x03\x06\aT\n\x05\x01\x12"},
{"testing", "\x03\n`\x02\x01X\x0f\x13\r\x04\x1b\x06\x02\x05\x02\a\x01\x02\x01\x02\x01\f\x02\x02\x02"},
{"testing/fstest", "m\x03z\x01\v%\x12\x03\b\a"},
{"testing/internal/testdeps", "\x02\v\xa6\x01'\x10,\x03\x05\x03\b\a\x02\r"},
{"testing/iotest", "\x03j\x03z\x04"},
{"testing/quick", "o\x01\x87\x01\x04#\x12\x0f"},
{"testing/slogtest", "\r`\x03\x80\x01.\x05\x12\n"},
{"text/scanner", "\x03mz,+\x02"},
{"text/tabwriter", "pzY"},
{"text/template", "m\x03B8\x01\v\x1f\x01\x05\x01\x02\x05\r\x02\f\x03\x02"},
{"text/template/parse", "\x03m\xb3\x01\f\x01\x11\x02"},
{"time", "m+\x1d\x1d'*\x0f\x02\x11"},
{"time/tzdata", "m\xc7\x01\x11"},
{"sync", "\xc9\x01\x10\x01P\x0e\x13"},
{"sync/atomic", "\xcb\x02"},
{"syscall", "n'\x03\x01\x1c\b\x03\x03\x06\vV\b\x05\x01\x13"},
{"testing", "\x03\na\x02\x01X\x14\x14\f\x05\x1b\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\r\x02\x02\x02"},
{"testing/fstest", "n\x03\x80\x01\x01\n&\x10\x03\b\b"},
{"testing/internal/testdeps", "\x02\v\xa7\x01-\x10,\x03\x05\x03\x06\a\x02\x0e"},
{"testing/iotest", "\x03k\x03\x80\x01\x04"},
{"testing/quick", "p\x01\x8c\x01\x05#\x10\x10"},
{"testing/slogtest", "\ra\x03\x86\x01.\x05\x10\v"},
{"testing/synctest", "\xda\x01`\x11"},
{"text/scanner", "\x03n\x80\x01,*\x02"},
{"text/tabwriter", "q\x80\x01X"},
{"text/template", "n\x03B>\x01\n \x01\x05\x01\x02\x05\v\x02\r\x03\x02"},
{"text/template/parse", "\x03n\xb9\x01\n\x01\x12\x02"},
{"time", "n*\x1e\"(*\r\x02\x12"},
{"time/tzdata", "n\xcb\x01\x12"},
{"unicode", ""},
{"unicode/utf16", ""},
{"unicode/utf8", ""},
{"unique", "\x94\x01>\x01P\x0f\x13\x12"},
{"unique", "\x94\x01!#\x01Q\r\x01\x13\x12"},
{"unsafe", ""},
{"vendor/golang.org/x/crypto/chacha20", "\x10V\a\x8c\x01*'"},
{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10V\a\xd9\x01\x04\x01\a"},
{"vendor/golang.org/x/crypto/cryptobyte", "c\n\x03\x88\x01&!\n"},
{"vendor/golang.org/x/crypto/chacha20", "\x10W\a\x92\x01*&"},
{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10W\a\xde\x01\x04\x01\a"},
{"vendor/golang.org/x/crypto/cryptobyte", "d\n\x03\x8d\x01' \n"},
{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
{"vendor/golang.org/x/crypto/internal/alias", "\xc5\x02"},
{"vendor/golang.org/x/crypto/internal/poly1305", "Q\x15\x93\x01"},
{"vendor/golang.org/x/net/dns/dnsmessage", "m"},
{"vendor/golang.org/x/net/http/httpguts", "\x80\x02\x14\x1c\x13\r"},
{"vendor/golang.org/x/net/http/httpproxy", "m\x03\x90\x01\x15\x01\x1a\x13\r"},
{"vendor/golang.org/x/net/http2/hpack", "\x03j\x03zH"},
{"vendor/golang.org/x/net/idna", "p\x87\x019\x13\x10\x02\x01"},
{"vendor/golang.org/x/net/nettest", "\x03c\a\x03z\x11\x05\x16\x01\f\f\x01\x02\x02\x01\n"},
{"vendor/golang.org/x/sys/cpu", "\x96\x02\r\f\x01\x15"},
{"vendor/golang.org/x/text/secure/bidirule", "m\xd6\x01\x11\x01"},
{"vendor/golang.org/x/text/transform", "\x03j}Y"},
{"vendor/golang.org/x/text/unicode/bidi", "\x03\be~@\x15"},
{"vendor/golang.org/x/text/unicode/norm", "f\nzH\x11\x11"},
{"weak", "\x94\x01\x8f\x01\""},
{"vendor/golang.org/x/crypto/internal/alias", "\xcb\x02"},
{"vendor/golang.org/x/crypto/internal/poly1305", "R\x15\x99\x01"},
{"vendor/golang.org/x/net/dns/dnsmessage", "n"},
{"vendor/golang.org/x/net/http/httpguts", "\x87\x02\x14\x1a\x14\r"},
{"vendor/golang.org/x/net/http/httpproxy", "n\x03\x96\x01\x10\x05\x01\x18\x14\r"},
{"vendor/golang.org/x/net/http2/hpack", "\x03k\x03\x80\x01F"},
{"vendor/golang.org/x/net/idna", "q\x8c\x018\x14\x10\x02\x01"},
{"vendor/golang.org/x/net/nettest", "\x03d\a\x03\x80\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\v"},
{"vendor/golang.org/x/sys/cpu", "\x9d\x02\r\n\x01\x16"},
{"vendor/golang.org/x/text/secure/bidirule", "n\xdb\x01\x11\x01"},
{"vendor/golang.org/x/text/transform", "\x03k\x83\x01X"},
{"vendor/golang.org/x/text/unicode/bidi", "\x03\bf\x84\x01>\x16"},
{"vendor/golang.org/x/text/unicode/norm", "g\n\x80\x01F\x12\x11"},
{"weak", "\x94\x01\x96\x01!"},
}
+54 -4
View File
@@ -502,6 +502,7 @@ var PackageSymbols = map[string][]Symbol{
{"MD4", Const, 0, ""},
{"MD5", Const, 0, ""},
{"MD5SHA1", Const, 0, ""},
{"MessageSigner", Type, 25, ""},
{"PrivateKey", Type, 0, ""},
{"PublicKey", Type, 2, ""},
{"RIPEMD160", Const, 0, ""},
@@ -517,6 +518,7 @@ var PackageSymbols = map[string][]Symbol{
{"SHA512", Const, 0, ""},
{"SHA512_224", Const, 5, ""},
{"SHA512_256", Const, 5, ""},
{"SignMessage", Func, 25, "func(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)"},
{"Signer", Type, 4, ""},
{"SignerOpts", Type, 4, ""},
},
@@ -600,10 +602,12 @@ var PackageSymbols = map[string][]Symbol{
{"X25519", Func, 20, "func() Curve"},
},
"crypto/ecdsa": {
{"(*PrivateKey).Bytes", Method, 25, ""},
{"(*PrivateKey).ECDH", Method, 20, ""},
{"(*PrivateKey).Equal", Method, 15, ""},
{"(*PrivateKey).Public", Method, 4, ""},
{"(*PrivateKey).Sign", Method, 4, ""},
{"(*PublicKey).Bytes", Method, 25, ""},
{"(*PublicKey).ECDH", Method, 20, ""},
{"(*PublicKey).Equal", Method, 15, ""},
{"(PrivateKey).Add", Method, 0, ""},
@@ -619,6 +623,8 @@ var PackageSymbols = map[string][]Symbol{
{"(PublicKey).ScalarBaseMult", Method, 0, ""},
{"(PublicKey).ScalarMult", Method, 0, ""},
{"GenerateKey", Func, 0, "func(c elliptic.Curve, rand io.Reader) (*PrivateKey, error)"},
{"ParseRawPrivateKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PrivateKey, error)"},
{"ParseUncompressedPublicKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PublicKey, error)"},
{"PrivateKey", Type, 0, ""},
{"PrivateKey.D", Field, 0, ""},
{"PrivateKey.PublicKey", Field, 0, ""},
@@ -815,6 +821,7 @@ var PackageSymbols = map[string][]Symbol{
"crypto/sha3": {
{"(*SHA3).AppendBinary", Method, 24, ""},
{"(*SHA3).BlockSize", Method, 24, ""},
{"(*SHA3).Clone", Method, 25, ""},
{"(*SHA3).MarshalBinary", Method, 24, ""},
{"(*SHA3).Reset", Method, 24, ""},
{"(*SHA3).Size", Method, 24, ""},
@@ -967,6 +974,7 @@ var PackageSymbols = map[string][]Symbol{
{"Config.GetCertificate", Field, 4, ""},
{"Config.GetClientCertificate", Field, 8, ""},
{"Config.GetConfigForClient", Field, 8, ""},
{"Config.GetEncryptedClientHelloKeys", Field, 25, ""},
{"Config.InsecureSkipVerify", Field, 0, ""},
{"Config.KeyLogWriter", Field, 8, ""},
{"Config.MaxVersion", Field, 2, ""},
@@ -5463,6 +5471,7 @@ var PackageSymbols = map[string][]Symbol{
{"ParenExpr.X", Field, 0, ""},
{"Pkg", Const, 0, ""},
{"Preorder", Func, 23, "func(root Node) iter.Seq[Node]"},
{"PreorderStack", Func, 25, "func(root Node, stack []Node, f func(n Node, stack []Node) bool)"},
{"Print", Func, 0, "func(fset *token.FileSet, x any) error"},
{"RECV", Const, 0, ""},
{"RangeStmt", Type, 0, ""},
@@ -5933,6 +5942,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*File).SetLines", Method, 0, ""},
{"(*File).SetLinesForContent", Method, 0, ""},
{"(*File).Size", Method, 0, ""},
{"(*FileSet).AddExistingFiles", Method, 25, ""},
{"(*FileSet).AddFile", Method, 0, ""},
{"(*FileSet).Base", Method, 0, ""},
{"(*FileSet).File", Method, 0, ""},
@@ -6382,7 +6392,7 @@ var PackageSymbols = map[string][]Symbol{
{"Label", Type, 5, ""},
{"LocalVar", Const, 25, ""},
{"LookupFieldOrMethod", Func, 5, "func(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool)"},
{"LookupSelection", Func, 25, ""},
{"LookupSelection", Func, 25, "func(T Type, addressable bool, pkg *Package, name string) (Selection, bool)"},
{"Map", Type, 5, ""},
{"MethodExpr", Const, 5, ""},
{"MethodSet", Type, 5, ""},
@@ -6490,9 +6500,11 @@ var PackageSymbols = map[string][]Symbol{
{"Lang", Func, 22, "func(x string) string"},
},
"hash": {
{"Cloner", Type, 25, ""},
{"Hash", Type, 0, ""},
{"Hash32", Type, 0, ""},
{"Hash64", Type, 0, ""},
{"XOF", Type, 25, ""},
},
"hash/adler32": {
{"Checksum", Func, 0, "func(data []byte) uint32"},
@@ -6533,6 +6545,7 @@ var PackageSymbols = map[string][]Symbol{
},
"hash/maphash": {
{"(*Hash).BlockSize", Method, 14, ""},
{"(*Hash).Clone", Method, 25, ""},
{"(*Hash).Reset", Method, 14, ""},
{"(*Hash).Seed", Method, 14, ""},
{"(*Hash).SetSeed", Method, 14, ""},
@@ -7133,7 +7146,7 @@ var PackageSymbols = map[string][]Symbol{
{"FormatFileInfo", Func, 21, "func(info FileInfo) string"},
{"Glob", Func, 16, "func(fsys FS, pattern string) (matches []string, err error)"},
{"GlobFS", Type, 16, ""},
{"Lstat", Func, 25, ""},
{"Lstat", Func, 25, "func(fsys FS, name string) (FileInfo, error)"},
{"ModeAppend", Const, 16, ""},
{"ModeCharDevice", Const, 16, ""},
{"ModeDevice", Const, 16, ""},
@@ -7158,7 +7171,7 @@ var PackageSymbols = map[string][]Symbol{
{"ReadDirFile", Type, 16, ""},
{"ReadFile", Func, 16, "func(fsys FS, name string) ([]byte, error)"},
{"ReadFileFS", Type, 16, ""},
{"ReadLink", Func, 25, ""},
{"ReadLink", Func, 25, "func(fsys FS, name string) (string, error)"},
{"ReadLinkFS", Type, 25, ""},
{"SkipAll", Var, 20, ""},
{"SkipDir", Var, 16, ""},
@@ -7275,6 +7288,7 @@ var PackageSymbols = map[string][]Symbol{
{"(Record).Attrs", Method, 21, ""},
{"(Record).Clone", Method, 21, ""},
{"(Record).NumAttrs", Method, 21, ""},
{"(Record).Source", Method, 25, ""},
{"(Value).Any", Method, 21, ""},
{"(Value).Bool", Method, 21, ""},
{"(Value).Duration", Method, 21, ""},
@@ -7306,6 +7320,7 @@ var PackageSymbols = map[string][]Symbol{
{"Float64", Func, 21, "func(key string, v float64) Attr"},
{"Float64Value", Func, 21, "func(v float64) Value"},
{"Group", Func, 21, "func(key string, args ...any) Attr"},
{"GroupAttrs", Func, 25, "func(key string, attrs ...Attr) Attr"},
{"GroupValue", Func, 21, "func(as ...Attr) Value"},
{"Handler", Type, 21, ""},
{"HandlerOptions", Type, 21, ""},
@@ -7916,7 +7931,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*Writer).WriteField", Method, 0, ""},
{"ErrMessageTooLarge", Var, 9, ""},
{"File", Type, 0, ""},
{"FileContentDisposition", Func, 25, ""},
{"FileContentDisposition", Func, 25, "func(fieldname string, filename string) string"},
{"FileHeader", Type, 0, ""},
{"FileHeader.Filename", Field, 0, ""},
{"FileHeader.Header", Field, 0, ""},
@@ -8294,6 +8309,11 @@ var PackageSymbols = map[string][]Symbol{
{"(*Client).PostForm", Method, 0, ""},
{"(*Cookie).String", Method, 0, ""},
{"(*Cookie).Valid", Method, 18, ""},
{"(*CrossOriginProtection).AddInsecureBypassPattern", Method, 25, ""},
{"(*CrossOriginProtection).AddTrustedOrigin", Method, 25, ""},
{"(*CrossOriginProtection).Check", Method, 25, ""},
{"(*CrossOriginProtection).Handler", Method, 25, ""},
{"(*CrossOriginProtection).SetDenyHandler", Method, 25, ""},
{"(*MaxBytesError).Error", Method, 19, ""},
{"(*ProtocolError).Error", Method, 0, ""},
{"(*ProtocolError).Is", Method, 21, ""},
@@ -8388,6 +8408,7 @@ var PackageSymbols = map[string][]Symbol{
{"Cookie.Unparsed", Field, 0, ""},
{"Cookie.Value", Field, 0, ""},
{"CookieJar", Type, 0, ""},
{"CrossOriginProtection", Type, 25, ""},
{"DefaultClient", Var, 0, ""},
{"DefaultMaxHeaderBytes", Const, 0, ""},
{"DefaultMaxIdleConnsPerHost", Const, 0, ""},
@@ -8460,6 +8481,7 @@ var PackageSymbols = map[string][]Symbol{
{"MethodPost", Const, 6, ""},
{"MethodPut", Const, 6, ""},
{"MethodTrace", Const, 6, ""},
{"NewCrossOriginProtection", Func, 25, "func() *CrossOriginProtection"},
{"NewFileTransport", Func, 0, "func(fs FileSystem) RoundTripper"},
{"NewFileTransportFS", Func, 22, "func(fsys fs.FS) RoundTripper"},
{"NewRequest", Func, 0, "func(method string, url string, body io.Reader) (*Request, error)"},
@@ -9174,15 +9196,19 @@ var PackageSymbols = map[string][]Symbol{
{"(*Root).Link", Method, 25, ""},
{"(*Root).Lstat", Method, 24, ""},
{"(*Root).Mkdir", Method, 24, ""},
{"(*Root).MkdirAll", Method, 25, ""},
{"(*Root).Name", Method, 24, ""},
{"(*Root).Open", Method, 24, ""},
{"(*Root).OpenFile", Method, 24, ""},
{"(*Root).OpenRoot", Method, 24, ""},
{"(*Root).ReadFile", Method, 25, ""},
{"(*Root).Readlink", Method, 25, ""},
{"(*Root).Remove", Method, 24, ""},
{"(*Root).RemoveAll", Method, 25, ""},
{"(*Root).Rename", Method, 25, ""},
{"(*Root).Stat", Method, 24, ""},
{"(*Root).Symlink", Method, 25, ""},
{"(*Root).WriteFile", Method, 25, ""},
{"(*SyscallError).Error", Method, 0, ""},
{"(*SyscallError).Timeout", Method, 10, ""},
{"(*SyscallError).Unwrap", Method, 13, ""},
@@ -9623,6 +9649,7 @@ var PackageSymbols = map[string][]Symbol{
{"StructTag", Type, 0, ""},
{"Swapper", Func, 8, "func(slice any) func(i int, j int)"},
{"Type", Type, 0, ""},
{"TypeAssert", Func, 25, "func[T any](v Value) (T, bool)"},
{"TypeFor", Func, 22, "func[T any]() Type"},
{"TypeOf", Func, 0, "func(i any) Type"},
{"Uint", Const, 0, ""},
@@ -9909,6 +9936,7 @@ var PackageSymbols = map[string][]Symbol{
{"SetBlockProfileRate", Func, 1, "func(rate int)"},
{"SetCPUProfileRate", Func, 0, "func(hz int)"},
{"SetCgoTraceback", Func, 7, "func(version int, traceback unsafe.Pointer, context unsafe.Pointer, symbolizer unsafe.Pointer)"},
{"SetDefaultGOMAXPROCS", Func, 25, "func()"},
{"SetFinalizer", Func, 0, "func(obj any, finalizer any)"},
{"SetMutexProfileFraction", Func, 8, "func(rate int) int"},
{"Stack", Func, 0, "func(buf []byte, all bool) int"},
@@ -10021,11 +10049,20 @@ var PackageSymbols = map[string][]Symbol{
{"WriteHeapProfile", Func, 0, "func(w io.Writer) error"},
},
"runtime/trace": {
{"(*FlightRecorder).Enabled", Method, 25, ""},
{"(*FlightRecorder).Start", Method, 25, ""},
{"(*FlightRecorder).Stop", Method, 25, ""},
{"(*FlightRecorder).WriteTo", Method, 25, ""},
{"(*Region).End", Method, 11, ""},
{"(*Task).End", Method, 11, ""},
{"FlightRecorder", Type, 25, ""},
{"FlightRecorderConfig", Type, 25, ""},
{"FlightRecorderConfig.MaxBytes", Field, 25, ""},
{"FlightRecorderConfig.MinAge", Field, 25, ""},
{"IsEnabled", Func, 11, "func() bool"},
{"Log", Func, 11, "func(ctx context.Context, category string, message string)"},
{"Logf", Func, 11, "func(ctx context.Context, category string, format string, args ...any)"},
{"NewFlightRecorder", Func, 25, "func(cfg FlightRecorderConfig) *FlightRecorder"},
{"NewTask", Func, 11, "func(pctx context.Context, taskType string) (ctx context.Context, task *Task)"},
{"Region", Type, 11, ""},
{"Start", Func, 5, "func(w io.Writer) error"},
@@ -16642,6 +16679,7 @@ var PackageSymbols = map[string][]Symbol{
{"ValueOf", Func, 0, ""},
},
"testing": {
{"(*B).Attr", Method, 25, ""},
{"(*B).Chdir", Method, 24, ""},
{"(*B).Cleanup", Method, 14, ""},
{"(*B).Context", Method, 24, ""},
@@ -16658,6 +16696,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*B).Logf", Method, 0, ""},
{"(*B).Loop", Method, 24, ""},
{"(*B).Name", Method, 8, ""},
{"(*B).Output", Method, 25, ""},
{"(*B).ReportAllocs", Method, 1, ""},
{"(*B).ReportMetric", Method, 13, ""},
{"(*B).ResetTimer", Method, 0, ""},
@@ -16674,6 +16713,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*B).StopTimer", Method, 0, ""},
{"(*B).TempDir", Method, 15, ""},
{"(*F).Add", Method, 18, ""},
{"(*F).Attr", Method, 25, ""},
{"(*F).Chdir", Method, 24, ""},
{"(*F).Cleanup", Method, 18, ""},
{"(*F).Context", Method, 24, ""},
@@ -16689,6 +16729,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*F).Log", Method, 18, ""},
{"(*F).Logf", Method, 18, ""},
{"(*F).Name", Method, 18, ""},
{"(*F).Output", Method, 25, ""},
{"(*F).Setenv", Method, 18, ""},
{"(*F).Skip", Method, 18, ""},
{"(*F).SkipNow", Method, 18, ""},
@@ -16697,6 +16738,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*F).TempDir", Method, 18, ""},
{"(*M).Run", Method, 4, ""},
{"(*PB).Next", Method, 3, ""},
{"(*T).Attr", Method, 25, ""},
{"(*T).Chdir", Method, 24, ""},
{"(*T).Cleanup", Method, 14, ""},
{"(*T).Context", Method, 24, ""},
@@ -16712,6 +16754,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*T).Log", Method, 0, ""},
{"(*T).Logf", Method, 0, ""},
{"(*T).Name", Method, 8, ""},
{"(*T).Output", Method, 25, ""},
{"(*T).Parallel", Method, 0, ""},
{"(*T).Run", Method, 7, ""},
{"(*T).Setenv", Method, 17, ""},
@@ -16834,6 +16877,10 @@ var PackageSymbols = map[string][]Symbol{
{"Run", Func, 22, "func(t *testing.T, newHandler func(*testing.T) slog.Handler, result func(*testing.T) map[string]any)"},
{"TestHandler", Func, 21, "func(h slog.Handler, results func() []map[string]any) error"},
},
"testing/synctest": {
{"Test", Func, 25, "func(t *testing.T, f func(*testing.T))"},
{"Wait", Func, 25, "func()"},
},
"text/scanner": {
{"(*Position).IsValid", Method, 0, ""},
{"(*Scanner).Init", Method, 0, ""},
@@ -17347,6 +17394,7 @@ var PackageSymbols = map[string][]Symbol{
{"CaseRange.Lo", Field, 0, ""},
{"CaseRanges", Var, 0, ""},
{"Categories", Var, 0, ""},
{"CategoryAliases", Var, 25, ""},
{"Caucasian_Albanian", Var, 4, ""},
{"Cc", Var, 0, ""},
{"Cf", Var, 0, ""},
@@ -17354,6 +17402,7 @@ var PackageSymbols = map[string][]Symbol{
{"Cham", Var, 0, ""},
{"Cherokee", Var, 0, ""},
{"Chorasmian", Var, 16, ""},
{"Cn", Var, 25, ""},
{"Co", Var, 0, ""},
{"Common", Var, 0, ""},
{"Coptic", Var, 0, ""},
@@ -17432,6 +17481,7 @@ var PackageSymbols = map[string][]Symbol{
{"Khojki", Var, 4, ""},
{"Khudawadi", Var, 4, ""},
{"L", Var, 0, ""},
{"LC", Var, 25, ""},
{"Lao", Var, 0, ""},
{"Latin", Var, 0, ""},
{"Lepcha", Var, 0, ""},
@@ -15,6 +15,14 @@ import (
// file.
// If the same package is imported multiple times, the last appearance is
// recorded.
//
// TODO(adonovan): this function ignores the effect of shadowing. It
// should accept a [token.Pos] and a [types.Info] and compute only the
// set of imports that are not shadowed at that point, analogous to
// [analysisinternal.AddImport]. It could also compute (as a side
// effect) the set of additional imports required to ensure that there
// is an accessible import for each necessary package, making it
// converge even more closely with AddImport.
func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier {
// Construct mapping of import paths to their defined names.
// It is only necessary to look at renaming imports.
+46 -2
View File
@@ -2,8 +2,20 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package typesinternal provides access to internal go/types APIs that are not
// yet exported.
// Package typesinternal provides helpful operators for dealing with
// go/types:
//
// - operators for querying typed syntax trees (e.g. [Imports], [IsFunctionNamed]);
// - functions for converting types to strings or syntax (e.g. [TypeExpr], FileQualifier]);
// - helpers for working with the [go/types] API (e.g. [NewTypesInfo]);
// - access to internal go/types APIs that are not yet
// exported (e.g. [SetUsesCgo], [ErrorCodeStartEnd], [VarKind]); and
// - common algorithms related to types (e.g. [TooNewStdSymbols]).
//
// See also:
// - [golang.org/x/tools/internal/astutil], for operations on untyped syntax;
// - [golang.org/x/tools/internal/analysisinernal], for helpers for analyzers;
// - [golang.org/x/tools/internal/refactor], for operators to compute text edits.
package typesinternal
import (
@@ -13,6 +25,7 @@ import (
"reflect"
"unsafe"
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/aliases"
)
@@ -60,6 +73,9 @@ func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, o
// which is often excessive.)
//
// If pkg is nil, it is equivalent to [*types.Package.Name].
//
// TODO(adonovan): all uses of this with TypeString should be
// eliminated when https://go.dev/issues/75604 is resolved.
func NameRelativeTo(pkg *types.Package) types.Qualifier {
return func(other *types.Package) string {
if pkg != nil && pkg == other {
@@ -153,3 +169,31 @@ func NewTypesInfo() *types.Info {
FileVersions: map[*ast.File]string{},
}
}
// EnclosingScope returns the innermost block logically enclosing the cursor.
func EnclosingScope(info *types.Info, cur inspector.Cursor) *types.Scope {
for cur := range cur.Enclosing() {
n := cur.Node()
// A function's Scope is associated with its FuncType.
switch f := n.(type) {
case *ast.FuncDecl:
n = f.Type
case *ast.FuncLit:
n = f.Type
}
if b := info.Scopes[n]; b != nil {
return b
}
}
panic("no Scope for *ast.File")
}
// Imports reports whether path is imported by pkg.
func Imports(pkg *types.Package, path string) bool {
for _, imp := range pkg.Imports() {
if imp.Path() == path {
return true
}
}
return false
}
+3 -14
View File
@@ -204,23 +204,12 @@ func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) {
}
}
// IsZeroExpr uses simple syntactic heuristics to report whether expr
// is a obvious zero value, such as 0, "", nil, or false.
// It cannot do better without type information.
func IsZeroExpr(expr ast.Expr) bool {
switch e := expr.(type) {
case *ast.BasicLit:
return e.Value == "0" || e.Value == `""`
case *ast.Ident:
return e.Name == "nil" || e.Name == "false"
default:
return false
}
}
// TypeExpr returns syntax for the specified type. References to named types
// are qualified by an appropriate (optional) qualifier function.
// It may panic for types such as Tuple or Union.
//
// See also https://go.dev/issues/75604, which will provide a robust
// Type-to-valid-Go-syntax formatter.
func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr {
switch t := t.(type) {
case *types.Basic:
+25 -1
View File
@@ -371,7 +371,31 @@ func ConsumeVarint(b []byte) (v uint64, n int) {
func SizeVarint(v uint64) int {
// This computes 1 + (bits.Len64(v)-1)/7.
// 9/64 is a good enough approximation of 1/7
return int(9*uint32(bits.Len64(v))+64) / 64
//
// The Go compiler can translate the bits.LeadingZeros64 call into the LZCNT
// instruction, which is very fast on CPUs from the last few years. The
// specific way of expressing the calculation matches C++ Protobuf, see
// https://godbolt.org/z/4P3h53oM4 for the C++ code and how gcc/clang
// optimize that function for GOAMD64=v1 and GOAMD64=v3 (-march=haswell).
// By OR'ing v with 1, we guarantee that v is never 0, without changing the
// result of SizeVarint. LZCNT is not defined for 0, meaning the compiler
// needs to add extra instructions to handle that case.
//
// The Go compiler currently (go1.24.4) does not make use of this knowledge.
// This opportunity (removing the XOR instruction, which handles the 0 case)
// results in a small (1%) performance win across CPU architectures.
//
// Independently of avoiding the 0 case, we need the v |= 1 line because
// it allows the Go compiler to eliminate an extra XCHGL barrier.
v |= 1
// It would be clearer to write log2value := 63 - uint32(...), but
// writing uint32(...) ^ 63 is much more efficient (-14% ARM, -20% Intel).
// Proof of identity for our value range [0..63]:
// https://go.dev/play/p/Pdn9hEWYakX
log2value := uint32(bits.LeadingZeros64(v)) ^ 63
return int((log2value*9 + (64 + 9)) / 64)
}
// AppendFixed32 appends v to b as a little-endian uint32.
-40
View File
@@ -1,40 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.13
// +build !go1.13
package errors
import "reflect"
// Is is a copy of Go 1.13's errors.Is for use with older Go versions.
func Is(err, target error) bool {
if target == nil {
return err == target
}
isComparable := reflect.TypeOf(target).Comparable()
for {
if isComparable && err == target {
return true
}
if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
return true
}
if err = unwrap(err); err == nil {
return false
}
}
}
func unwrap(err error) error {
u, ok := err.(interface {
Unwrap() error
})
if !ok {
return nil
}
return u.Unwrap()
}
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.13
// +build go1.13
package errors
import "errors"
// Is is errors.Is.
func Is(err, target error) bool { return errors.Is(err, target) }
+1 -1
View File
@@ -6,7 +6,7 @@
package flags
// ProtoLegacy specifies whether to enable support for legacy functionality
// such as MessageSets, weak fields, and various other obscure behavior
// such as MessageSets, and various other obscure behavior
// that is necessary to maintain backwards compatibility with proto1 or
// the pre-release variants of proto2 and proto3.
//
+80 -18
View File
@@ -34,6 +34,19 @@ const (
Edition_EDITION_MAX_enum_value = 2147483647
)
// Full and short names for google.protobuf.SymbolVisibility.
const (
SymbolVisibility_enum_fullname = "google.protobuf.SymbolVisibility"
SymbolVisibility_enum_name = "SymbolVisibility"
)
// Enum values for google.protobuf.SymbolVisibility.
const (
SymbolVisibility_VISIBILITY_UNSET_enum_value = 0
SymbolVisibility_VISIBILITY_LOCAL_enum_value = 1
SymbolVisibility_VISIBILITY_EXPORT_enum_value = 2
)
// Names for google.protobuf.FileDescriptorSet.
const (
FileDescriptorSet_message_name protoreflect.Name = "FileDescriptorSet"
@@ -65,6 +78,7 @@ const (
FileDescriptorProto_Dependency_field_name protoreflect.Name = "dependency"
FileDescriptorProto_PublicDependency_field_name protoreflect.Name = "public_dependency"
FileDescriptorProto_WeakDependency_field_name protoreflect.Name = "weak_dependency"
FileDescriptorProto_OptionDependency_field_name protoreflect.Name = "option_dependency"
FileDescriptorProto_MessageType_field_name protoreflect.Name = "message_type"
FileDescriptorProto_EnumType_field_name protoreflect.Name = "enum_type"
FileDescriptorProto_Service_field_name protoreflect.Name = "service"
@@ -79,6 +93,7 @@ const (
FileDescriptorProto_Dependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.dependency"
FileDescriptorProto_PublicDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.public_dependency"
FileDescriptorProto_WeakDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.weak_dependency"
FileDescriptorProto_OptionDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.option_dependency"
FileDescriptorProto_MessageType_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.message_type"
FileDescriptorProto_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.enum_type"
FileDescriptorProto_Service_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.service"
@@ -96,6 +111,7 @@ const (
FileDescriptorProto_Dependency_field_number protoreflect.FieldNumber = 3
FileDescriptorProto_PublicDependency_field_number protoreflect.FieldNumber = 10
FileDescriptorProto_WeakDependency_field_number protoreflect.FieldNumber = 11
FileDescriptorProto_OptionDependency_field_number protoreflect.FieldNumber = 15
FileDescriptorProto_MessageType_field_number protoreflect.FieldNumber = 4
FileDescriptorProto_EnumType_field_number protoreflect.FieldNumber = 5
FileDescriptorProto_Service_field_number protoreflect.FieldNumber = 6
@@ -124,6 +140,7 @@ const (
DescriptorProto_Options_field_name protoreflect.Name = "options"
DescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range"
DescriptorProto_ReservedName_field_name protoreflect.Name = "reserved_name"
DescriptorProto_Visibility_field_name protoreflect.Name = "visibility"
DescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.name"
DescriptorProto_Field_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.field"
@@ -135,6 +152,7 @@ const (
DescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.options"
DescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_range"
DescriptorProto_ReservedName_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_name"
DescriptorProto_Visibility_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.visibility"
)
// Field numbers for google.protobuf.DescriptorProto.
@@ -149,6 +167,7 @@ const (
DescriptorProto_Options_field_number protoreflect.FieldNumber = 7
DescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 9
DescriptorProto_ReservedName_field_number protoreflect.FieldNumber = 10
DescriptorProto_Visibility_field_number protoreflect.FieldNumber = 11
)
// Names for google.protobuf.DescriptorProto.ExtensionRange.
@@ -388,12 +407,14 @@ const (
EnumDescriptorProto_Options_field_name protoreflect.Name = "options"
EnumDescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range"
EnumDescriptorProto_ReservedName_field_name protoreflect.Name = "reserved_name"
EnumDescriptorProto_Visibility_field_name protoreflect.Name = "visibility"
EnumDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.name"
EnumDescriptorProto_Value_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.value"
EnumDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.options"
EnumDescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_range"
EnumDescriptorProto_ReservedName_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_name"
EnumDescriptorProto_Visibility_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.visibility"
)
// Field numbers for google.protobuf.EnumDescriptorProto.
@@ -403,6 +424,7 @@ const (
EnumDescriptorProto_Options_field_number protoreflect.FieldNumber = 3
EnumDescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 4
EnumDescriptorProto_ReservedName_field_number protoreflect.FieldNumber = 5
EnumDescriptorProto_Visibility_field_number protoreflect.FieldNumber = 6
)
// Names for google.protobuf.EnumDescriptorProto.EnumReservedRange.
@@ -1008,29 +1030,35 @@ const (
// Field names for google.protobuf.FeatureSet.
const (
FeatureSet_FieldPresence_field_name protoreflect.Name = "field_presence"
FeatureSet_EnumType_field_name protoreflect.Name = "enum_type"
FeatureSet_RepeatedFieldEncoding_field_name protoreflect.Name = "repeated_field_encoding"
FeatureSet_Utf8Validation_field_name protoreflect.Name = "utf8_validation"
FeatureSet_MessageEncoding_field_name protoreflect.Name = "message_encoding"
FeatureSet_JsonFormat_field_name protoreflect.Name = "json_format"
FeatureSet_FieldPresence_field_name protoreflect.Name = "field_presence"
FeatureSet_EnumType_field_name protoreflect.Name = "enum_type"
FeatureSet_RepeatedFieldEncoding_field_name protoreflect.Name = "repeated_field_encoding"
FeatureSet_Utf8Validation_field_name protoreflect.Name = "utf8_validation"
FeatureSet_MessageEncoding_field_name protoreflect.Name = "message_encoding"
FeatureSet_JsonFormat_field_name protoreflect.Name = "json_format"
FeatureSet_EnforceNamingStyle_field_name protoreflect.Name = "enforce_naming_style"
FeatureSet_DefaultSymbolVisibility_field_name protoreflect.Name = "default_symbol_visibility"
FeatureSet_FieldPresence_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.field_presence"
FeatureSet_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enum_type"
FeatureSet_RepeatedFieldEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.repeated_field_encoding"
FeatureSet_Utf8Validation_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation"
FeatureSet_MessageEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding"
FeatureSet_JsonFormat_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.json_format"
FeatureSet_FieldPresence_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.field_presence"
FeatureSet_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enum_type"
FeatureSet_RepeatedFieldEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.repeated_field_encoding"
FeatureSet_Utf8Validation_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation"
FeatureSet_MessageEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding"
FeatureSet_JsonFormat_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.json_format"
FeatureSet_EnforceNamingStyle_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enforce_naming_style"
FeatureSet_DefaultSymbolVisibility_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.default_symbol_visibility"
)
// Field numbers for google.protobuf.FeatureSet.
const (
FeatureSet_FieldPresence_field_number protoreflect.FieldNumber = 1
FeatureSet_EnumType_field_number protoreflect.FieldNumber = 2
FeatureSet_RepeatedFieldEncoding_field_number protoreflect.FieldNumber = 3
FeatureSet_Utf8Validation_field_number protoreflect.FieldNumber = 4
FeatureSet_MessageEncoding_field_number protoreflect.FieldNumber = 5
FeatureSet_JsonFormat_field_number protoreflect.FieldNumber = 6
FeatureSet_FieldPresence_field_number protoreflect.FieldNumber = 1
FeatureSet_EnumType_field_number protoreflect.FieldNumber = 2
FeatureSet_RepeatedFieldEncoding_field_number protoreflect.FieldNumber = 3
FeatureSet_Utf8Validation_field_number protoreflect.FieldNumber = 4
FeatureSet_MessageEncoding_field_number protoreflect.FieldNumber = 5
FeatureSet_JsonFormat_field_number protoreflect.FieldNumber = 6
FeatureSet_EnforceNamingStyle_field_number protoreflect.FieldNumber = 7
FeatureSet_DefaultSymbolVisibility_field_number protoreflect.FieldNumber = 8
)
// Full and short names for google.protobuf.FeatureSet.FieldPresence.
@@ -1112,6 +1140,40 @@ const (
FeatureSet_LEGACY_BEST_EFFORT_enum_value = 2
)
// Full and short names for google.protobuf.FeatureSet.EnforceNamingStyle.
const (
FeatureSet_EnforceNamingStyle_enum_fullname = "google.protobuf.FeatureSet.EnforceNamingStyle"
FeatureSet_EnforceNamingStyle_enum_name = "EnforceNamingStyle"
)
// Enum values for google.protobuf.FeatureSet.EnforceNamingStyle.
const (
FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN_enum_value = 0
FeatureSet_STYLE2024_enum_value = 1
FeatureSet_STYLE_LEGACY_enum_value = 2
)
// Names for google.protobuf.FeatureSet.VisibilityFeature.
const (
FeatureSet_VisibilityFeature_message_name protoreflect.Name = "VisibilityFeature"
FeatureSet_VisibilityFeature_message_fullname protoreflect.FullName = "google.protobuf.FeatureSet.VisibilityFeature"
)
// Full and short names for google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility.
const (
FeatureSet_VisibilityFeature_DefaultSymbolVisibility_enum_fullname = "google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility"
FeatureSet_VisibilityFeature_DefaultSymbolVisibility_enum_name = "DefaultSymbolVisibility"
)
// Enum values for google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility.
const (
FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN_enum_value = 0
FeatureSet_VisibilityFeature_EXPORT_ALL_enum_value = 1
FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL_enum_value = 2
FeatureSet_VisibilityFeature_LOCAL_ALL_enum_value = 3
FeatureSet_VisibilityFeature_STRICT_enum_value = 4
)
// Names for google.protobuf.FeatureSetDefaults.
const (
FeatureSetDefaults_message_name protoreflect.Name = "FeatureSetDefaults"
+1 -1
View File
@@ -6,6 +6,6 @@
// and the well-known types.
package genid
import protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
const GoogleProtobuf_package protoreflect.FullName = "google.protobuf"
@@ -12,20 +12,59 @@ import (
const File_google_protobuf_go_features_proto = "google/protobuf/go_features.proto"
// Names for google.protobuf.GoFeatures.
// Names for pb.GoFeatures.
const (
GoFeatures_message_name protoreflect.Name = "GoFeatures"
GoFeatures_message_fullname protoreflect.FullName = "google.protobuf.GoFeatures"
GoFeatures_message_fullname protoreflect.FullName = "pb.GoFeatures"
)
// Field names for google.protobuf.GoFeatures.
// Field names for pb.GoFeatures.
const (
GoFeatures_LegacyUnmarshalJsonEnum_field_name protoreflect.Name = "legacy_unmarshal_json_enum"
GoFeatures_ApiLevel_field_name protoreflect.Name = "api_level"
GoFeatures_StripEnumPrefix_field_name protoreflect.Name = "strip_enum_prefix"
GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "google.protobuf.GoFeatures.legacy_unmarshal_json_enum"
GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "pb.GoFeatures.legacy_unmarshal_json_enum"
GoFeatures_ApiLevel_field_fullname protoreflect.FullName = "pb.GoFeatures.api_level"
GoFeatures_StripEnumPrefix_field_fullname protoreflect.FullName = "pb.GoFeatures.strip_enum_prefix"
)
// Field numbers for google.protobuf.GoFeatures.
// Field numbers for pb.GoFeatures.
const (
GoFeatures_LegacyUnmarshalJsonEnum_field_number protoreflect.FieldNumber = 1
GoFeatures_ApiLevel_field_number protoreflect.FieldNumber = 2
GoFeatures_StripEnumPrefix_field_number protoreflect.FieldNumber = 3
)
// Full and short names for pb.GoFeatures.APILevel.
const (
GoFeatures_APILevel_enum_fullname = "pb.GoFeatures.APILevel"
GoFeatures_APILevel_enum_name = "APILevel"
)
// Enum values for pb.GoFeatures.APILevel.
const (
GoFeatures_API_LEVEL_UNSPECIFIED_enum_value = 0
GoFeatures_API_OPEN_enum_value = 1
GoFeatures_API_HYBRID_enum_value = 2
GoFeatures_API_OPAQUE_enum_value = 3
)
// Full and short names for pb.GoFeatures.StripEnumPrefix.
const (
GoFeatures_StripEnumPrefix_enum_fullname = "pb.GoFeatures.StripEnumPrefix"
GoFeatures_StripEnumPrefix_enum_name = "StripEnumPrefix"
)
// Enum values for pb.GoFeatures.StripEnumPrefix.
const (
GoFeatures_STRIP_ENUM_PREFIX_UNSPECIFIED_enum_value = 0
GoFeatures_STRIP_ENUM_PREFIX_KEEP_enum_value = 1
GoFeatures_STRIP_ENUM_PREFIX_GENERATE_BOTH_enum_value = 2
GoFeatures_STRIP_ENUM_PREFIX_STRIP_enum_value = 3
)
// Extension numbers
const (
FeatureSet_Go_ext_number protoreflect.FieldNumber = 1002
)
-5
View File
@@ -11,15 +11,10 @@ const (
SizeCache_goname = "sizeCache"
SizeCacheA_goname = "XXX_sizecache"
WeakFields_goname = "weakFields"
WeakFieldsA_goname = "XXX_weak"
UnknownFields_goname = "unknownFields"
UnknownFieldsA_goname = "XXX_unrecognized"
ExtensionFields_goname = "extensionFields"
ExtensionFieldsA_goname = "XXX_InternalExtensions"
ExtensionFieldsB_goname = "XXX_extensions"
WeakFieldPrefix_goname = "XXX_weak_"
)
+1 -1
View File
@@ -4,7 +4,7 @@
package genid
import protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
// Generic field names and numbers for synthetic map entry messages.
const (
+1 -1
View File
@@ -4,7 +4,7 @@
package genid
import protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
// Generic field name and number for messages in wrappers.proto.
const (
@@ -1,28 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build purego || appengine
// +build purego appengine
package strs
import pref "google.golang.org/protobuf/reflect/protoreflect"
func UnsafeString(b []byte) string {
return string(b)
}
func UnsafeBytes(s string) []byte {
return []byte(s)
}
type Builder struct{}
func (*Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.FullName {
return prefix.Append(name)
}
func (*Builder) MakeString(b []byte) string {
return string(b)
}
@@ -1,95 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && !go1.21
// +build !purego,!appengine,!go1.21
package strs
import (
"unsafe"
"google.golang.org/protobuf/reflect/protoreflect"
)
type (
stringHeader struct {
Data unsafe.Pointer
Len int
}
sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
)
// UnsafeString returns an unsafe string reference of b.
// The caller must treat the input slice as immutable.
//
// WARNING: Use carefully. The returned result must not leak to the end user
// unless the input slice is provably immutable.
func UnsafeString(b []byte) (s string) {
src := (*sliceHeader)(unsafe.Pointer(&b))
dst := (*stringHeader)(unsafe.Pointer(&s))
dst.Data = src.Data
dst.Len = src.Len
return s
}
// UnsafeBytes returns an unsafe bytes slice reference of s.
// The caller must treat returned slice as immutable.
//
// WARNING: Use carefully. The returned result must not leak to the end user.
func UnsafeBytes(s string) (b []byte) {
src := (*stringHeader)(unsafe.Pointer(&s))
dst := (*sliceHeader)(unsafe.Pointer(&b))
dst.Data = src.Data
dst.Len = src.Len
dst.Cap = src.Len
return b
}
// Builder builds a set of strings with shared lifetime.
// This differs from strings.Builder, which is for building a single string.
type Builder struct {
buf []byte
}
// AppendFullName is equivalent to protoreflect.FullName.Append,
// but optimized for large batches where each name has a shared lifetime.
func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName {
n := len(prefix) + len(".") + len(name)
if len(prefix) == 0 {
n -= len(".")
}
sb.grow(n)
sb.buf = append(sb.buf, prefix...)
sb.buf = append(sb.buf, '.')
sb.buf = append(sb.buf, name...)
return protoreflect.FullName(sb.last(n))
}
// MakeString is equivalent to string(b), but optimized for large batches
// with a shared lifetime.
func (sb *Builder) MakeString(b []byte) string {
sb.grow(len(b))
sb.buf = append(sb.buf, b...)
return sb.last(len(b))
}
func (sb *Builder) grow(n int) {
if cap(sb.buf)-len(sb.buf) >= n {
return
}
// Unlike strings.Builder, we do not need to copy over the contents
// of the old buffer since our builder provides no API for
// retrieving previously created strings.
sb.buf = make([]byte, 0, 2*(cap(sb.buf)+n))
}
func (sb *Builder) last(n int) string {
return UnsafeString(sb.buf[len(sb.buf)-n:])
}
@@ -1,74 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && go1.21
// +build !purego,!appengine,go1.21
package strs
import (
"unsafe"
"google.golang.org/protobuf/reflect/protoreflect"
)
// UnsafeString returns an unsafe string reference of b.
// The caller must treat the input slice as immutable.
//
// WARNING: Use carefully. The returned result must not leak to the end user
// unless the input slice is provably immutable.
func UnsafeString(b []byte) string {
return unsafe.String(unsafe.SliceData(b), len(b))
}
// UnsafeBytes returns an unsafe bytes slice reference of s.
// The caller must treat returned slice as immutable.
//
// WARNING: Use carefully. The returned result must not leak to the end user.
func UnsafeBytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
// Builder builds a set of strings with shared lifetime.
// This differs from strings.Builder, which is for building a single string.
type Builder struct {
buf []byte
}
// AppendFullName is equivalent to protoreflect.FullName.Append,
// but optimized for large batches where each name has a shared lifetime.
func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName {
n := len(prefix) + len(".") + len(name)
if len(prefix) == 0 {
n -= len(".")
}
sb.grow(n)
sb.buf = append(sb.buf, prefix...)
sb.buf = append(sb.buf, '.')
sb.buf = append(sb.buf, name...)
return protoreflect.FullName(sb.last(n))
}
// MakeString is equivalent to string(b), but optimized for large batches
// with a shared lifetime.
func (sb *Builder) MakeString(b []byte) string {
sb.grow(len(b))
sb.buf = append(sb.buf, b...)
return sb.last(len(b))
}
func (sb *Builder) grow(n int) {
if cap(sb.buf)-len(sb.buf) >= n {
return
}
// Unlike strings.Builder, we do not need to copy over the contents
// of the old buffer since our builder provides no API for
// retrieving previously created strings.
sb.buf = make([]byte, 0, 2*(cap(sb.buf)+n))
}
func (sb *Builder) last(n int) string {
return UnsafeString(sb.buf[len(sb.buf)-n:])
}
+16 -5
View File
@@ -8,7 +8,6 @@ import (
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect"
@@ -47,6 +46,12 @@ type UnmarshalOptions struct {
// RecursionLimit limits how deeply messages may be nested.
// If zero, a default limit is applied.
RecursionLimit int
//
// NoLazyDecoding turns off lazy decoding, which otherwise is enabled by
// default. Lazy decoding only affects submessages (annotated with [lazy =
// true] in the .proto file) within messages that use the Opaque API.
NoLazyDecoding bool
}
// Unmarshal parses the wire-format message in b and places the result in m.
@@ -104,6 +109,16 @@ func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out proto
if o.DiscardUnknown {
in.Flags |= protoiface.UnmarshalDiscardUnknown
}
if !allowPartial {
// This does not affect how current unmarshal functions work, it just allows them
// to record this for lazy the decoding case.
in.Flags |= protoiface.UnmarshalCheckRequired
}
if o.NoLazyDecoding {
in.Flags |= protoiface.UnmarshalNoLazyDecoding
}
out, err = methods.Unmarshal(in)
} else {
o.RecursionLimit--
@@ -156,10 +171,6 @@ func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message)
var err error
if fd == nil {
err = errUnknown
} else if flags.ProtoLegacy {
if fd.IsWeak() && fd.Message().IsPlaceholder() {
err = errUnknown // weak referent is not linked in
}
}
// Parse the field value.
+2 -1
View File
@@ -63,7 +63,8 @@ type MarshalOptions struct {
// options (except for UseCachedSize itself).
//
// 2. The message and all its submessages have not changed in any
// way since the Size call.
// way since the Size call. For lazily decoded messages, accessing
// a message results in decoding the message, which is a change.
//
// If either of these invariants is violated,
// the results are undefined and may include panics or corrupted output.
+9
View File
@@ -8,6 +8,7 @@ import (
"reflect"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface"
)
// Equal reports whether two messages are equal,
@@ -51,6 +52,14 @@ func Equal(x, y Message) bool {
if mx.IsValid() != my.IsValid() {
return false
}
// Only one of the messages needs to implement the fast-path for it to work.
pmx := protoMethods(mx)
pmy := protoMethods(my)
if pmx != nil && pmy != nil && pmx.Equal != nil && pmy.Equal != nil {
return pmx.Equal(protoiface.EqualInput{MessageA: mx, MessageB: my}).Equal
}
vx := protoreflect.ValueOfMessage(mx)
vy := protoreflect.ValueOfMessage(my)
return vx.Equal(vy)
+71
View File
@@ -39,6 +39,48 @@ func ClearExtension(m Message, xt protoreflect.ExtensionType) {
// If the field is unpopulated, it returns the default value for
// scalars and an immutable, empty value for lists or messages.
// It panics if xt does not extend m.
//
// The type of the value is dependent on the field type of the extension.
// For extensions generated by protoc-gen-go, the Go type is as follows:
//
// ╔═══════════════════╤═════════════════════════╗
// ║ Go type │ Protobuf kind ║
// ╠═══════════════════╪═════════════════════════╣
// ║ bool │ bool ║
// ║ int32 │ int32, sint32, sfixed32 ║
// ║ int64 │ int64, sint64, sfixed64 ║
// ║ uint32 │ uint32, fixed32 ║
// ║ uint64 │ uint64, fixed64 ║
// ║ float32 │ float ║
// ║ float64 │ double ║
// ║ string │ string ║
// ║ []byte │ bytes ║
// ║ protoreflect.Enum │ enum ║
// ║ proto.Message │ message, group ║
// ╚═══════════════════╧═════════════════════════╝
//
// The protoreflect.Enum and proto.Message types are the concrete Go type
// associated with the named enum or message. Repeated fields are represented
// using a Go slice of the base element type.
//
// If a generated extension descriptor variable is directly passed to
// GetExtension, then the call should be followed immediately by a
// type assertion to the expected output value. For example:
//
// mm := proto.GetExtension(m, foopb.E_MyExtension).(*foopb.MyMessage)
//
// This pattern enables static analysis tools to verify that the asserted type
// matches the Go type associated with the extension field and
// also enables a possible future migration to a type-safe extension API.
//
// Since singular messages are the most common extension type, the pattern of
// calling HasExtension followed by GetExtension may be simplified to:
//
// if mm := proto.GetExtension(m, foopb.E_MyExtension).(*foopb.MyMessage); mm != nil {
// ... // make use of mm
// }
//
// The mm variable is non-nil if and only if HasExtension reports true.
func GetExtension(m Message, xt protoreflect.ExtensionType) any {
// Treat nil message interface as an empty message; return the default.
if m == nil {
@@ -51,6 +93,35 @@ func GetExtension(m Message, xt protoreflect.ExtensionType) any {
// SetExtension stores the value of an extension field.
// It panics if m is invalid, xt does not extend m, or if type of v
// is invalid for the specified extension field.
//
// The type of the value is dependent on the field type of the extension.
// For extensions generated by protoc-gen-go, the Go type is as follows:
//
// ╔═══════════════════╤═════════════════════════╗
// ║ Go type │ Protobuf kind ║
// ╠═══════════════════╪═════════════════════════╣
// ║ bool │ bool ║
// ║ int32 │ int32, sint32, sfixed32 ║
// ║ int64 │ int64, sint64, sfixed64 ║
// ║ uint32 │ uint32, fixed32 ║
// ║ uint64 │ uint64, fixed64 ║
// ║ float32 │ float ║
// ║ float64 │ double ║
// ║ string │ string ║
// ║ []byte │ bytes ║
// ║ protoreflect.Enum │ enum ║
// ║ proto.Message │ message, group ║
// ╚═══════════════════╧═════════════════════════╝
//
// The protoreflect.Enum and proto.Message types are the concrete Go type
// associated with the named enum or message. Repeated fields are represented
// using a Go slice of the base element type.
//
// If a generated extension descriptor variable is directly passed to
// SetExtension (e.g., foopb.E_MyExtension), then the value should be a
// concrete type that matches the expected Go type for the extension descriptor
// so that static analysis tools can verify type correctness.
// This also enables a possible future migration to a type-safe extension API.
func SetExtension(m Message, xt protoreflect.ExtensionType, v any) {
xd := xt.TypeDescriptor()
pv := xt.ValueOf(v)
+6
View File
@@ -59,6 +59,12 @@ func Clone(m Message) Message {
return dst.Interface()
}
// CloneOf returns a deep copy of m. If the top-level message is invalid,
// it returns an invalid message as well.
func CloneOf[M Message](m M) M {
return Clone(m).(M)
}
// mergeOptions provides a namespace for merge functions, and can be
// exported in the future if we add user-visible merge options.
type mergeOptions struct{}
+8
View File
@@ -12,11 +12,19 @@ import (
)
// Size returns the size in bytes of the wire-format encoding of m.
//
// Note that Size might return more bytes than Marshal will write in the case of
// lazily decoded messages that arrive in non-minimal wire format: see
// https://protobuf.dev/reference/go/size/ for more details.
func Size(m Message) int {
return MarshalOptions{}.Size(m)
}
// Size returns the size in bytes of the wire-format encoding of m.
//
// Note that Size might return more bytes than Marshal will write in the case of
// lazily decoded messages that arrive in non-minimal wire format: see
// https://protobuf.dev/reference/go/size/ for more details.
func (o MarshalOptions) Size(m Message) int {
// Treat a nil message interface as an empty message; nothing to output.
if m == nil {
@@ -23,6 +23,7 @@ type (
Unmarshal func(unmarshalInput) (unmarshalOutput, error)
Merge func(mergeInput) mergeOutput
CheckInitialized func(checkInitializedInput) (checkInitializedOutput, error)
Equal func(equalInput) equalOutput
}
supportFlags = uint64
sizeInput = struct {
@@ -75,4 +76,13 @@ type (
checkInitializedOutput = struct {
pragma.NoUnkeyedLiterals
}
equalInput = struct {
pragma.NoUnkeyedLiterals
MessageA Message
MessageB Message
}
equalOutput = struct {
pragma.NoUnkeyedLiterals
Equal bool
}
)
@@ -21,6 +21,8 @@ func (p *SourcePath) appendFileDescriptorProto(b []byte) []byte {
b = p.appendRepeatedField(b, "public_dependency", nil)
case 11:
b = p.appendRepeatedField(b, "weak_dependency", nil)
case 15:
b = p.appendRepeatedField(b, "option_dependency", nil)
case 4:
b = p.appendRepeatedField(b, "message_type", (*SourcePath).appendDescriptorProto)
case 5:
@@ -66,6 +68,8 @@ func (p *SourcePath) appendDescriptorProto(b []byte) []byte {
b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendDescriptorProto_ReservedRange)
case 10:
b = p.appendRepeatedField(b, "reserved_name", nil)
case 11:
b = p.appendSingularField(b, "visibility", nil)
}
return b
}
@@ -85,6 +89,8 @@ func (p *SourcePath) appendEnumDescriptorProto(b []byte) []byte {
b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendEnumDescriptorProto_EnumReservedRange)
case 5:
b = p.appendRepeatedField(b, "reserved_name", nil)
case 6:
b = p.appendSingularField(b, "visibility", nil)
}
return b
}
@@ -398,6 +404,10 @@ func (p *SourcePath) appendFeatureSet(b []byte) []byte {
b = p.appendSingularField(b, "message_encoding", nil)
case 6:
b = p.appendSingularField(b, "json_format", nil)
case 7:
b = p.appendSingularField(b, "enforce_naming_style", nil)
case 8:
b = p.appendSingularField(b, "default_symbol_visibility", nil)
}
return b
}
+3 -9
View File
@@ -68,7 +68,7 @@ type Descriptor interface {
// dependency is not resolved, in which case only name information is known.
//
// Placeholder types may only be returned by the following accessors
// as a result of unresolved dependencies or weak imports:
// as a result of unresolved dependencies:
//
// ╔═══════════════════════════════════╤═════════════════════╗
// ║ Accessor │ Descriptor ║
@@ -168,11 +168,7 @@ type FileImport struct {
// The current file and the imported file must be within proto package.
IsPublic bool
// IsWeak reports whether this is a weak import, which does not impose
// a direct dependency on the target file.
//
// Weak imports are a legacy proto1 feature. Equivalent behavior is
// achieved using proto2 extension fields or proto3 Any messages.
// Deprecated: support for weak fields has been removed.
IsWeak bool
}
@@ -325,9 +321,7 @@ type FieldDescriptor interface {
// specified in the source .proto file.
HasOptionalKeyword() bool
// IsWeak reports whether this is a weak field, which does not impose a
// direct dependency on the target type.
// If true, then Message returns a placeholder type.
// Deprecated: support for weak fields has been removed.
IsWeak() bool
// IsPacked reports whether repeated primitive numeric kinds should be
+1 -1
View File
@@ -152,7 +152,7 @@ type Message interface {
// This method may return nil.
//
// The returned methods type is identical to
// google.golang.org/protobuf/runtime/protoiface.Methods.
// [google.golang.org/protobuf/runtime/protoiface.Methods].
// Consult the protoiface package documentation for details.
ProtoMethods() *methods
}
@@ -1,60 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build purego || appengine
// +build purego appengine
package protoreflect
import "google.golang.org/protobuf/internal/pragma"
type valueType int
const (
nilType valueType = iota
boolType
int32Type
int64Type
uint32Type
uint64Type
float32Type
float64Type
stringType
bytesType
enumType
ifaceType
)
// value is a union where only one type can be represented at a time.
// This uses a distinct field for each type. This is type safe in Go, but
// occupies more memory than necessary (72B).
type value struct {
pragma.DoNotCompare // 0B
typ valueType // 8B
num uint64 // 8B
str string // 16B
bin []byte // 24B
iface any // 16B
}
func valueOfString(v string) Value {
return Value{typ: stringType, str: v}
}
func valueOfBytes(v []byte) Value {
return Value{typ: bytesType, bin: v}
}
func valueOfIface(v any) Value {
return Value{typ: ifaceType, iface: v}
}
func (v Value) getString() string {
return v.str
}
func (v Value) getBytes() []byte {
return v.bin
}
func (v Value) getIface() any {
return v.iface
}
@@ -1,99 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && !go1.21
// +build !purego,!appengine,!go1.21
package protoreflect
import (
"unsafe"
"google.golang.org/protobuf/internal/pragma"
)
type (
stringHeader struct {
Data unsafe.Pointer
Len int
}
sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
ifaceHeader struct {
Type unsafe.Pointer
Data unsafe.Pointer
}
)
var (
nilType = typeOf(nil)
boolType = typeOf(*new(bool))
int32Type = typeOf(*new(int32))
int64Type = typeOf(*new(int64))
uint32Type = typeOf(*new(uint32))
uint64Type = typeOf(*new(uint64))
float32Type = typeOf(*new(float32))
float64Type = typeOf(*new(float64))
stringType = typeOf(*new(string))
bytesType = typeOf(*new([]byte))
enumType = typeOf(*new(EnumNumber))
)
// typeOf returns a pointer to the Go type information.
// The pointer is comparable and equal if and only if the types are identical.
func typeOf(t any) unsafe.Pointer {
return (*ifaceHeader)(unsafe.Pointer(&t)).Type
}
// value is a union where only one type can be represented at a time.
// The struct is 24B large on 64-bit systems and requires the minimum storage
// necessary to represent each possible type.
//
// The Go GC needs to be able to scan variables containing pointers.
// As such, pointers and non-pointers cannot be intermixed.
type value struct {
pragma.DoNotCompare // 0B
// typ stores the type of the value as a pointer to the Go type.
typ unsafe.Pointer // 8B
// ptr stores the data pointer for a String, Bytes, or interface value.
ptr unsafe.Pointer // 8B
// num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or
// Enum value as a raw uint64.
//
// It is also used to store the length of a String or Bytes value;
// the capacity is ignored.
num uint64 // 8B
}
func valueOfString(v string) Value {
p := (*stringHeader)(unsafe.Pointer(&v))
return Value{typ: stringType, ptr: p.Data, num: uint64(len(v))}
}
func valueOfBytes(v []byte) Value {
p := (*sliceHeader)(unsafe.Pointer(&v))
return Value{typ: bytesType, ptr: p.Data, num: uint64(len(v))}
}
func valueOfIface(v any) Value {
p := (*ifaceHeader)(unsafe.Pointer(&v))
return Value{typ: p.Type, ptr: p.Data}
}
func (v Value) getString() (x string) {
*(*stringHeader)(unsafe.Pointer(&x)) = stringHeader{Data: v.ptr, Len: int(v.num)}
return x
}
func (v Value) getBytes() (x []byte) {
*(*sliceHeader)(unsafe.Pointer(&x)) = sliceHeader{Data: v.ptr, Len: int(v.num), Cap: int(v.num)}
return x
}
func (v Value) getIface() (x any) {
*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
return x
}
@@ -1,87 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && go1.21
// +build !purego,!appengine,go1.21
package protoreflect
import (
"unsafe"
"google.golang.org/protobuf/internal/pragma"
)
type (
ifaceHeader struct {
_ [0]any // if interfaces have greater alignment than unsafe.Pointer, this will enforce it.
Type unsafe.Pointer
Data unsafe.Pointer
}
)
var (
nilType = typeOf(nil)
boolType = typeOf(*new(bool))
int32Type = typeOf(*new(int32))
int64Type = typeOf(*new(int64))
uint32Type = typeOf(*new(uint32))
uint64Type = typeOf(*new(uint64))
float32Type = typeOf(*new(float32))
float64Type = typeOf(*new(float64))
stringType = typeOf(*new(string))
bytesType = typeOf(*new([]byte))
enumType = typeOf(*new(EnumNumber))
)
// typeOf returns a pointer to the Go type information.
// The pointer is comparable and equal if and only if the types are identical.
func typeOf(t any) unsafe.Pointer {
return (*ifaceHeader)(unsafe.Pointer(&t)).Type
}
// value is a union where only one type can be represented at a time.
// The struct is 24B large on 64-bit systems and requires the minimum storage
// necessary to represent each possible type.
//
// The Go GC needs to be able to scan variables containing pointers.
// As such, pointers and non-pointers cannot be intermixed.
type value struct {
pragma.DoNotCompare // 0B
// typ stores the type of the value as a pointer to the Go type.
typ unsafe.Pointer // 8B
// ptr stores the data pointer for a String, Bytes, or interface value.
ptr unsafe.Pointer // 8B
// num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or
// Enum value as a raw uint64.
//
// It is also used to store the length of a String or Bytes value;
// the capacity is ignored.
num uint64 // 8B
}
func valueOfString(v string) Value {
return Value{typ: stringType, ptr: unsafe.Pointer(unsafe.StringData(v)), num: uint64(len(v))}
}
func valueOfBytes(v []byte) Value {
return Value{typ: bytesType, ptr: unsafe.Pointer(unsafe.SliceData(v)), num: uint64(len(v))}
}
func valueOfIface(v any) Value {
p := (*ifaceHeader)(unsafe.Pointer(&v))
return Value{typ: p.Type, ptr: p.Data}
}
func (v Value) getString() string {
return unsafe.String((*byte)(v.ptr), v.num)
}
func (v Value) getBytes() []byte {
return unsafe.Slice((*byte)(v.ptr), v.num)
}
func (v Value) getIface() (x any) {
*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
return x
}
@@ -39,6 +39,9 @@ type Methods = struct {
// CheckInitialized returns an error if any required fields in the message are not set.
CheckInitialized func(CheckInitializedInput) (CheckInitializedOutput, error)
// Equal compares two messages and returns EqualOutput.Equal == true if they are equal.
Equal func(EqualInput) EqualOutput
}
// SupportFlags indicate support for optional features.
@@ -119,6 +122,22 @@ type UnmarshalInputFlags = uint8
const (
UnmarshalDiscardUnknown UnmarshalInputFlags = 1 << iota
// UnmarshalAliasBuffer permits unmarshal operations to alias the input buffer.
// The unmarshaller must not modify the contents of the buffer.
UnmarshalAliasBuffer
// UnmarshalValidated indicates that validation has already been
// performed on the input buffer.
UnmarshalValidated
// UnmarshalCheckRequired is set if this unmarshal operation ultimately will care if required fields are
// initialized.
UnmarshalCheckRequired
// UnmarshalNoLazyDecoding is set if this unmarshal operation should not use
// lazy decoding, even when otherwise available.
UnmarshalNoLazyDecoding
)
// UnmarshalOutputFlags are output from the Unmarshal method.
@@ -166,3 +185,18 @@ type CheckInitializedInput = struct {
type CheckInitializedOutput = struct {
pragma.NoUnkeyedLiterals
}
// EqualInput is input to the Equal method.
type EqualInput = struct {
pragma.NoUnkeyedLiterals
MessageA protoreflect.Message
MessageB protoreflect.Message
}
// EqualOutput is output from the Equal method.
type EqualOutput = struct {
pragma.NoUnkeyedLiterals
Equal bool
}
+236 -16
View File
@@ -19,9 +19,16 @@ github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/o
github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/options
github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared
github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version
# github.com/Masterminds/semver/v3 v3.4.0
## explicit; go 1.21
github.com/Masterminds/semver/v3
# github.com/PuerkitoBio/goquery v1.8.1
## explicit; go 1.13
github.com/PuerkitoBio/goquery
# github.com/andybalholm/brotli v1.2.0
## explicit; go 1.22
github.com/andybalholm/brotli
github.com/andybalholm/brotli/matchfinder
# github.com/andybalholm/cascadia v1.3.1
## explicit; go 1.16
github.com/andybalholm/cascadia
@@ -108,6 +115,45 @@ github.com/charmbracelet/x/cellbuf
# github.com/charmbracelet/x/term v0.2.1
## explicit; go 1.18
github.com/charmbracelet/x/term
# github.com/cloudflare/circl v1.3.3
## explicit; go 1.19
github.com/cloudflare/circl/dh/x25519
github.com/cloudflare/circl/dh/x448
github.com/cloudflare/circl/ecc/goldilocks
github.com/cloudflare/circl/internal/conv
github.com/cloudflare/circl/internal/sha3
github.com/cloudflare/circl/kem
github.com/cloudflare/circl/kem/hybrid
github.com/cloudflare/circl/kem/kyber/kyber1024
github.com/cloudflare/circl/kem/kyber/kyber512
github.com/cloudflare/circl/kem/kyber/kyber768
github.com/cloudflare/circl/math
github.com/cloudflare/circl/math/fp25519
github.com/cloudflare/circl/math/fp448
github.com/cloudflare/circl/math/mlsbset
github.com/cloudflare/circl/pke/kyber/internal/common
github.com/cloudflare/circl/pke/kyber/internal/common/params
github.com/cloudflare/circl/pke/kyber/kyber1024
github.com/cloudflare/circl/pke/kyber/kyber1024/internal
github.com/cloudflare/circl/pke/kyber/kyber512
github.com/cloudflare/circl/pke/kyber/kyber512/internal
github.com/cloudflare/circl/pke/kyber/kyber768
github.com/cloudflare/circl/pke/kyber/kyber768/internal
github.com/cloudflare/circl/pki
github.com/cloudflare/circl/sign
github.com/cloudflare/circl/sign/dilithium/internal/common
github.com/cloudflare/circl/sign/dilithium/internal/common/params
github.com/cloudflare/circl/sign/dilithium/mode2
github.com/cloudflare/circl/sign/dilithium/mode2/internal
github.com/cloudflare/circl/sign/dilithium/mode3
github.com/cloudflare/circl/sign/dilithium/mode3/internal
github.com/cloudflare/circl/sign/ed25519
github.com/cloudflare/circl/sign/ed448
github.com/cloudflare/circl/sign/eddilithium2
github.com/cloudflare/circl/sign/eddilithium3
github.com/cloudflare/circl/sign/schemes
github.com/cloudflare/circl/simd/keccakf1600
github.com/cloudflare/circl/xof
# github.com/cloudwego/base64x v0.1.4
## explicit; go 1.16
github.com/cloudwego/base64x
@@ -118,6 +164,78 @@ github.com/cloudwego/iasm/x86_64
# github.com/davecgh/go-spew v1.1.1
## explicit
github.com/davecgh/go-spew/spew
# github.com/enetx/g v1.0.194
## explicit; go 1.24.0
github.com/enetx/g
github.com/enetx/g/cell
github.com/enetx/g/cmp
github.com/enetx/g/constraints
github.com/enetx/g/f
github.com/enetx/g/internal/filelock
github.com/enetx/g/internal/filelock/syscall/windows
github.com/enetx/g/internal/filelock/syscall/windows/sysdll
github.com/enetx/g/rand
github.com/enetx/g/ref
# github.com/enetx/http v1.0.19
## explicit; go 1.24.0
github.com/enetx/http
github.com/enetx/http/cookiejar
github.com/enetx/http/httptrace
github.com/enetx/http/httputil
github.com/enetx/http/internal
github.com/enetx/http/internal/ascii
github.com/enetx/http/internal/nettrace
# github.com/enetx/http2 v1.0.20
## explicit; go 1.24.0
github.com/enetx/http2
github.com/enetx/http2/httpcommon
# github.com/enetx/iter v0.0.0-20250912135656-f1583323588f
## explicit; go 1.24
github.com/enetx/iter
# github.com/enetx/surf v1.0.141
## explicit; go 1.24.0
github.com/enetx/surf
github.com/enetx/surf/header
github.com/enetx/surf/internal/drainbody
github.com/enetx/surf/internal/specclone
github.com/enetx/surf/pkg/connectproxy
github.com/enetx/surf/pkg/quicconn
github.com/enetx/surf/pkg/sse
github.com/enetx/surf/profiles/chrome
github.com/enetx/surf/profiles/firefox
# github.com/enetx/uquic v0.0.0-20250922085439-3a2249d297c9
## explicit; go 1.24.0
github.com/enetx/uquic
github.com/enetx/uquic/http3
github.com/enetx/uquic/http3/httpcommon
github.com/enetx/uquic/internal/ackhandler
github.com/enetx/uquic/internal/congestion
github.com/enetx/uquic/internal/flowcontrol
github.com/enetx/uquic/internal/handshake
github.com/enetx/uquic/internal/logutils
github.com/enetx/uquic/internal/protocol
github.com/enetx/uquic/internal/qerr
github.com/enetx/uquic/internal/qtls
github.com/enetx/uquic/internal/utils
github.com/enetx/uquic/internal/utils/linkedlist
github.com/enetx/uquic/internal/utils/ringbuffer
github.com/enetx/uquic/internal/wire
github.com/enetx/uquic/logging
github.com/enetx/uquic/quicvarint
# github.com/enetx/utls v0.0.0-20251024090823-efbd194d7328
## explicit; go 1.24.0
github.com/enetx/utls
github.com/enetx/utls/dicttls
github.com/enetx/utls/internal/boring
github.com/enetx/utls/internal/byteorder
github.com/enetx/utls/internal/fips140tls
github.com/enetx/utls/internal/helper
github.com/enetx/utls/internal/hkdf
github.com/enetx/utls/internal/hpke
github.com/enetx/utls/internal/quicvarint
github.com/enetx/utls/internal/quicvarint/protocol
github.com/enetx/utls/internal/tls12
github.com/enetx/utls/internal/tls13
# github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f
## explicit; go 1.16
github.com/erikgeiser/coninput
@@ -133,6 +251,13 @@ github.com/gabriel-vasile/mimetype
github.com/gabriel-vasile/mimetype/internal/charset
github.com/gabriel-vasile/mimetype/internal/json
github.com/gabriel-vasile/mimetype/internal/magic
# github.com/gaukas/clienthellod v0.4.2
## explicit; go 1.20
github.com/gaukas/clienthellod
github.com/gaukas/clienthellod/internal/utils
# github.com/gaukas/godicttls v0.0.4
## explicit; go 1.19
github.com/gaukas/godicttls
# github.com/gin-contrib/sse v0.1.0
## explicit; go 1.12
github.com/gin-contrib/sse
@@ -159,6 +284,9 @@ github.com/go-playground/universal-translator
# github.com/go-playground/validator/v10 v10.22.0
## explicit; go 1.18
github.com/go-playground/validator/v10
# github.com/go-task/slim-sprig/v3 v3.0.0
## explicit; go 1.20
github.com/go-task/slim-sprig/v3
# github.com/goccy/go-json v0.10.3
## explicit; go 1.19
github.com/goccy/go-json
@@ -173,7 +301,14 @@ github.com/goccy/go-json/internal/runtime
# github.com/golang-jwt/jwt/v5 v5.2.2
## explicit; go 1.18
github.com/golang-jwt/jwt/v5
# github.com/google/uuid v1.3.0
# github.com/google/gopacket v1.1.19
## explicit; go 1.12
github.com/google/gopacket
github.com/google/gopacket/layers
# github.com/google/pprof v0.0.0-20250403155104-27863c87afa6
## explicit; go 1.23
github.com/google/pprof/profile
# github.com/google/uuid v1.3.1
## explicit
github.com/google/uuid
# github.com/jinzhu/inflection v1.0.0
@@ -185,6 +320,16 @@ github.com/jinzhu/now
# github.com/json-iterator/go v1.1.12
## explicit; go 1.12
github.com/json-iterator/go
# github.com/klauspost/compress v1.18.1
## explicit; go 1.23
github.com/klauspost/compress
github.com/klauspost/compress/fse
github.com/klauspost/compress/huff0
github.com/klauspost/compress/internal/cpuinfo
github.com/klauspost/compress/internal/le
github.com/klauspost/compress/internal/snapref
github.com/klauspost/compress/zstd
github.com/klauspost/compress/zstd/internal/xxhash
# github.com/klauspost/cpuid/v2 v2.2.8
## explicit; go 1.15
github.com/klauspost/cpuid/v2
@@ -243,6 +388,26 @@ github.com/muesli/termenv
# github.com/oapi-codegen/nullable v1.1.0
## explicit; go 1.20
github.com/oapi-codegen/nullable
# github.com/onsi/ginkgo/v2 v2.27.2
## explicit; go 1.23.0
github.com/onsi/ginkgo/v2/config
github.com/onsi/ginkgo/v2/formatter
github.com/onsi/ginkgo/v2/ginkgo
github.com/onsi/ginkgo/v2/ginkgo/automaxprocs
github.com/onsi/ginkgo/v2/ginkgo/build
github.com/onsi/ginkgo/v2/ginkgo/command
github.com/onsi/ginkgo/v2/ginkgo/generators
github.com/onsi/ginkgo/v2/ginkgo/internal
github.com/onsi/ginkgo/v2/ginkgo/labels
github.com/onsi/ginkgo/v2/ginkgo/outline
github.com/onsi/ginkgo/v2/ginkgo/run
github.com/onsi/ginkgo/v2/ginkgo/unfocus
github.com/onsi/ginkgo/v2/ginkgo/watch
github.com/onsi/ginkgo/v2/internal/interrupt_handler
github.com/onsi/ginkgo/v2/internal/parallel_support
github.com/onsi/ginkgo/v2/internal/reporters
github.com/onsi/ginkgo/v2/reporters
github.com/onsi/ginkgo/v2/types
# github.com/pelletier/go-toml/v2 v2.2.2
## explicit; go 1.16
github.com/pelletier/go-toml/v2
@@ -259,6 +424,18 @@ github.com/pquerna/otp
github.com/pquerna/otp/hotp
github.com/pquerna/otp/internal
github.com/pquerna/otp/totp
# github.com/quic-go/qpack v0.5.1
## explicit; go 1.22
github.com/quic-go/qpack
# github.com/quic-go/quic-go v0.39.0
## explicit; go 1.20
github.com/quic-go/quic-go/internal/protocol
github.com/quic-go/quic-go/quicvarint
# github.com/refraction-networking/utls v1.5.4
## explicit; go 1.20
github.com/refraction-networking/utls
github.com/refraction-networking/utls/internal/boring
github.com/refraction-networking/utls/internal/helper
# github.com/rivo/uniseg v0.4.7
## explicit; go 1.18
github.com/rivo/uniseg
@@ -297,6 +474,9 @@ github.com/wneessen/go-mail
github.com/wneessen/go-mail/internal/pkcs7
github.com/wneessen/go-mail/log
github.com/wneessen/go-mail/smtp
# github.com/wzshiming/socks5 v0.6.0
## explicit; go 1.15
github.com/wzshiming/socks5
# github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e
## explicit; go 1.19
github.com/xo/terminfo
@@ -319,6 +499,10 @@ github.com/zeebo/blake3/internal/alg/hash/hash_avx2
github.com/zeebo/blake3/internal/alg/hash/hash_pure
github.com/zeebo/blake3/internal/consts
github.com/zeebo/blake3/internal/utils
# go.uber.org/mock v0.6.0
## explicit; go 1.23.0
go.uber.org/mock/mockgen
go.uber.org/mock/mockgen/model
# go.uber.org/multierr v1.11.0
## explicit; go 1.19
go.uber.org/multierr
@@ -336,24 +520,38 @@ go.uber.org/zap/zapcore
# golang.org/x/arch v0.9.0
## explicit; go 1.18
golang.org/x/arch/x86/x86asm
# golang.org/x/crypto v0.41.0
## explicit; go 1.23.0
# golang.org/x/crypto v0.43.0
## explicit; go 1.24.0
golang.org/x/crypto/argon2
golang.org/x/crypto/blake2b
golang.org/x/crypto/blake2s
golang.org/x/crypto/chacha20
golang.org/x/crypto/chacha20poly1305
golang.org/x/crypto/cryptobyte
golang.org/x/crypto/cryptobyte/asn1
golang.org/x/crypto/hkdf
golang.org/x/crypto/internal/alias
golang.org/x/crypto/internal/poly1305
golang.org/x/crypto/ocsp
golang.org/x/crypto/sha3
# golang.org/x/mod v0.27.0
## explicit; go 1.23.0
# golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546
## explicit; go 1.24.0
golang.org/x/exp/rand
# golang.org/x/mod v0.29.0
## explicit; go 1.24.0
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile
golang.org/x/mod/module
golang.org/x/mod/semver
# golang.org/x/net v0.43.0
## explicit; go 1.23.0
# golang.org/x/net v0.46.0
## explicit; go 1.24.0
golang.org/x/net/bpf
golang.org/x/net/context
golang.org/x/net/html
golang.org/x/net/html/atom
golang.org/x/net/html/charset
golang.org/x/net/http/httpguts
golang.org/x/net/http/httpproxy
golang.org/x/net/http2
golang.org/x/net/http2/h2c
golang.org/x/net/http2/hpack
@@ -361,23 +559,37 @@ golang.org/x/net/idna
golang.org/x/net/internal/httpcommon
golang.org/x/net/internal/iana
golang.org/x/net/internal/socket
golang.org/x/net/internal/socks
golang.org/x/net/ipv4
golang.org/x/net/ipv6
golang.org/x/net/proxy
golang.org/x/net/publicsuffix
# golang.org/x/sync v0.17.0
## explicit; go 1.24.0
golang.org/x/sync/errgroup
# golang.org/x/sys v0.35.0
## explicit; go 1.23.0
# golang.org/x/sys v0.37.0
## explicit; go 1.24.0
golang.org/x/sys/cpu
golang.org/x/sys/unix
golang.org/x/sys/windows
# golang.org/x/text v0.29.0
# golang.org/x/text v0.30.0
## explicit; go 1.24.0
golang.org/x/text/cases
golang.org/x/text/encoding
golang.org/x/text/encoding/charmap
golang.org/x/text/encoding/htmlindex
golang.org/x/text/encoding/internal
golang.org/x/text/encoding/internal/identifier
golang.org/x/text/encoding/japanese
golang.org/x/text/encoding/korean
golang.org/x/text/encoding/simplifiedchinese
golang.org/x/text/encoding/traditionalchinese
golang.org/x/text/encoding/unicode
golang.org/x/text/internal
golang.org/x/text/internal/language
golang.org/x/text/internal/language/compact
golang.org/x/text/internal/tag
golang.org/x/text/internal/utf8internal
golang.org/x/text/language
golang.org/x/text/runes
golang.org/x/text/secure/bidirule
@@ -386,15 +598,20 @@ golang.org/x/text/transform
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
golang.org/x/text/width
# golang.org/x/time v0.3.0
## explicit
# golang.org/x/time v0.14.0
## explicit; go 1.24.0
golang.org/x/time/rate
# golang.org/x/tools v0.36.0
## explicit; go 1.23.0
# golang.org/x/tools v0.38.0
## explicit; go 1.24.0
golang.org/x/tools/cover
golang.org/x/tools/go/ast/astutil
golang.org/x/tools/go/ast/edge
golang.org/x/tools/go/ast/inspector
golang.org/x/tools/go/gcexportdata
golang.org/x/tools/go/packages
golang.org/x/tools/go/types/objectpath
golang.org/x/tools/go/types/typeutil
golang.org/x/tools/imports
golang.org/x/tools/internal/aliases
golang.org/x/tools/internal/event
golang.org/x/tools/internal/event/core
@@ -402,14 +619,17 @@ golang.org/x/tools/internal/event/keys
golang.org/x/tools/internal/event/label
golang.org/x/tools/internal/gcimporter
golang.org/x/tools/internal/gocommand
golang.org/x/tools/internal/gopathwalk
golang.org/x/tools/internal/imports
golang.org/x/tools/internal/modindex
golang.org/x/tools/internal/packagesinternal
golang.org/x/tools/internal/pkgbits
golang.org/x/tools/internal/stdlib
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
golang.org/x/tools/internal/versions
# google.golang.org/protobuf v1.34.2
## explicit; go 1.20
# google.golang.org/protobuf v1.36.7
## explicit; go 1.22
google.golang.org/protobuf/encoding/protowire
google.golang.org/protobuf/internal/detrand
google.golang.org/protobuf/internal/encoding/messageset