update deps
This commit is contained in:
parent
449762ae99
commit
2994ff9ede
214 changed files with 128929 additions and 185043 deletions
|
|
@ -4,8 +4,6 @@ run:
|
|||
issues-exit-code: 1
|
||||
tests: true
|
||||
build-tags: []
|
||||
skip-dirs-use-default: true
|
||||
skip-files: []
|
||||
modules-download-mode: readonly
|
||||
|
||||
output:
|
||||
|
|
@ -118,6 +116,7 @@ linters:
|
|||
|
||||
|
||||
issues:
|
||||
exclude-dirs-use-default: true
|
||||
exclude-dirs:
|
||||
- mocks
|
||||
exclude-rules:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
zlogsentry "github.com/archdx/zerolog-sentry"
|
||||
"github.com/etkecc/go-healthchecks/v2"
|
||||
"github.com/etkecc/go-linkpearl"
|
||||
"github.com/etkecc/go-psd"
|
||||
"github.com/getsentry/sentry-go"
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/mileusna/crontab"
|
||||
|
|
@ -126,10 +125,9 @@ func initMatrix(cfg *config.Config) {
|
|||
log.Fatal().Err(err).Msg("cannot initialize matrix bot")
|
||||
}
|
||||
|
||||
psdc := psd.NewClient(cfg.PSD.URL, cfg.PSD.Login, cfg.PSD.Password)
|
||||
mxc = mxconfig.New(lp, &log, cfg.DKIM.PrivKey, cfg.DKIM.Signature)
|
||||
q = queue.New(lp, mxc, &log)
|
||||
mxb, err = bot.New(q, lp, &log, mxc, psdc, cfg.Proxies, cfg.Prefix, cfg.Domains, cfg.Admins, bot.MBXConfig(cfg.Mailboxes))
|
||||
mxb, err = bot.New(q, lp, &log, mxc, cfg.Proxies, cfg.Prefix, cfg.Domains, cfg.Admins, bot.MBXConfig(cfg.Mailboxes))
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("cannot start matrix bot")
|
||||
}
|
||||
|
|
|
|||
42
go.mod
42
go.mod
|
|
@ -1,8 +1,8 @@
|
|||
module github.com/etkecc/postmoogle
|
||||
|
||||
go 1.22.0
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.1
|
||||
toolchain go1.23.5
|
||||
|
||||
require (
|
||||
github.com/archdx/zerolog-sentry v1.8.5
|
||||
|
|
@ -13,14 +13,13 @@ require (
|
|||
github.com/etkecc/go-fswatcher v1.0.1
|
||||
github.com/etkecc/go-healthchecks/v2 v2.2.2
|
||||
github.com/etkecc/go-kit v1.5.0
|
||||
github.com/etkecc/go-linkpearl v0.0.0-20241219100412-83bcd2416637
|
||||
github.com/etkecc/go-linkpearl v0.0.0-20250217075507-d5e511599d5c
|
||||
github.com/etkecc/go-mxidwc v1.0.1
|
||||
github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8
|
||||
github.com/etkecc/go-secgen v1.4.0
|
||||
github.com/etkecc/go-validator/v2 v2.2.4
|
||||
github.com/fsnotify/fsnotify v1.8.0
|
||||
github.com/gabriel-vasile/mimetype v1.4.7
|
||||
github.com/getsentry/sentry-go v0.30.0
|
||||
github.com/gabriel-vasile/mimetype v1.4.8
|
||||
github.com/getsentry/sentry-go v0.31.1
|
||||
github.com/jhillyerd/enmime v1.3.0
|
||||
github.com/kvannotten/mailstrip v0.0.0-20200711213611-0002f5c0467e
|
||||
github.com/lib/pq v1.10.9
|
||||
|
|
@ -29,9 +28,9 @@ require (
|
|||
github.com/raja/argon2pw v1.0.2-0.20210910183755-a391af63bd39
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/swaggo/swag v1.16.3
|
||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67
|
||||
maunium.net/go/mautrix v0.22.1
|
||||
modernc.org/sqlite v1.34.3
|
||||
golang.org/x/exp v0.0.0-20250215185904-eff6e970281f
|
||||
maunium.net/go/mautrix v0.23.1
|
||||
modernc.org/sqlite v1.35.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
@ -54,13 +53,13 @@ require (
|
|||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
|
|
@ -70,17 +69,14 @@ require (
|
|||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/yuin/goldmark v1.7.8 // indirect
|
||||
go.mau.fi/util v0.8.3 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
go.mau.fi/util v0.8.5 // indirect
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/tools v0.30.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 // indirect
|
||||
modernc.org/libc v1.61.4 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
modernc.org/libc v1.61.13 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.8.2 // indirect
|
||||
)
|
||||
|
|
|
|||
117
go.sum
117
go.sum
|
|
@ -38,12 +38,10 @@ github.com/etkecc/go-healthchecks/v2 v2.2.2 h1:YV7e+Ga8JY3aZX4Qf6Q1Ca+DnqbT5Drjl
|
|||
github.com/etkecc/go-healthchecks/v2 v2.2.2/go.mod h1:IowWGN4F6By6z0eh63+639OscylgtdvT9ITjfN6hnZA=
|
||||
github.com/etkecc/go-kit v1.5.0 h1:i7QxpWxgoIBEDbUW5dbaDHnwbVXDCHw3Y5B9Xm++v0k=
|
||||
github.com/etkecc/go-kit v1.5.0/go.mod h1:yikghi8YaYbTjRXNtx82g0LFv90YqZi2vLf5Chw0ysg=
|
||||
github.com/etkecc/go-linkpearl v0.0.0-20241219100412-83bcd2416637 h1:IpNGgNynfoTqz5JQRx1PKa6pXLlOQ90u9YJ3UKTTIa8=
|
||||
github.com/etkecc/go-linkpearl v0.0.0-20241219100412-83bcd2416637/go.mod h1:frjbaXFfD9H4X7JbCyeBEQ2fgkSm6/67tiR9NTgcx58=
|
||||
github.com/etkecc/go-linkpearl v0.0.0-20250217075507-d5e511599d5c h1:fjRauzmHqH42Dq8BKIe5y4RcGzQnF+/OQdm/uyXp12U=
|
||||
github.com/etkecc/go-linkpearl v0.0.0-20250217075507-d5e511599d5c/go.mod h1:NydJ3vV/L1muFhXphAlgFcrPHAC3knjlJFoQkZgp+AE=
|
||||
github.com/etkecc/go-mxidwc v1.0.1 h1:t4Kq3FxSlQjt1i7RpzE5q3cOWjJ0vrTzzGZRSpgh8mg=
|
||||
github.com/etkecc/go-mxidwc v1.0.1/go.mod h1:WFlntcH4mdual/gNi6X7a6rSJERNuLjdrwM3K/tucQA=
|
||||
github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8 h1:ariQTBlHHe71O507IZ97QSHFrk0Eo2vlMm1skJ97Y7Q=
|
||||
github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8/go.mod h1:x4ORuml+JdRsska0sXHbpSQAqvQyqDLjXydP5Ax5wBg=
|
||||
github.com/etkecc/go-secgen v1.4.0 h1:PapLpen3aIqG2LDu+U6KWDb4SMW2UGuvetpJjd86yUc=
|
||||
github.com/etkecc/go-secgen v1.4.0/go.mod h1:6dkfdOtmtVxkj1hIJM6U6yA7frSNpr1H5brz5t18Y3I=
|
||||
github.com/etkecc/go-trysmtp v1.1.5 h1:MQ4l4bE9nWUqRKoJOalGHGLkb/hRmzbcBMlClufEOng=
|
||||
|
|
@ -52,10 +50,10 @@ github.com/etkecc/go-validator/v2 v2.2.4 h1:E4sE4FpYPVP6VRvnndni+8qUXbeSuHxkniFs
|
|||
github.com/etkecc/go-validator/v2 v2.2.4/go.mod h1:5VX2VICgMALoFBiGc02p/6RjQ8ifRxZ0KOuLAH5fTe0=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
||||
github.com/getsentry/sentry-go v0.30.0 h1:lWUwDnY7sKHaVIoZ9wYqRHJ5iEmoc0pqcRqFkosKzBo=
|
||||
github.com/getsentry/sentry-go v0.30.0/go.mod h1:WU9B9/1/sHDqeV8T+3VwwbjeR5MSXs/6aqG3mqZrezA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/getsentry/sentry-go v0.31.1 h1:ELVc0h7gwyhnXHDouXkhqTFSO5oslsRDk0++eyE0KJ4=
|
||||
github.com/getsentry/sentry-go v0.31.1/go.mod h1:CYNcMMz73YigoHljQRG+qPF+eMq8gG72XcGN/p71BAY=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
|
|
@ -88,6 +86,8 @@ github.com/jhillyerd/enmime v1.3.0/go.mod h1:6c6jg5HdRRV2FtvVL69LjiX1M8oE0xDX9VE
|
|||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
|
|
@ -101,8 +101,9 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
|
|||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
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-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
|
|
@ -120,12 +121,11 @@ github.com/mileusna/crontab v1.2.0 h1:x9ZmE2A4p6CDqMEGQ+GbqsNtnmbdmWMQYShdQu8Lvr
|
|||
github.com/mileusna/crontab v1.2.0/go.mod h1:dbns64w/u3tUnGZGf8pAa76ZqOfeBX4olW4U1ZwExmc=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 h1:ah1dvbqPMN5+ocrg/ZSgZ6k8bOk+kcZQ7fnyx6UvOm4=
|
||||
github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||
github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a h1:ckxP/kGzsxvxXo8jO6E/0QJ8MMmwI7IRj4Fys9QbAZA=
|
||||
github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
|
@ -139,6 +139,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq
|
|||
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.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
|
|
@ -163,41 +165,44 @@ 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/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
||||
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
go.mau.fi/util v0.8.3 h1:sulhXtfquMrQjsOP67x9CzWVBYUwhYeoo8hNQIpCWZ4=
|
||||
go.mau.fi/util v0.8.3/go.mod h1:c00Db8xog70JeIsEvhdHooylTkTkakgnAOsZ04hplQY=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
|
||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
go.mau.fi/util v0.8.5 h1:PwCAAtcfK0XxZ4sdErJyfBMkTEWoQU33aB7QqDDzQRI=
|
||||
go.mau.fi/util v0.8.5/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/exp v0.0.0-20250215185904-eff6e970281f h1:oFMYAjX0867ZD2jcNiLBrI9BdpmEkvPyi5YrBGXbamg=
|
||||
golang.org/x/exp v0.0.0-20250215185904-eff6e970281f/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
|
@ -205,31 +210,29 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/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=
|
||||
maunium.net/go/mautrix v0.22.1 h1:2lCM37vmVzZGE0tWD7UOySMtAuC5hq6Pw33KlY2VU/c=
|
||||
maunium.net/go/mautrix v0.22.1/go.mod h1:1rhqwH34Rz54ZqzdQYkmNW6rQUymNeTdaLA4l9LK6AI=
|
||||
modernc.org/cc/v4 v4.23.1 h1:WqJoPL3x4cUufQVHkXpXX7ThFJ1C4ik80i2eXEXbhD8=
|
||||
modernc.org/cc/v4 v4.23.1/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.23.1 h1:N49a7JiWGWV7lkPE4yYcvjkBGZQi93/JabRYjdWmJXc=
|
||||
modernc.org/ccgo/v4 v4.23.1/go.mod h1:JoIUegEIfutvoWV/BBfDFpPpfR2nc3U0jKucGcbmwDU=
|
||||
maunium.net/go/mautrix v0.23.1 h1:xZtX43YZF3WRxkdR+oMUrpiQe+jbjc+LeXLxHuXP5IM=
|
||||
maunium.net/go/mautrix v0.23.1/go.mod h1:kldoZQDneV/jquIhwG1MmMw5j2A2M/MnQYRSWt863cY=
|
||||
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
||||
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.23.16 h1:Z2N+kk38b7SfySC1ZkpGLN2vthNJP1+ZzGZIlH7uBxo=
|
||||
modernc.org/ccgo/v4 v4.23.16/go.mod h1:nNma8goMTY7aQZQNTyN9AIoJfxav4nvTnvKThAeMDdo=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M=
|
||||
modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 h1:ovz6yUKX71igz2yvk4NpiCL5fvdjZAI+DhuDEGx1xyU=
|
||||
modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.61.4 h1:wVyqEx6tlltte9lPTjq0kDAdtdM9c4JH8rU6M1ZVawA=
|
||||
modernc.org/libc v1.61.4/go.mod h1:VfXVuM/Shh5XsMNrh3C6OkfL78G3loa4ZC/Ljv9k7xc=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.34.3 h1:494MIwJKBLd0tErBYkRar2HvEpy04Bl0ykPEm4XLhbo=
|
||||
modernc.org/sqlite v1.34.3/go.mod h1:dnR723UrTtjKpoHCAMN0Q/gZ9MT4r+iRvIBb9umWFkU=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw=
|
||||
modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8=
|
||||
modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.8.2 h1:cL9L4bcoAObu4NkxOlKWBWtNHIsnnACGF/TbqQ6sbcI=
|
||||
modernc.org/memory v1.8.2/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU=
|
||||
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.35.0 h1:yQps4fegMnZFdphtzlfQTCNBWtS0CZv48pRpW3RFHRw=
|
||||
modernc.org/sqlite v1.35.0/go.mod h1:9cr2sicr7jIaWTBKQmAxQLfBv9LL0su4ZTEV+utt3ic=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
"github.com/etkecc/go-kit"
|
||||
"github.com/etkecc/go-linkpearl"
|
||||
"github.com/etkecc/go-psd"
|
||||
"github.com/rs/zerolog"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
|
@ -38,7 +37,6 @@ type Bot struct {
|
|||
rooms sync.Map
|
||||
proxies []string
|
||||
sendmail func(string, string, string, *url.URL) error
|
||||
psdc *psd.Client
|
||||
cfg *config.Manager
|
||||
log *zerolog.Logger
|
||||
lp *linkpearl.Linkpearl
|
||||
|
|
@ -53,7 +51,6 @@ func New(
|
|||
lp *linkpearl.Linkpearl,
|
||||
log *zerolog.Logger,
|
||||
cfg *config.Manager,
|
||||
psdc *psd.Client,
|
||||
proxies []string,
|
||||
prefix string,
|
||||
domains []string,
|
||||
|
|
@ -67,7 +64,6 @@ func New(
|
|||
adminRooms: []id.RoomID{},
|
||||
proxies: proxies,
|
||||
mbxc: mbxc,
|
||||
psdc: psdc,
|
||||
cfg: cfg,
|
||||
log: log,
|
||||
lp: lp,
|
||||
|
|
|
|||
|
|
@ -163,13 +163,13 @@ func (b *Bot) IncomingEmail(ctx context.Context, eml *email.Email) error {
|
|||
if cfg.Stripify() && !cfg.Threadify() {
|
||||
contentOpts := cfg.ContentOptions()
|
||||
contentOpts.Stripify = false
|
||||
content := eml.Content(threadID, contentOpts, b.psdc)
|
||||
content := eml.Content(threadID, contentOpts)
|
||||
eml.Files = append(eml.Files, //nolint:forcetypeassert // that's ok
|
||||
utils.NewFile("original.md", []byte(content.Parsed.(*event.MessageEventContent).Body)), //nolint:errcheck // that's ok
|
||||
)
|
||||
}
|
||||
|
||||
content := eml.Content(threadID, cfg.ContentOptions(), b.psdc)
|
||||
content := eml.Content(threadID, cfg.ContentOptions())
|
||||
eventID, serr := b.lp.Send(ctx, roomID, content)
|
||||
if serr != nil {
|
||||
if !strings.Contains(serr.Error(), "M_UNKNOWN") { // if it's not an unknown event error
|
||||
|
|
@ -560,7 +560,7 @@ func (b *Bot) saveSentMetadata(ctx context.Context, queued bool, threadID id.Eve
|
|||
}
|
||||
|
||||
evt := eventFromContext(ctx)
|
||||
content := eml.Content(threadID, cfg.ContentOptions(), b.psdc)
|
||||
content := eml.Content(threadID, cfg.ContentOptions())
|
||||
notice := format.RenderMarkdown(text, true, true)
|
||||
msgContent, ok := content.Parsed.(*event.MessageEventContent)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -52,11 +52,6 @@ func New() *Config {
|
|||
DSN: env.String("db.dsn", defaultConfig.DB.DSN),
|
||||
Dialect: env.String("db.dialect", defaultConfig.DB.Dialect),
|
||||
},
|
||||
PSD: PSD{
|
||||
URL: env.String("psd.url"),
|
||||
Login: env.String("psd.login"),
|
||||
Password: env.String("psd.password"),
|
||||
},
|
||||
Relay: Relay{
|
||||
Host: env.String("relay.host", defaultConfig.Relay.Host),
|
||||
Port: env.String("relay.port", defaultConfig.Relay.Port),
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ type Config struct {
|
|||
// DB config
|
||||
DB DB
|
||||
|
||||
// PSD config
|
||||
PSD PSD
|
||||
|
||||
// TLS config
|
||||
TLS TLS
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
"github.com/emersion/go-msgauth/dkim"
|
||||
"github.com/etkecc/go-linkpearl"
|
||||
"github.com/etkecc/go-psd"
|
||||
"github.com/jhillyerd/enmime"
|
||||
"github.com/kvannotten/mailstrip"
|
||||
"maunium.net/go/mautrix/event"
|
||||
|
|
@ -110,17 +109,8 @@ func (e *Email) Mailbox(incoming bool) string {
|
|||
return utils.Mailbox(e.From)
|
||||
}
|
||||
|
||||
func (e *Email) addressStatus(email string, psdc *psd.Client) string {
|
||||
targets, _ := psdc.Get(email) //nolint:errcheck // that's ok
|
||||
if len(targets) > 0 {
|
||||
return "👥" + targets[0].GetDomain() + " 👤"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *Email) contentHeader(threadID id.EventID, text *strings.Builder, options *ContentOptions, psdc *psd.Client) {
|
||||
func (e *Email) contentHeader(threadID id.EventID, text *strings.Builder, options *ContentOptions) {
|
||||
if options.Sender {
|
||||
text.WriteString(e.addressStatus(e.From, psdc))
|
||||
text.WriteString(e.From)
|
||||
}
|
||||
if options.Recipient {
|
||||
|
|
@ -136,12 +126,8 @@ func (e *Email) contentHeader(threadID id.EventID, text *strings.Builder, option
|
|||
}
|
||||
}
|
||||
if options.CC && len(e.CC) > 0 {
|
||||
ccs := make([]string, 0, len(e.CC))
|
||||
for _, addr := range e.CC {
|
||||
ccs = append(ccs, e.addressStatus(addr, psdc)+addr)
|
||||
}
|
||||
text.WriteString("\ncc: ")
|
||||
text.WriteString(strings.Join(ccs, ", "))
|
||||
text.WriteString(strings.Join(e.CC, ", "))
|
||||
}
|
||||
if options.Sender || options.Recipient || options.CC {
|
||||
text.WriteString("\n\n")
|
||||
|
|
@ -161,10 +147,10 @@ func (e *Email) contentHeader(threadID id.EventID, text *strings.Builder, option
|
|||
}
|
||||
|
||||
// Content converts the email object to a Matrix event content
|
||||
func (e *Email) Content(threadID id.EventID, options *ContentOptions, psdc *psd.Client) *event.Content {
|
||||
func (e *Email) Content(threadID id.EventID, options *ContentOptions) *event.Content {
|
||||
var text strings.Builder
|
||||
|
||||
e.contentHeader(threadID, &text, options, psdc)
|
||||
e.contentHeader(threadID, &text, options)
|
||||
|
||||
if threadID != "" || (threadID == "" && !options.Threadify) {
|
||||
if e.HTML != "" && options.HTML {
|
||||
|
|
|
|||
13
vendor/github.com/etkecc/go-linkpearl/linkpearl.go
generated
vendored
13
vendor/github.com/etkecc/go-linkpearl/linkpearl.go
generated
vendored
|
|
@ -139,15 +139,6 @@ func (l *Linkpearl) GetAccountDataCrypter() *Crypter {
|
|||
return l.acr
|
||||
}
|
||||
|
||||
// SetPresence (own). See https://spec.matrix.org/v1.3/client-server-api/#put_matrixclientv3presenceuseridstatus
|
||||
func (l *Linkpearl) SetPresence(ctx context.Context, presence event.Presence, message string) error {
|
||||
req := ReqPresence{Presence: presence, StatusMsg: message}
|
||||
u := l.GetClient().BuildClientURL("v3", "presence", l.GetClient().UserID, "status")
|
||||
_, err := l.GetClient().MakeRequest(ctx, "PUT", u, req, nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// SetJoinPermit sets the join permit callback function
|
||||
func (l *Linkpearl) SetJoinPermit(value func(context.Context, *event.Event) bool) {
|
||||
l.joinPermit = value
|
||||
|
|
@ -161,7 +152,7 @@ func (l *Linkpearl) Start(ctx context.Context, optionalStatusMsg ...string) erro
|
|||
statusMsg = optionalStatusMsg[0]
|
||||
}
|
||||
|
||||
err := l.SetPresence(ctx, event.PresenceOnline, statusMsg)
|
||||
err := l.api.SetPresence(ctx, mautrix.ReqPresence{Presence: event.PresenceOnline, StatusMsg: statusMsg})
|
||||
if err != nil {
|
||||
l.log.Error().Err(err).Msg("cannot set presence")
|
||||
}
|
||||
|
|
@ -174,7 +165,7 @@ func (l *Linkpearl) Start(ctx context.Context, optionalStatusMsg ...string) erro
|
|||
// Stop the client
|
||||
func (l *Linkpearl) Stop(ctx context.Context) {
|
||||
l.log.Debug().Msg("stopping the client")
|
||||
if err := l.api.SetPresence(ctx, event.PresenceOffline); err != nil {
|
||||
if err := l.api.SetPresence(ctx, mautrix.ReqPresence{Presence: event.PresenceOffline}); err != nil {
|
||||
l.log.Error().Err(err).Msg("cannot set presence")
|
||||
}
|
||||
l.api.StopSync()
|
||||
|
|
|
|||
2
vendor/github.com/etkecc/go-linkpearl/sync.go
generated
vendored
2
vendor/github.com/etkecc/go-linkpearl/sync.go
generated
vendored
|
|
@ -74,7 +74,7 @@ func (l *Linkpearl) tryJoin(ctx context.Context, roomID id.RoomID, retry int) {
|
|||
return
|
||||
}
|
||||
|
||||
_, err := l.api.JoinRoom(ctx, roomID.String(), "", nil)
|
||||
_, err := l.api.JoinRoom(ctx, roomID.String(), nil)
|
||||
err = UnwrapError(err)
|
||||
if err != nil {
|
||||
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot join room")
|
||||
|
|
|
|||
166
vendor/github.com/etkecc/go-psd/LICENSE
generated
vendored
166
vendor/github.com/etkecc/go-psd/LICENSE
generated
vendored
|
|
@ -1,166 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
126
vendor/github.com/etkecc/go-psd/client.go
generated
vendored
126
vendor/github.com/etkecc/go-psd/client.go
generated
vendored
|
|
@ -1,126 +0,0 @@
|
|||
package psd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||
)
|
||||
|
||||
// DefaultUserAgent is the default user agent used by the client
|
||||
const DefaultUserAgent = "Go-PSD-client/v0.0.0"
|
||||
|
||||
// Client is the client to interact with the Prometheus Service Discovery HTTP API
|
||||
type Client struct {
|
||||
url *url.URL
|
||||
cache *expirable.LRU[string, cacheValue]
|
||||
login string
|
||||
password string
|
||||
userAgent string
|
||||
}
|
||||
|
||||
type cacheValue struct {
|
||||
data []byte
|
||||
etag string
|
||||
cachedAt string
|
||||
}
|
||||
|
||||
// NewClient returns a new PSD client
|
||||
func NewClient(baseURL, login, password string, userAgentOverride ...string) *Client {
|
||||
uri, err := url.Parse(baseURL)
|
||||
if err != nil || login == "" || password == "" {
|
||||
return &Client{}
|
||||
}
|
||||
|
||||
cache := expirable.NewLRU[string, cacheValue](1000, nil, 5*time.Minute)
|
||||
userAgent := DefaultUserAgent
|
||||
if len(userAgentOverride) > 0 {
|
||||
userAgent = userAgentOverride[0]
|
||||
}
|
||||
|
||||
return &Client{
|
||||
url: uri,
|
||||
cache: cache,
|
||||
login: login,
|
||||
password: password,
|
||||
userAgent: userAgent,
|
||||
}
|
||||
}
|
||||
|
||||
// GetWithContext returns the list of targets for the given identifier using the given context
|
||||
func (p *Client) GetWithContext(ctx context.Context, identifier string, jobOverride ...string) (Items, error) {
|
||||
if p.url == nil {
|
||||
return nil, nil
|
||||
}
|
||||
cloned := *p.url
|
||||
job := "node"
|
||||
if len(jobOverride) > 0 {
|
||||
job = jobOverride[0]
|
||||
}
|
||||
uri := cloned.JoinPath("/" + job + "/" + identifier)
|
||||
urlTarget := uri.String()
|
||||
cachedData, cached := p.cache.Get(urlTarget)
|
||||
|
||||
childCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
req, err := http.NewRequestWithContext(childCtx, http.MethodGet, urlTarget, http.NoBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.SetBasicAuth(p.login, p.password)
|
||||
if cached {
|
||||
req.Header.Set("If-Modified-Since", cachedData.cachedAt)
|
||||
req.Header.Set("If-None-Match", cachedData.etag)
|
||||
}
|
||||
|
||||
req.Header.Set("User-Agent", p.userAgent)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var datab []byte
|
||||
if resp.StatusCode == http.StatusNotModified && cached {
|
||||
datab = cachedData.data
|
||||
} else if resp.StatusCode == http.StatusGone { // not found, to distinguish from reverse proxy 404 error
|
||||
return nil, nil
|
||||
} else if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf("HTTP error: %s", resp.Status) //nolint:goerr113 // that's ok
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if datab == nil {
|
||||
datab, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lastModified := resp.Header.Get("Last-Modified")
|
||||
if lastModified == "" {
|
||||
lastModified = time.Now().Format(http.TimeFormat)
|
||||
}
|
||||
p.cache.Add(urlTarget, cacheValue{
|
||||
data: datab,
|
||||
etag: resp.Header.Get("ETag"),
|
||||
cachedAt: lastModified,
|
||||
})
|
||||
}
|
||||
var psd []*Item
|
||||
err = json.Unmarshal(datab, &psd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return psd, nil
|
||||
}
|
||||
|
||||
// Get returns the list of targets for the given identifier
|
||||
func (p *Client) Get(identifier string) (Items, error) {
|
||||
return p.GetWithContext(context.Background(), identifier)
|
||||
}
|
||||
22
vendor/github.com/etkecc/go-psd/justfile
generated
vendored
22
vendor/github.com/etkecc/go-psd/justfile
generated
vendored
|
|
@ -1,22 +0,0 @@
|
|||
# show help by default
|
||||
default:
|
||||
@just --list --justfile {{ justfile() }}
|
||||
|
||||
# update go deps
|
||||
update *flags:
|
||||
go get {{ flags }} .
|
||||
go mod tidy
|
||||
|
||||
# run linter
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
|
||||
# automatically fix liter issues
|
||||
lintfix:
|
||||
golangci-lint run --fix ./...
|
||||
|
||||
# run unit tests
|
||||
test:
|
||||
@go test -cover -coverprofile=cover.out -coverpkg=./... -covermode=set ./...
|
||||
@go tool cover -func=cover.out
|
||||
-@rm -f cover.out
|
||||
91
vendor/github.com/etkecc/go-psd/model.go
generated
vendored
91
vendor/github.com/etkecc/go-psd/model.go
generated
vendored
|
|
@ -1,91 +0,0 @@
|
|||
package psd
|
||||
|
||||
import "strings"
|
||||
|
||||
// Item is a struct that represents a single set of targets in Prometheus Service Discovery
|
||||
type Item struct {
|
||||
Targets []string `json:"targets"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
||||
|
||||
// GetDomain returns the domain of the target
|
||||
func (i *Item) GetDomain() string {
|
||||
return i.Labels["domain"]
|
||||
}
|
||||
|
||||
// Items is a slice of Prometheus Service Discovery items
|
||||
type Items []*Item
|
||||
|
||||
// GetDomains - get domains from service discovery labels
|
||||
func (items Items) GetDomains() []string {
|
||||
if len(items) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
domainsMap := map[string]struct{}{}
|
||||
for _, item := range items {
|
||||
domain := item.GetDomain()
|
||||
if domain == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := domainsMap[domain]; !ok {
|
||||
domainsMap[domain] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
domains := make([]string, 0, len(domainsMap))
|
||||
for domain := range domainsMap {
|
||||
domains = append(domains, domain)
|
||||
}
|
||||
|
||||
return domains
|
||||
}
|
||||
|
||||
// Contains - check if target exists in service discovery items
|
||||
func (items Items) Contains(needle string) bool {
|
||||
for _, item := range items {
|
||||
for _, target := range item.Targets {
|
||||
if target == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ContainsFederation - check if service discovery items contain matrix federation endpoint
|
||||
func (items Items) ContainsFederation() bool {
|
||||
for _, item := range items {
|
||||
for _, target := range item.Targets {
|
||||
if strings.HasSuffix(target, "_matrix/federation/v1/version") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ContainsDelegation - check if service discovery items contain matrix server delegation endpoint
|
||||
func (items Items) ContainsDelegation() bool {
|
||||
for _, item := range items {
|
||||
for _, target := range item.Targets {
|
||||
if strings.HasSuffix(target, "/.well-known/matrix/server") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ContainsMSC1929 - check if service discovery items contain matrix MSC1929 endpoint
|
||||
func (items Items) ContainsMSC1929() bool {
|
||||
for _, item := range items {
|
||||
for _, target := range item.Targets {
|
||||
if strings.HasSuffix(target, "/.well-known/matrix/support") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
11
vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go
generated
vendored
11
vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go
generated
vendored
|
|
@ -52,10 +52,15 @@ func InstallShieldCab(raw []byte, _ uint32) bool {
|
|||
}
|
||||
|
||||
// Zstd matches a Zstandard archive file.
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
|
||||
func Zstd(raw []byte, limit uint32) bool {
|
||||
return len(raw) >= 4 &&
|
||||
(0x22 <= raw[0] && raw[0] <= 0x28 || raw[0] == 0x1E) && // Different Zstandard versions.
|
||||
bytes.HasPrefix(raw[1:], []byte{0xB5, 0x2F, 0xFD})
|
||||
if len(raw) < 4 {
|
||||
return false
|
||||
}
|
||||
sig := binary.LittleEndian.Uint32(raw)
|
||||
// Check for Zstandard frames and skippable frames.
|
||||
return (sig >= 0xFD2FB522 && sig <= 0xFD2FB528) ||
|
||||
(sig >= 0x184D2A50 && sig <= 0x184D2A5F)
|
||||
}
|
||||
|
||||
// CRX matches a Chrome extension file: a zip archive prepended by a package header.
|
||||
|
|
|
|||
19
vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go
generated
vendored
19
vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go
generated
vendored
|
|
@ -110,3 +110,22 @@ func zipContains(raw, sig []byte, msoCheck bool) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// APK matches an Android Package Archive.
|
||||
// The source of signatures is https://github.com/file/file/blob/1778642b8ba3d947a779a36fcd81f8e807220a19/magic/Magdir/archive#L1820-L1887
|
||||
func APK(raw []byte, _ uint32) bool {
|
||||
apkSignatures := [][]byte{
|
||||
[]byte("AndroidManifest.xml"),
|
||||
[]byte("META-INF/com/android/build/gradle/app-metadata.properties"),
|
||||
[]byte("classes.dex"),
|
||||
[]byte("resources.arsc"),
|
||||
[]byte("res/drawable"),
|
||||
}
|
||||
for _, sig := range apkSignatures {
|
||||
if zipContains(raw, sig, false) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
3
vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
generated
vendored
3
vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
## 177 Supported MIME types
|
||||
## 178 Supported MIME types
|
||||
This file is automatically generated when running tests. Do not edit manually.
|
||||
|
||||
Extension | MIME type | Aliases
|
||||
|
|
@ -11,6 +11,7 @@ Extension | MIME type | Aliases
|
|||
**.docx** | application/vnd.openxmlformats-officedocument.wordprocessingml.document | -
|
||||
**.pptx** | application/vnd.openxmlformats-officedocument.presentationml.presentation | -
|
||||
**.epub** | application/epub+zip | -
|
||||
**.apk** | application/vnd.android.package-archive | -
|
||||
**.jar** | application/jar | -
|
||||
**.odt** | application/vnd.oasis.opendocument.text | application/x-vnd.oasis.opendocument.text
|
||||
**.ott** | application/vnd.oasis.opendocument.text-template | application/x-vnd.oasis.opendocument.text-template
|
||||
|
|
|
|||
7
vendor/github.com/gabriel-vasile/mimetype/tree.go
generated
vendored
7
vendor/github.com/gabriel-vasile/mimetype/tree.go
generated
vendored
|
|
@ -44,7 +44,11 @@ var (
|
|||
"application/gzip-compressed", "application/x-gzip-compressed",
|
||||
"gzip/document")
|
||||
sevenZ = newMIME("application/x-7z-compressed", ".7z", magic.SevenZ)
|
||||
zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, jar, odt, ods, odp, odg, odf, odc, sxc).
|
||||
// APK must be checked before JAR because APK is a subset of JAR.
|
||||
// This means APK should be a child of JAR detector, but in practice,
|
||||
// the decisive signature for JAR might be located at the end of the file
|
||||
// and not reachable because of library readLimit.
|
||||
zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, apk, jar, odt, ods, odp, odg, odf, odc, sxc).
|
||||
alias("application/x-zip", "application/x-zip-compressed")
|
||||
tar = newMIME("application/x-tar", ".tar", magic.Tar)
|
||||
xar = newMIME("application/x-xar", ".xar", magic.Xar)
|
||||
|
|
@ -57,6 +61,7 @@ var (
|
|||
pptx = newMIME("application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx", magic.Pptx)
|
||||
epub = newMIME("application/epub+zip", ".epub", magic.Epub)
|
||||
jar = newMIME("application/jar", ".jar", magic.Jar)
|
||||
apk = newMIME("application/vnd.android.package-archive", ".apk", magic.APK)
|
||||
ole = newMIME("application/x-ole-storage", "", magic.Ole, msi, aaf, msg, xls, pub, ppt, doc)
|
||||
msi = newMIME("application/x-ms-installer", ".msi", magic.Msi).
|
||||
alias("application/x-windows-installer", "application/x-msi")
|
||||
|
|
|
|||
21
vendor/github.com/getsentry/sentry-go/.craft.yml
generated
vendored
21
vendor/github.com/getsentry/sentry-go/.craft.yml
generated
vendored
|
|
@ -8,6 +8,27 @@ targets:
|
|||
- name: github
|
||||
tagPrefix: otel/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: echo/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: fasthttp/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: fiber/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: gin/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: iris/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: negroni/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: logrus/v
|
||||
tagOnly: true
|
||||
- name: github
|
||||
tagPrefix: slog/v
|
||||
tagOnly: true
|
||||
|
|
|
|||
65
vendor/github.com/getsentry/sentry-go/CHANGELOG.md
generated
vendored
65
vendor/github.com/getsentry/sentry-go/CHANGELOG.md
generated
vendored
|
|
@ -1,5 +1,70 @@
|
|||
# Changelog
|
||||
|
||||
## 0.31.1
|
||||
|
||||
The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.31.1.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Correct wrong module name for `sentry-go/logrus` ([#950](https://github.com/getsentry/sentry-go/pull/950))
|
||||
|
||||
## 0.31.0
|
||||
|
||||
The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.31.0.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- Remove support for metrics. Read more about the end of the Metrics beta [here](https://sentry.zendesk.com/hc/en-us/articles/26369339769883-Metrics-Beta-Ended-on-October-7th). ([#914](https://github.com/getsentry/sentry-go/pull/914))
|
||||
|
||||
- Remove support for profiling. ([#915](https://github.com/getsentry/sentry-go/pull/915))
|
||||
|
||||
- Remove `Segment` field from the `User` struct. This field is no longer used in the Sentry product. ([#928](https://github.com/getsentry/sentry-go/pull/928))
|
||||
|
||||
- Every integration is now a separate module, reducing the binary size and number of dependencies. Once you update `sentry-go` to latest version, you'll need to `go get` the integration you want to use. For example, if you want to use the `echo` integration, you'll need to run `go get github.com/getsentry/sentry-go/echo` ([#919](github.com/getsentry/sentry-go/pull/919)).
|
||||
|
||||
### Features
|
||||
|
||||
Add the ability to override `hub` in `context` for integrations that use custom context. ([#931](https://github.com/getsentry/sentry-go/pull/931))
|
||||
|
||||
- Add `HubProvider` Hook for `sentrylogrus`, enabling dynamic Sentry hub allocation for each log entry or goroutine. ([#936](https://github.com/getsentry/sentry-go/pull/936))
|
||||
|
||||
This change enhances compatibility with Sentry's recommendation of using separate hubs per goroutine. To ensure a separate Sentry hub for each goroutine, configure the `HubProvider` like this:
|
||||
|
||||
```go
|
||||
hook, err := sentrylogrus.New(nil, sentry.ClientOptions{})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize Sentry hook: %v", err)
|
||||
}
|
||||
|
||||
// Set a custom HubProvider to generate a new hub for each goroutine or log entry
|
||||
hook.SetHubProvider(func() *sentry.Hub {
|
||||
client, _ := sentry.NewClient(sentry.ClientOptions{})
|
||||
return sentry.NewHub(client, sentry.NewScope())
|
||||
})
|
||||
|
||||
logrus.AddHook(hook)
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Add support for closing worker goroutines started by the `HTTPTranport` to prevent goroutine leaks. ([#894](https://github.com/getsentry/sentry-go/pull/894))
|
||||
|
||||
```go
|
||||
client, _ := sentry.NewClient()
|
||||
defer client.Close()
|
||||
```
|
||||
|
||||
Worker can be also closed by calling `Close()` method on the `HTTPTransport` instance. `Close` should be called after `Flush` and before terminating the program otherwise some events may be lost.
|
||||
|
||||
```go
|
||||
transport := sentry.NewHTTPTransport()
|
||||
defer transport.Close()
|
||||
```
|
||||
|
||||
### Misc
|
||||
|
||||
- Bump [gin-gonic/gin](https://github.com/gin-gonic/gin) to v1.9.1. ([#946](https://github.com/getsentry/sentry-go/pull/946))
|
||||
|
||||
## 0.30.0
|
||||
|
||||
The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.30.0.
|
||||
|
|
|
|||
6
vendor/github.com/getsentry/sentry-go/README.md
generated
vendored
6
vendor/github.com/getsentry/sentry-go/README.md
generated
vendored
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
# Official Sentry SDK for Go
|
||||
|
||||
[](https://github.com/getsentry/sentry-go/actions?query=workflow%3Ago-workflow)
|
||||
[](https://github.com/getsentry/sentry-go/actions/workflows/test.yml)
|
||||
[](https://goreportcard.com/report/github.com/getsentry/sentry-go)
|
||||
[](https://discord.gg/Ww9hbqr)
|
||||
[](https://pkg.go.dev/github.com/getsentry/sentry-go)
|
||||
|
|
@ -68,7 +68,7 @@ To get started, have a look at one of our [examples](_examples/):
|
|||
We also provide a [complete API reference](https://pkg.go.dev/github.com/getsentry/sentry-go).
|
||||
|
||||
For more detailed information about how to get the most out of `sentry-go`,
|
||||
checkout the official documentation:
|
||||
check out the official documentation:
|
||||
|
||||
- [Sentry Go SDK documentation](https://docs.sentry.io/platforms/go/)
|
||||
- Guides:
|
||||
|
|
@ -80,6 +80,8 @@ checkout the official documentation:
|
|||
- [iris](https://docs.sentry.io/platforms/go/guides/iris/)
|
||||
- [logrus](https://docs.sentry.io/platforms/go/guides/logrus/)
|
||||
- [negroni](https://docs.sentry.io/platforms/go/guides/negroni/)
|
||||
- [slog](https://docs.sentry.io/platforms/go/guides/slog/)
|
||||
- [zerolog](https://docs.sentry.io/platforms/go/guides/zerolog/)
|
||||
|
||||
## Resources
|
||||
|
||||
|
|
|
|||
15
vendor/github.com/getsentry/sentry-go/client.go
generated
vendored
15
vendor/github.com/getsentry/sentry-go/client.go
generated
vendored
|
|
@ -133,9 +133,6 @@ type ClientOptions struct {
|
|||
TracesSampleRate float64
|
||||
// Used to customize the sampling of traces, overrides TracesSampleRate.
|
||||
TracesSampler TracesSampler
|
||||
// The sample rate for profiling traces in the range [0.0, 1.0].
|
||||
// This is relative to TracesSampleRate - it is a ratio of profiled traces out of all sampled traces.
|
||||
ProfilesSampleRate float64
|
||||
// List of regexp strings that will be used to match against event's message
|
||||
// and if applicable, caught errors type and value.
|
||||
// If the match is found, then a whole event will be dropped.
|
||||
|
|
@ -513,6 +510,14 @@ func (client *Client) Flush(timeout time.Duration) bool {
|
|||
return client.Transport.Flush(timeout)
|
||||
}
|
||||
|
||||
// Close clean up underlying Transport resources.
|
||||
//
|
||||
// Close should be called after Flush and before terminating the program
|
||||
// otherwise some events may be lost.
|
||||
func (client *Client) Close() {
|
||||
client.Transport.Close()
|
||||
}
|
||||
|
||||
// EventFromMessage creates an event from the given message string.
|
||||
func (client *Client) EventFromMessage(message string, level Level) *Event {
|
||||
if message == "" {
|
||||
|
|
@ -701,10 +706,6 @@ func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventMod
|
|||
}
|
||||
}
|
||||
|
||||
if event.sdkMetaData.transactionProfile != nil {
|
||||
event.sdkMetaData.transactionProfile.UpdateFromEvent(event)
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
|
|
|
|||
4
vendor/github.com/getsentry/sentry-go/dsn.go
generated
vendored
4
vendor/github.com/getsentry/sentry-go/dsn.go
generated
vendored
|
|
@ -89,8 +89,8 @@ func NewDsn(rawURL string) (*Dsn, error) {
|
|||
|
||||
// Port
|
||||
var port int
|
||||
if parsedURL.Port() != "" {
|
||||
port, err = strconv.Atoi(parsedURL.Port())
|
||||
if p := parsedURL.Port(); p != "" {
|
||||
port, err = strconv.Atoi(p)
|
||||
if err != nil {
|
||||
return nil, &DsnParseError{"invalid port"}
|
||||
}
|
||||
|
|
|
|||
17
vendor/github.com/getsentry/sentry-go/interfaces.go
generated
vendored
17
vendor/github.com/getsentry/sentry-go/interfaces.go
generated
vendored
|
|
@ -19,16 +19,9 @@ const eventType = "event"
|
|||
// transactionType is the type of a transaction event.
|
||||
const transactionType = "transaction"
|
||||
|
||||
// profileType is the type of a profile event.
|
||||
// currently, profiles are always sent as part of a transaction event.
|
||||
const profileType = "profile"
|
||||
|
||||
// checkInType is the type of a check in event.
|
||||
const checkInType = "check_in"
|
||||
|
||||
// metricType is the type of a metric event.
|
||||
const metricType = "statsd"
|
||||
|
||||
// Level marks the severity of the event.
|
||||
type Level string
|
||||
|
||||
|
|
@ -119,7 +112,6 @@ type User struct {
|
|||
IPAddress string `json:"ip_address,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Segment string `json:"segment,omitempty"`
|
||||
Data map[string]string `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -144,10 +136,6 @@ func (u User) IsEmpty() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if u.Segment != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(u.Data) > 0 {
|
||||
return false
|
||||
}
|
||||
|
|
@ -196,6 +184,7 @@ func NewRequest(r *http.Request) *Request {
|
|||
// attach more than one Cookie header field.
|
||||
cookies = r.Header.Get("Cookie")
|
||||
|
||||
headers = make(map[string]string, len(r.Header))
|
||||
for k, v := range r.Header {
|
||||
headers[k] = strings.Join(v, ",")
|
||||
}
|
||||
|
|
@ -255,8 +244,7 @@ type Exception struct {
|
|||
// SDKMetaData is a struct to stash data which is needed at some point in the SDK's event processing pipeline
|
||||
// but which shouldn't get send to Sentry.
|
||||
type SDKMetaData struct {
|
||||
dsc DynamicSamplingContext
|
||||
transactionProfile *profileInfo
|
||||
dsc DynamicSamplingContext
|
||||
}
|
||||
|
||||
// Contains information about how the name of the transaction was determined.
|
||||
|
|
@ -324,7 +312,6 @@ type Event struct {
|
|||
Exception []Exception `json:"exception,omitempty"`
|
||||
DebugMeta *DebugMeta `json:"debug_meta,omitempty"`
|
||||
Attachments []*Attachment `json:"-"`
|
||||
Metrics []Metric `json:"-"`
|
||||
|
||||
// The fields below are only relevant for transactions.
|
||||
|
||||
|
|
|
|||
15
vendor/github.com/getsentry/sentry-go/internal/traceparser/README.md
generated
vendored
15
vendor/github.com/getsentry/sentry-go/internal/traceparser/README.md
generated
vendored
|
|
@ -1,15 +0,0 @@
|
|||
## Benchmark results
|
||||
|
||||
```
|
||||
goos: windows
|
||||
goarch: amd64
|
||||
pkg: github.com/getsentry/sentry-go/internal/trace
|
||||
cpu: 12th Gen Intel(R) Core(TM) i7-12700K
|
||||
BenchmarkEqualBytes-20 44323621 26.08 ns/op
|
||||
BenchmarkStringEqual-20 60980257 18.27 ns/op
|
||||
BenchmarkEqualPrefix-20 41369181 31.12 ns/op
|
||||
BenchmarkFullParse-20 702012 1507 ns/op 1353.42 MB/s 1024 B/op 6 allocs/op
|
||||
BenchmarkFramesIterator-20 1229971 969.3 ns/op 896 B/op 5 allocs/op
|
||||
BenchmarkFramesReversedIterator-20 1271061 944.5 ns/op 896 B/op 5 allocs/op
|
||||
BenchmarkSplitOnly-20 2250800 534.0 ns/op 3818.23 MB/s 128 B/op 1 allocs/op
|
||||
```
|
||||
217
vendor/github.com/getsentry/sentry-go/internal/traceparser/parser.go
generated
vendored
217
vendor/github.com/getsentry/sentry-go/internal/traceparser/parser.go
generated
vendored
|
|
@ -1,217 +0,0 @@
|
|||
package traceparser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var blockSeparator = []byte("\n\n")
|
||||
var lineSeparator = []byte("\n")
|
||||
|
||||
// Parses multi-stacktrace text dump produced by runtime.Stack([]byte, all=true).
|
||||
// The parser prioritizes performance but requires the input to be well-formed in order to return correct data.
|
||||
// See https://github.com/golang/go/blob/go1.20.4/src/runtime/mprof.go#L1191
|
||||
func Parse(data []byte) TraceCollection {
|
||||
var it = TraceCollection{}
|
||||
if len(data) > 0 {
|
||||
it.blocks = bytes.Split(data, blockSeparator)
|
||||
}
|
||||
return it
|
||||
}
|
||||
|
||||
type TraceCollection struct {
|
||||
blocks [][]byte
|
||||
}
|
||||
|
||||
func (it TraceCollection) Length() int {
|
||||
return len(it.blocks)
|
||||
}
|
||||
|
||||
// Returns the stacktrace item at the given index.
|
||||
func (it *TraceCollection) Item(i int) Trace {
|
||||
// The first item may have a leading data separator and the last one may have a trailing one.
|
||||
// Note: Trim() doesn't make a copy for single-character cutset under 0x80. It will just slice the original.
|
||||
var data []byte
|
||||
switch {
|
||||
case i == 0:
|
||||
data = bytes.TrimLeft(it.blocks[i], "\n")
|
||||
case i == len(it.blocks)-1:
|
||||
data = bytes.TrimRight(it.blocks[i], "\n")
|
||||
default:
|
||||
data = it.blocks[i]
|
||||
}
|
||||
|
||||
var splitAt = bytes.IndexByte(data, '\n')
|
||||
if splitAt < 0 {
|
||||
return Trace{header: data}
|
||||
}
|
||||
|
||||
return Trace{
|
||||
header: data[:splitAt],
|
||||
data: data[splitAt+1:],
|
||||
}
|
||||
}
|
||||
|
||||
// Trace represents a single stacktrace block, identified by a Goroutine ID and a sequence of Frames.
|
||||
type Trace struct {
|
||||
header []byte
|
||||
data []byte
|
||||
}
|
||||
|
||||
var goroutinePrefix = []byte("goroutine ")
|
||||
|
||||
// GoID parses the Goroutine ID from the header.
|
||||
func (t *Trace) GoID() (id uint64) {
|
||||
if bytes.HasPrefix(t.header, goroutinePrefix) {
|
||||
var line = t.header[len(goroutinePrefix):]
|
||||
var splitAt = bytes.IndexByte(line, ' ')
|
||||
if splitAt >= 0 {
|
||||
id, _ = strconv.ParseUint(string(line[:splitAt]), 10, 64)
|
||||
}
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// UniqueIdentifier can be used as a map key to identify the trace.
|
||||
func (t *Trace) UniqueIdentifier() []byte {
|
||||
return t.data
|
||||
}
|
||||
|
||||
func (t *Trace) Frames() FrameIterator {
|
||||
var lines = bytes.Split(t.data, lineSeparator)
|
||||
return FrameIterator{lines: lines, i: 0, len: len(lines)}
|
||||
}
|
||||
|
||||
func (t *Trace) FramesReversed() ReverseFrameIterator {
|
||||
var lines = bytes.Split(t.data, lineSeparator)
|
||||
return ReverseFrameIterator{lines: lines, i: len(lines)}
|
||||
}
|
||||
|
||||
const framesElided = "...additional frames elided..."
|
||||
|
||||
// FrameIterator iterates over stack frames.
|
||||
type FrameIterator struct {
|
||||
lines [][]byte
|
||||
i int
|
||||
len int
|
||||
}
|
||||
|
||||
// Next returns the next frame, or nil if there are none.
|
||||
func (it *FrameIterator) Next() Frame {
|
||||
return Frame{it.popLine(), it.popLine()}
|
||||
}
|
||||
|
||||
func (it *FrameIterator) popLine() []byte {
|
||||
switch {
|
||||
case it.i >= it.len:
|
||||
return nil
|
||||
case string(it.lines[it.i]) == framesElided:
|
||||
it.i++
|
||||
return it.popLine()
|
||||
default:
|
||||
it.i++
|
||||
return it.lines[it.i-1]
|
||||
}
|
||||
}
|
||||
|
||||
// HasNext return true if there are values to be read.
|
||||
func (it *FrameIterator) HasNext() bool {
|
||||
return it.i < it.len
|
||||
}
|
||||
|
||||
// LengthUpperBound returns the maximum number of elements this stacks may contain.
|
||||
// The actual number may be lower because of elided frames. As such, the returned value
|
||||
// cannot be used to iterate over the frames but may be used to reserve capacity.
|
||||
func (it *FrameIterator) LengthUpperBound() int {
|
||||
return it.len / 2
|
||||
}
|
||||
|
||||
// ReverseFrameIterator iterates over stack frames in reverse order.
|
||||
type ReverseFrameIterator struct {
|
||||
lines [][]byte
|
||||
i int
|
||||
}
|
||||
|
||||
// Next returns the next frame, or nil if there are none.
|
||||
func (it *ReverseFrameIterator) Next() Frame {
|
||||
var line2 = it.popLine()
|
||||
return Frame{it.popLine(), line2}
|
||||
}
|
||||
|
||||
func (it *ReverseFrameIterator) popLine() []byte {
|
||||
it.i--
|
||||
switch {
|
||||
case it.i < 0:
|
||||
return nil
|
||||
case string(it.lines[it.i]) == framesElided:
|
||||
return it.popLine()
|
||||
default:
|
||||
return it.lines[it.i]
|
||||
}
|
||||
}
|
||||
|
||||
// HasNext return true if there are values to be read.
|
||||
func (it *ReverseFrameIterator) HasNext() bool {
|
||||
return it.i > 1
|
||||
}
|
||||
|
||||
// LengthUpperBound returns the maximum number of elements this stacks may contain.
|
||||
// The actual number may be lower because of elided frames. As such, the returned value
|
||||
// cannot be used to iterate over the frames but may be used to reserve capacity.
|
||||
func (it *ReverseFrameIterator) LengthUpperBound() int {
|
||||
return len(it.lines) / 2
|
||||
}
|
||||
|
||||
type Frame struct {
|
||||
line1 []byte
|
||||
line2 []byte
|
||||
}
|
||||
|
||||
// UniqueIdentifier can be used as a map key to identify the frame.
|
||||
func (f *Frame) UniqueIdentifier() []byte {
|
||||
// line2 contains file path, line number and program-counter offset from the beginning of a function
|
||||
// e.g. C:/Users/name/scoop/apps/go/current/src/testing/testing.go:1906 +0x63a
|
||||
return f.line2
|
||||
}
|
||||
|
||||
var createdByPrefix = []byte("created by ")
|
||||
|
||||
func (f *Frame) Func() []byte {
|
||||
if bytes.HasPrefix(f.line1, createdByPrefix) {
|
||||
// Since go1.21, the line ends with " in goroutine X", saying which goroutine created this one.
|
||||
// We currently don't have use for that so just remove it.
|
||||
var line = f.line1[len(createdByPrefix):]
|
||||
var spaceAt = bytes.IndexByte(line, ' ')
|
||||
if spaceAt < 0 {
|
||||
return line
|
||||
}
|
||||
return line[:spaceAt]
|
||||
}
|
||||
|
||||
var end = bytes.LastIndexByte(f.line1, '(')
|
||||
if end >= 0 {
|
||||
return f.line1[:end]
|
||||
}
|
||||
|
||||
return f.line1
|
||||
}
|
||||
|
||||
func (f *Frame) File() (path []byte, lineNumber int) {
|
||||
var line = f.line2
|
||||
if len(line) > 0 && line[0] == '\t' {
|
||||
line = line[1:]
|
||||
}
|
||||
|
||||
var splitAt = bytes.IndexByte(line, ' ')
|
||||
if splitAt >= 0 {
|
||||
line = line[:splitAt]
|
||||
}
|
||||
|
||||
splitAt = bytes.LastIndexByte(line, ':')
|
||||
if splitAt < 0 {
|
||||
return line, 0
|
||||
}
|
||||
|
||||
lineNumber, _ = strconv.Atoi(string(line[splitAt+1:]))
|
||||
return line[:splitAt], lineNumber
|
||||
}
|
||||
421
vendor/github.com/getsentry/sentry-go/metrics.go
generated
vendored
421
vendor/github.com/getsentry/sentry-go/metrics.go
generated
vendored
|
|
@ -1,421 +0,0 @@
|
|||
package sentry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"math"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
NumberOrString interface {
|
||||
int | string
|
||||
}
|
||||
|
||||
void struct{}
|
||||
)
|
||||
|
||||
var (
|
||||
member void
|
||||
keyRegex = regexp.MustCompile(`[^a-zA-Z0-9_/.-]+`)
|
||||
valueRegex = regexp.MustCompile(`[^\w\d\s_:/@\.{}\[\]$-]+`)
|
||||
unitRegex = regexp.MustCompile(`[^a-z]+`)
|
||||
)
|
||||
|
||||
type MetricUnit struct {
|
||||
unit string
|
||||
}
|
||||
|
||||
func (m MetricUnit) toString() string {
|
||||
return m.unit
|
||||
}
|
||||
|
||||
func NanoSecond() MetricUnit {
|
||||
return MetricUnit{
|
||||
"nanosecond",
|
||||
}
|
||||
}
|
||||
|
||||
func MicroSecond() MetricUnit {
|
||||
return MetricUnit{
|
||||
"microsecond",
|
||||
}
|
||||
}
|
||||
|
||||
func MilliSecond() MetricUnit {
|
||||
return MetricUnit{
|
||||
"millisecond",
|
||||
}
|
||||
}
|
||||
|
||||
func Second() MetricUnit {
|
||||
return MetricUnit{
|
||||
"second",
|
||||
}
|
||||
}
|
||||
|
||||
func Minute() MetricUnit {
|
||||
return MetricUnit{
|
||||
"minute",
|
||||
}
|
||||
}
|
||||
|
||||
func Hour() MetricUnit {
|
||||
return MetricUnit{
|
||||
"hour",
|
||||
}
|
||||
}
|
||||
|
||||
func Day() MetricUnit {
|
||||
return MetricUnit{
|
||||
"day",
|
||||
}
|
||||
}
|
||||
|
||||
func Week() MetricUnit {
|
||||
return MetricUnit{
|
||||
"week",
|
||||
}
|
||||
}
|
||||
|
||||
func Bit() MetricUnit {
|
||||
return MetricUnit{
|
||||
"bit",
|
||||
}
|
||||
}
|
||||
|
||||
func Byte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"byte",
|
||||
}
|
||||
}
|
||||
|
||||
func KiloByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"kilobyte",
|
||||
}
|
||||
}
|
||||
|
||||
func KibiByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"kibibyte",
|
||||
}
|
||||
}
|
||||
|
||||
func MegaByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"megabyte",
|
||||
}
|
||||
}
|
||||
|
||||
func MebiByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"mebibyte",
|
||||
}
|
||||
}
|
||||
|
||||
func GigaByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"gigabyte",
|
||||
}
|
||||
}
|
||||
|
||||
func GibiByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"gibibyte",
|
||||
}
|
||||
}
|
||||
|
||||
func TeraByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"terabyte",
|
||||
}
|
||||
}
|
||||
|
||||
func TebiByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"tebibyte",
|
||||
}
|
||||
}
|
||||
|
||||
func PetaByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"petabyte",
|
||||
}
|
||||
}
|
||||
|
||||
func PebiByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"pebibyte",
|
||||
}
|
||||
}
|
||||
|
||||
func ExaByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"exabyte",
|
||||
}
|
||||
}
|
||||
|
||||
func ExbiByte() MetricUnit {
|
||||
return MetricUnit{
|
||||
"exbibyte",
|
||||
}
|
||||
}
|
||||
|
||||
func Ratio() MetricUnit {
|
||||
return MetricUnit{
|
||||
"ratio",
|
||||
}
|
||||
}
|
||||
|
||||
func Percent() MetricUnit {
|
||||
return MetricUnit{
|
||||
"percent",
|
||||
}
|
||||
}
|
||||
|
||||
func CustomUnit(unit string) MetricUnit {
|
||||
return MetricUnit{
|
||||
unitRegex.ReplaceAllString(unit, ""),
|
||||
}
|
||||
}
|
||||
|
||||
type Metric interface {
|
||||
GetType() string
|
||||
GetTags() map[string]string
|
||||
GetKey() string
|
||||
GetUnit() string
|
||||
GetTimestamp() int64
|
||||
SerializeValue() string
|
||||
SerializeTags() string
|
||||
}
|
||||
|
||||
type abstractMetric struct {
|
||||
key string
|
||||
unit MetricUnit
|
||||
tags map[string]string
|
||||
// A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC).
|
||||
timestamp int64
|
||||
}
|
||||
|
||||
func (am abstractMetric) GetTags() map[string]string {
|
||||
return am.tags
|
||||
}
|
||||
|
||||
func (am abstractMetric) GetKey() string {
|
||||
return am.key
|
||||
}
|
||||
|
||||
func (am abstractMetric) GetUnit() string {
|
||||
return am.unit.toString()
|
||||
}
|
||||
|
||||
func (am abstractMetric) GetTimestamp() int64 {
|
||||
return am.timestamp
|
||||
}
|
||||
|
||||
func (am abstractMetric) SerializeTags() string {
|
||||
var sb strings.Builder
|
||||
|
||||
values := make([]string, 0, len(am.tags))
|
||||
for k := range am.tags {
|
||||
values = append(values, k)
|
||||
}
|
||||
slices.Sort(values)
|
||||
|
||||
for _, key := range values {
|
||||
val := sanitizeValue(am.tags[key])
|
||||
key = sanitizeKey(key)
|
||||
sb.WriteString(fmt.Sprintf("%s:%s,", key, val))
|
||||
}
|
||||
s := sb.String()
|
||||
if len(s) > 0 {
|
||||
s = s[:len(s)-1]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Counter Metric.
|
||||
type CounterMetric struct {
|
||||
value float64
|
||||
abstractMetric
|
||||
}
|
||||
|
||||
func (c *CounterMetric) Add(value float64) {
|
||||
c.value += value
|
||||
}
|
||||
|
||||
func (c CounterMetric) GetType() string {
|
||||
return "c"
|
||||
}
|
||||
|
||||
func (c CounterMetric) SerializeValue() string {
|
||||
return fmt.Sprintf(":%v", c.value)
|
||||
}
|
||||
|
||||
// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC).
|
||||
func NewCounterMetric(key string, unit MetricUnit, tags map[string]string, timestamp int64, value float64) CounterMetric {
|
||||
am := abstractMetric{
|
||||
key,
|
||||
unit,
|
||||
tags,
|
||||
timestamp,
|
||||
}
|
||||
|
||||
return CounterMetric{
|
||||
value,
|
||||
am,
|
||||
}
|
||||
}
|
||||
|
||||
// Distribution Metric.
|
||||
type DistributionMetric struct {
|
||||
values []float64
|
||||
abstractMetric
|
||||
}
|
||||
|
||||
func (d *DistributionMetric) Add(value float64) {
|
||||
d.values = append(d.values, value)
|
||||
}
|
||||
|
||||
func (d DistributionMetric) GetType() string {
|
||||
return "d"
|
||||
}
|
||||
|
||||
func (d DistributionMetric) SerializeValue() string {
|
||||
var sb strings.Builder
|
||||
for _, el := range d.values {
|
||||
sb.WriteString(fmt.Sprintf(":%v", el))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC).
|
||||
func NewDistributionMetric(key string, unit MetricUnit, tags map[string]string, timestamp int64, value float64) DistributionMetric {
|
||||
am := abstractMetric{
|
||||
key,
|
||||
unit,
|
||||
tags,
|
||||
timestamp,
|
||||
}
|
||||
|
||||
return DistributionMetric{
|
||||
[]float64{value},
|
||||
am,
|
||||
}
|
||||
}
|
||||
|
||||
// Gauge Metric.
|
||||
type GaugeMetric struct {
|
||||
last float64
|
||||
min float64
|
||||
max float64
|
||||
sum float64
|
||||
count float64
|
||||
abstractMetric
|
||||
}
|
||||
|
||||
func (g *GaugeMetric) Add(value float64) {
|
||||
g.last = value
|
||||
g.min = math.Min(g.min, value)
|
||||
g.max = math.Max(g.max, value)
|
||||
g.sum += value
|
||||
g.count++
|
||||
}
|
||||
|
||||
func (g GaugeMetric) GetType() string {
|
||||
return "g"
|
||||
}
|
||||
|
||||
func (g GaugeMetric) SerializeValue() string {
|
||||
return fmt.Sprintf(":%v:%v:%v:%v:%v", g.last, g.min, g.max, g.sum, g.count)
|
||||
}
|
||||
|
||||
// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC).
|
||||
func NewGaugeMetric(key string, unit MetricUnit, tags map[string]string, timestamp int64, value float64) GaugeMetric {
|
||||
am := abstractMetric{
|
||||
key,
|
||||
unit,
|
||||
tags,
|
||||
timestamp,
|
||||
}
|
||||
|
||||
return GaugeMetric{
|
||||
value, // last
|
||||
value, // min
|
||||
value, // max
|
||||
value, // sum
|
||||
value, // count
|
||||
am,
|
||||
}
|
||||
}
|
||||
|
||||
// Set Metric.
|
||||
type SetMetric[T NumberOrString] struct {
|
||||
values map[T]void
|
||||
abstractMetric
|
||||
}
|
||||
|
||||
func (s *SetMetric[T]) Add(value T) {
|
||||
s.values[value] = member
|
||||
}
|
||||
|
||||
func (s SetMetric[T]) GetType() string {
|
||||
return "s"
|
||||
}
|
||||
|
||||
func (s SetMetric[T]) SerializeValue() string {
|
||||
_hash := func(s string) uint32 {
|
||||
return crc32.ChecksumIEEE([]byte(s))
|
||||
}
|
||||
|
||||
values := make([]T, 0, len(s.values))
|
||||
for k := range s.values {
|
||||
values = append(values, k)
|
||||
}
|
||||
slices.Sort(values)
|
||||
|
||||
var sb strings.Builder
|
||||
for _, el := range values {
|
||||
switch any(el).(type) {
|
||||
case int:
|
||||
sb.WriteString(fmt.Sprintf(":%v", el))
|
||||
case string:
|
||||
s := fmt.Sprintf("%v", el)
|
||||
sb.WriteString(fmt.Sprintf(":%d", _hash(s)))
|
||||
}
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC).
|
||||
func NewSetMetric[T NumberOrString](key string, unit MetricUnit, tags map[string]string, timestamp int64, value T) SetMetric[T] {
|
||||
am := abstractMetric{
|
||||
key,
|
||||
unit,
|
||||
tags,
|
||||
timestamp,
|
||||
}
|
||||
|
||||
return SetMetric[T]{
|
||||
map[T]void{
|
||||
value: member,
|
||||
},
|
||||
am,
|
||||
}
|
||||
}
|
||||
|
||||
func sanitizeKey(s string) string {
|
||||
return keyRegex.ReplaceAllString(s, "_")
|
||||
}
|
||||
|
||||
func sanitizeValue(s string) string {
|
||||
return valueRegex.ReplaceAllString(s, "")
|
||||
}
|
||||
|
||||
type Ordered interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string
|
||||
}
|
||||
73
vendor/github.com/getsentry/sentry-go/profile_sample.go
generated
vendored
73
vendor/github.com/getsentry/sentry-go/profile_sample.go
generated
vendored
|
|
@ -1,73 +0,0 @@
|
|||
package sentry
|
||||
|
||||
// Based on https://github.com/getsentry/vroom/blob/d11c26063e802d66b9a592c4010261746ca3dfa4/internal/sample/sample.go
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
profileDevice struct {
|
||||
Architecture string `json:"architecture"`
|
||||
Classification string `json:"classification"`
|
||||
Locale string `json:"locale"`
|
||||
Manufacturer string `json:"manufacturer"`
|
||||
Model string `json:"model"`
|
||||
}
|
||||
|
||||
profileOS struct {
|
||||
BuildNumber string `json:"build_number"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
profileRuntime struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
profileSample struct {
|
||||
ElapsedSinceStartNS uint64 `json:"elapsed_since_start_ns"`
|
||||
StackID int `json:"stack_id"`
|
||||
ThreadID uint64 `json:"thread_id"`
|
||||
}
|
||||
|
||||
profileThreadMetadata struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
}
|
||||
|
||||
profileStack []int
|
||||
|
||||
profileTrace struct {
|
||||
Frames []*Frame `json:"frames"`
|
||||
Samples []profileSample `json:"samples"`
|
||||
Stacks []profileStack `json:"stacks"`
|
||||
ThreadMetadata map[uint64]*profileThreadMetadata `json:"thread_metadata"`
|
||||
}
|
||||
|
||||
profileInfo struct {
|
||||
DebugMeta *DebugMeta `json:"debug_meta,omitempty"`
|
||||
Device profileDevice `json:"device"`
|
||||
Environment string `json:"environment,omitempty"`
|
||||
EventID string `json:"event_id"`
|
||||
OS profileOS `json:"os"`
|
||||
Platform string `json:"platform"`
|
||||
Release string `json:"release"`
|
||||
Dist string `json:"dist"`
|
||||
Runtime profileRuntime `json:"runtime"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Trace *profileTrace `json:"profile"`
|
||||
Transaction profileTransaction `json:"transaction"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// see https://github.com/getsentry/vroom/blob/a91e39416723ec44fc54010257020eeaf9a77cbd/internal/transaction/transaction.go
|
||||
profileTransaction struct {
|
||||
ActiveThreadID uint64 `json:"active_thread_id"`
|
||||
DurationNS uint64 `json:"duration_ns,omitempty"`
|
||||
ID EventID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
TraceID string `json:"trace_id"`
|
||||
}
|
||||
)
|
||||
446
vendor/github.com/getsentry/sentry-go/profiler.go
generated
vendored
446
vendor/github.com/getsentry/sentry-go/profiler.go
generated
vendored
|
|
@ -1,446 +0,0 @@
|
|||
package sentry
|
||||
|
||||
import (
|
||||
"container/ring"
|
||||
"encoding/binary"
|
||||
"strconv"
|
||||
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go/internal/traceparser"
|
||||
)
|
||||
|
||||
// Start a profiler that collects samples continuously, with a buffer of up to 30 seconds.
|
||||
// Later, you can collect a slice from this buffer, producing a Trace.
|
||||
func startProfiling(startTime time.Time) profiler {
|
||||
onProfilerStart()
|
||||
|
||||
p := newProfiler(startTime)
|
||||
|
||||
// Wait for the profiler to finish setting up before returning to the caller.
|
||||
started := make(chan struct{})
|
||||
go p.run(started)
|
||||
|
||||
if _, ok := <-started; ok {
|
||||
return p
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type profiler interface {
|
||||
// GetSlice returns a slice of the profiled data between the given times.
|
||||
GetSlice(startTime, endTime time.Time) *profilerResult
|
||||
Stop(wait bool)
|
||||
}
|
||||
|
||||
type profilerResult struct {
|
||||
callerGoID uint64
|
||||
trace *profileTrace
|
||||
}
|
||||
|
||||
func getCurrentGoID() uint64 {
|
||||
// We shouldn't panic but let's be super safe.
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
Logger.Printf("Profiler panic in getCurrentGoID(): %v\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Buffer to read the stack trace into. We should be good with a small buffer because we only need the first line.
|
||||
var stacksBuffer = make([]byte, 100)
|
||||
var n = runtime.Stack(stacksBuffer, false)
|
||||
if n > 0 {
|
||||
var traces = traceparser.Parse(stacksBuffer[0:n])
|
||||
if traces.Length() > 0 {
|
||||
var trace = traces.Item(0)
|
||||
return trace.GoID()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
const profilerSamplingRateHz = 101 // 101 Hz; not 100 Hz because of the lockstep sampling (https://stackoverflow.com/a/45471031/1181370)
|
||||
const profilerSamplingRate = time.Second / profilerSamplingRateHz
|
||||
const stackBufferMaxGrowth = 512 * 1024
|
||||
const stackBufferLimit = 10 * 1024 * 1024
|
||||
const profilerRuntimeLimit = 30 // seconds
|
||||
|
||||
type profileRecorder struct {
|
||||
startTime time.Time
|
||||
stopSignal chan struct{}
|
||||
stopped int64
|
||||
mutex sync.RWMutex
|
||||
testProfilerPanic int64
|
||||
|
||||
// Map from runtime.StackRecord.Stack0 to an index in stacks.
|
||||
stackIndexes map[string]int
|
||||
stacks []profileStack
|
||||
newStacks []profileStack // New stacks created in the current interation.
|
||||
stackKeyBuffer []byte
|
||||
|
||||
// Map from runtime.Frame.PC to an index in frames.
|
||||
frameIndexes map[string]int
|
||||
frames []*Frame
|
||||
newFrames []*Frame // New frames created in the current interation.
|
||||
|
||||
// We keep a ring buffer of 30 seconds worth of samples, so that we can later slice it.
|
||||
// Each bucket is a slice of samples all taken at the same time.
|
||||
samplesBucketsHead *ring.Ring
|
||||
|
||||
// Buffer to read current stacks - will grow automatically up to stackBufferLimit.
|
||||
stacksBuffer []byte
|
||||
}
|
||||
|
||||
func newProfiler(startTime time.Time) *profileRecorder {
|
||||
// Pre-allocate the profile trace for the currently active number of routines & 100 ms worth of samples.
|
||||
// Other coefficients are just guesses of what might be a good starting point to avoid allocs on short runs.
|
||||
return &profileRecorder{
|
||||
startTime: startTime,
|
||||
stopSignal: make(chan struct{}, 1),
|
||||
|
||||
stackIndexes: make(map[string]int, 32),
|
||||
stacks: make([]profileStack, 0, 32),
|
||||
newStacks: make([]profileStack, 0, 32),
|
||||
|
||||
frameIndexes: make(map[string]int, 128),
|
||||
frames: make([]*Frame, 0, 128),
|
||||
newFrames: make([]*Frame, 0, 128),
|
||||
|
||||
samplesBucketsHead: ring.New(profilerRuntimeLimit * profilerSamplingRateHz),
|
||||
|
||||
// A buffer of 2 KiB per goroutine stack looks like a good starting point (empirically determined).
|
||||
stacksBuffer: make([]byte, runtime.NumGoroutine()*2048),
|
||||
}
|
||||
}
|
||||
|
||||
// This allows us to test whether panic during profiling are handled correctly and don't block execution.
|
||||
// If the number is lower than 0, profilerGoroutine() will panic immedately.
|
||||
// If the number is higher than 0, profiler.onTick() will panic when the given samples-set index is being collected.
|
||||
var testProfilerPanic int64
|
||||
var profilerRunning int64
|
||||
|
||||
func (p *profileRecorder) run(started chan struct{}) {
|
||||
// Code backup for manual test debugging:
|
||||
// if !atomic.CompareAndSwapInt64(&profilerRunning, 0, 1) {
|
||||
// panic("Only one profiler can be running at a time")
|
||||
// }
|
||||
|
||||
// We shouldn't panic but let's be super safe.
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
Logger.Printf("Profiler panic in run(): %v\n", err)
|
||||
}
|
||||
atomic.StoreInt64(&testProfilerPanic, 0)
|
||||
close(started)
|
||||
p.stopSignal <- struct{}{}
|
||||
atomic.StoreInt64(&p.stopped, 1)
|
||||
atomic.StoreInt64(&profilerRunning, 0)
|
||||
}()
|
||||
|
||||
p.testProfilerPanic = atomic.LoadInt64(&testProfilerPanic)
|
||||
if p.testProfilerPanic < 0 {
|
||||
Logger.Printf("Profiler panicking during startup because testProfilerPanic == %v\n", p.testProfilerPanic)
|
||||
panic("This is an expected panic in profilerGoroutine() during tests")
|
||||
}
|
||||
|
||||
// Collect the first sample immediately.
|
||||
p.onTick()
|
||||
|
||||
// Periodically collect stacks, starting after profilerSamplingRate has passed.
|
||||
collectTicker := profilerTickerFactory(profilerSamplingRate)
|
||||
defer collectTicker.Stop()
|
||||
var tickerChannel = collectTicker.TickSource()
|
||||
|
||||
started <- struct{}{}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-tickerChannel:
|
||||
p.onTick()
|
||||
collectTicker.Ticked()
|
||||
case <-p.stopSignal:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *profileRecorder) Stop(wait bool) {
|
||||
if atomic.LoadInt64(&p.stopped) == 1 {
|
||||
return
|
||||
}
|
||||
p.stopSignal <- struct{}{}
|
||||
if wait {
|
||||
<-p.stopSignal
|
||||
}
|
||||
}
|
||||
|
||||
func (p *profileRecorder) GetSlice(startTime, endTime time.Time) *profilerResult {
|
||||
// Unlikely edge cases - profiler wasn't running at all or the given times are invalid in relation to each other.
|
||||
if p.startTime.After(endTime) || startTime.After(endTime) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var relativeStartNS = uint64(0)
|
||||
if p.startTime.Before(startTime) {
|
||||
relativeStartNS = uint64(startTime.Sub(p.startTime).Nanoseconds())
|
||||
}
|
||||
var relativeEndNS = uint64(endTime.Sub(p.startTime).Nanoseconds())
|
||||
|
||||
samplesCount, bucketsReversed, trace := p.getBuckets(relativeStartNS, relativeEndNS)
|
||||
if samplesCount == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result = &profilerResult{
|
||||
callerGoID: getCurrentGoID(),
|
||||
trace: trace,
|
||||
}
|
||||
|
||||
trace.Samples = make([]profileSample, samplesCount)
|
||||
trace.ThreadMetadata = make(map[uint64]*profileThreadMetadata, len(bucketsReversed[0].goIDs))
|
||||
var s = samplesCount - 1
|
||||
for _, bucket := range bucketsReversed {
|
||||
var elapsedSinceStartNS = bucket.relativeTimeNS - relativeStartNS
|
||||
for i, goID := range bucket.goIDs {
|
||||
trace.Samples[s].ElapsedSinceStartNS = elapsedSinceStartNS
|
||||
trace.Samples[s].ThreadID = goID
|
||||
trace.Samples[s].StackID = bucket.stackIDs[i]
|
||||
s--
|
||||
|
||||
if _, goroutineExists := trace.ThreadMetadata[goID]; !goroutineExists {
|
||||
trace.ThreadMetadata[goID] = &profileThreadMetadata{
|
||||
Name: "Goroutine " + strconv.FormatUint(goID, 10),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Collect all buckets of samples in the given time range while holding a read lock.
|
||||
func (p *profileRecorder) getBuckets(relativeStartNS, relativeEndNS uint64) (samplesCount int, buckets []*profileSamplesBucket, trace *profileTrace) {
|
||||
p.mutex.RLock()
|
||||
defer p.mutex.RUnlock()
|
||||
|
||||
// sampleBucketsHead points at the last stored bucket so it's a good starting point to search backwards for the end.
|
||||
var end = p.samplesBucketsHead
|
||||
for end.Value != nil && end.Value.(*profileSamplesBucket).relativeTimeNS > relativeEndNS {
|
||||
end = end.Prev()
|
||||
}
|
||||
|
||||
// Edge case - no items stored before the given endTime.
|
||||
if end.Value == nil {
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
{ // Find the first item after the given startTime.
|
||||
var start = end
|
||||
var prevBucket *profileSamplesBucket
|
||||
samplesCount = 0
|
||||
buckets = make([]*profileSamplesBucket, 0, int64((relativeEndNS-relativeStartNS)/uint64(profilerSamplingRate.Nanoseconds()))+1)
|
||||
for start.Value != nil {
|
||||
var bucket = start.Value.(*profileSamplesBucket)
|
||||
|
||||
// If this bucket's time is before the requests start time, don't collect it (and stop iterating further).
|
||||
if bucket.relativeTimeNS < relativeStartNS {
|
||||
break
|
||||
}
|
||||
|
||||
// If this bucket time is greater than previous the bucket's time, we have exhausted the whole ring buffer
|
||||
// before we were able to find the start time. That means the start time is not present and we must break.
|
||||
// This happens if the slice duration exceeds the ring buffer capacity.
|
||||
if prevBucket != nil && bucket.relativeTimeNS > prevBucket.relativeTimeNS {
|
||||
break
|
||||
}
|
||||
|
||||
samplesCount += len(bucket.goIDs)
|
||||
buckets = append(buckets, bucket)
|
||||
|
||||
start = start.Prev()
|
||||
prevBucket = bucket
|
||||
}
|
||||
}
|
||||
|
||||
// Edge case - if the period requested was too short and we haven't collected enough samples.
|
||||
if len(buckets) < 2 {
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
trace = &profileTrace{
|
||||
Frames: p.frames,
|
||||
Stacks: p.stacks,
|
||||
}
|
||||
return samplesCount, buckets, trace
|
||||
}
|
||||
|
||||
func (p *profileRecorder) onTick() {
|
||||
elapsedNs := time.Since(p.startTime).Nanoseconds()
|
||||
|
||||
if p.testProfilerPanic > 0 {
|
||||
Logger.Printf("Profiler testProfilerPanic == %v\n", p.testProfilerPanic)
|
||||
if p.testProfilerPanic == 1 {
|
||||
Logger.Println("Profiler panicking onTick()")
|
||||
panic("This is an expected panic in Profiler.OnTick() during tests")
|
||||
}
|
||||
p.testProfilerPanic--
|
||||
}
|
||||
|
||||
records := p.collectRecords()
|
||||
p.processRecords(uint64(elapsedNs), records)
|
||||
|
||||
// Free up some memory if we don't need such a large buffer anymore.
|
||||
if len(p.stacksBuffer) > len(records)*3 {
|
||||
p.stacksBuffer = make([]byte, len(records)*3)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *profileRecorder) collectRecords() []byte {
|
||||
for {
|
||||
// Capture stacks for all existing goroutines.
|
||||
// Note: runtime.GoroutineProfile() would be better but we can't use it at the moment because
|
||||
// it doesn't give us `gid` for each routine, see https://github.com/golang/go/issues/59663
|
||||
n := runtime.Stack(p.stacksBuffer, true)
|
||||
|
||||
// If we couldn't read everything, increase the buffer and try again.
|
||||
if n >= len(p.stacksBuffer) && n < stackBufferLimit {
|
||||
var newSize = n * 2
|
||||
if newSize > n+stackBufferMaxGrowth {
|
||||
newSize = n + stackBufferMaxGrowth
|
||||
}
|
||||
if newSize > stackBufferLimit {
|
||||
newSize = stackBufferLimit
|
||||
}
|
||||
p.stacksBuffer = make([]byte, newSize)
|
||||
} else {
|
||||
return p.stacksBuffer[0:n]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *profileRecorder) processRecords(elapsedNs uint64, stacksBuffer []byte) {
|
||||
var traces = traceparser.Parse(stacksBuffer)
|
||||
var length = traces.Length()
|
||||
|
||||
// Shouldn't happen but let's be safe and don't store empty buckets.
|
||||
if length == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var bucket = &profileSamplesBucket{
|
||||
relativeTimeNS: elapsedNs,
|
||||
stackIDs: make([]int, length),
|
||||
goIDs: make([]uint64, length),
|
||||
}
|
||||
|
||||
// reset buffers
|
||||
p.newFrames = p.newFrames[:0]
|
||||
p.newStacks = p.newStacks[:0]
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
var stack = traces.Item(i)
|
||||
bucket.stackIDs[i] = p.addStackTrace(stack)
|
||||
bucket.goIDs[i] = stack.GoID()
|
||||
}
|
||||
|
||||
p.mutex.Lock()
|
||||
defer p.mutex.Unlock()
|
||||
|
||||
p.stacks = append(p.stacks, p.newStacks...)
|
||||
p.frames = append(p.frames, p.newFrames...)
|
||||
|
||||
p.samplesBucketsHead = p.samplesBucketsHead.Next()
|
||||
p.samplesBucketsHead.Value = bucket
|
||||
}
|
||||
|
||||
func (p *profileRecorder) addStackTrace(capturedStack traceparser.Trace) int {
|
||||
iter := capturedStack.Frames()
|
||||
stack := make(profileStack, 0, iter.LengthUpperBound())
|
||||
|
||||
// Originally, we've used `capturedStack.UniqueIdentifier()` as a key but that was incorrect because it also
|
||||
// contains function arguments and we want to group stacks by function name and file/line only.
|
||||
// Instead, we need to parse frames and we use a list of their indexes as a key.
|
||||
// We reuse the same buffer for each stack to avoid allocations; this is a hot spot.
|
||||
var expectedBufferLen = cap(stack) * 5 // 4 bytes per frame + 1 byte for space
|
||||
if cap(p.stackKeyBuffer) < expectedBufferLen {
|
||||
p.stackKeyBuffer = make([]byte, 0, expectedBufferLen)
|
||||
} else {
|
||||
p.stackKeyBuffer = p.stackKeyBuffer[:0]
|
||||
}
|
||||
|
||||
for iter.HasNext() {
|
||||
var frame = iter.Next()
|
||||
if frameIndex := p.addFrame(frame); frameIndex >= 0 {
|
||||
stack = append(stack, frameIndex)
|
||||
|
||||
p.stackKeyBuffer = append(p.stackKeyBuffer, 0) // space
|
||||
|
||||
p.stackKeyBuffer = binary.AppendUvarint(p.stackKeyBuffer, uint64(frameIndex)+1)
|
||||
}
|
||||
}
|
||||
|
||||
stackIndex, exists := p.stackIndexes[string(p.stackKeyBuffer)]
|
||||
if !exists {
|
||||
stackIndex = len(p.stacks) + len(p.newStacks)
|
||||
p.newStacks = append(p.newStacks, stack)
|
||||
p.stackIndexes[string(p.stackKeyBuffer)] = stackIndex
|
||||
}
|
||||
|
||||
return stackIndex
|
||||
}
|
||||
|
||||
func (p *profileRecorder) addFrame(capturedFrame traceparser.Frame) int {
|
||||
// NOTE: Don't convert to string yet, it's expensive and compiler can avoid it when
|
||||
// indexing into a map (only needs a copy when adding a new key to the map).
|
||||
var key = capturedFrame.UniqueIdentifier()
|
||||
|
||||
frameIndex, exists := p.frameIndexes[string(key)]
|
||||
if !exists {
|
||||
module, function := splitQualifiedFunctionName(string(capturedFrame.Func()))
|
||||
file, line := capturedFrame.File()
|
||||
frame := newFrame(module, function, string(file), line)
|
||||
frameIndex = len(p.frames) + len(p.newFrames)
|
||||
p.newFrames = append(p.newFrames, &frame)
|
||||
p.frameIndexes[string(key)] = frameIndex
|
||||
}
|
||||
return frameIndex
|
||||
}
|
||||
|
||||
type profileSamplesBucket struct {
|
||||
relativeTimeNS uint64
|
||||
stackIDs []int
|
||||
goIDs []uint64
|
||||
}
|
||||
|
||||
// A Ticker holds a channel that delivers “ticks” of a clock at intervals.
|
||||
type profilerTicker interface {
|
||||
// Stop turns off a ticker. After Stop, no more ticks will be sent.
|
||||
Stop()
|
||||
|
||||
// TickSource returns a read-only channel of ticks.
|
||||
TickSource() <-chan time.Time
|
||||
|
||||
// Ticked is called by the Profiler after a tick is processed to notify the ticker. Used for testing.
|
||||
Ticked()
|
||||
}
|
||||
|
||||
type timeTicker struct {
|
||||
*time.Ticker
|
||||
}
|
||||
|
||||
func (t *timeTicker) TickSource() <-chan time.Time {
|
||||
return t.C
|
||||
}
|
||||
|
||||
func (t *timeTicker) Ticked() {}
|
||||
|
||||
func profilerTickerFactoryDefault(d time.Duration) profilerTicker {
|
||||
return &timeTicker{time.NewTicker(d)}
|
||||
}
|
||||
|
||||
// We allow overriding the ticker for tests. CI is terribly flaky
|
||||
// because the time.Ticker doesn't guarantee regular ticks - they may come (a lot) later than the given interval.
|
||||
var profilerTickerFactory = profilerTickerFactoryDefault
|
||||
5
vendor/github.com/getsentry/sentry-go/profiler_other.go
generated
vendored
5
vendor/github.com/getsentry/sentry-go/profiler_other.go
generated
vendored
|
|
@ -1,5 +0,0 @@
|
|||
//go:build !windows
|
||||
|
||||
package sentry
|
||||
|
||||
func onProfilerStart() {}
|
||||
24
vendor/github.com/getsentry/sentry-go/profiler_windows.go
generated
vendored
24
vendor/github.com/getsentry/sentry-go/profiler_windows.go
generated
vendored
|
|
@ -1,24 +0,0 @@
|
|||
package sentry
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// This works around the ticker resolution on Windows being ~15ms by default.
|
||||
// See https://github.com/golang/go/issues/44343
|
||||
func setTimeTickerResolution() {
|
||||
var winmmDLL = syscall.NewLazyDLL("winmm.dll")
|
||||
if winmmDLL != nil {
|
||||
var timeBeginPeriod = winmmDLL.NewProc("timeBeginPeriod")
|
||||
if timeBeginPeriod != nil {
|
||||
timeBeginPeriod.Call(uintptr(1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setupTickerResolutionOnce sync.Once
|
||||
|
||||
func onProfilerStart() {
|
||||
setupTickerResolutionOnce.Do(setTimeTickerResolution)
|
||||
}
|
||||
2
vendor/github.com/getsentry/sentry-go/sentry.go
generated
vendored
2
vendor/github.com/getsentry/sentry-go/sentry.go
generated
vendored
|
|
@ -6,7 +6,7 @@ import (
|
|||
)
|
||||
|
||||
// The version of the SDK.
|
||||
const SDKVersion = "0.30.0"
|
||||
const SDKVersion = "0.31.1"
|
||||
|
||||
// apiVersion is the minimum version of the Sentry API compatible with the
|
||||
// sentry-go SDK.
|
||||
|
|
|
|||
95
vendor/github.com/getsentry/sentry-go/traces_profiler.go
generated
vendored
95
vendor/github.com/getsentry/sentry-go/traces_profiler.go
generated
vendored
|
|
@ -1,95 +0,0 @@
|
|||
package sentry
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Checks whether the transaction should be profiled (according to ProfilesSampleRate)
|
||||
// and starts a profiler if so.
|
||||
func (s *Span) sampleTransactionProfile() {
|
||||
var sampleRate = s.clientOptions().ProfilesSampleRate
|
||||
switch {
|
||||
case sampleRate < 0.0 || sampleRate > 1.0:
|
||||
Logger.Printf("Skipping transaction profiling: ProfilesSampleRate out of range [0.0, 1.0]: %f\n", sampleRate)
|
||||
case sampleRate == 0.0 || rng.Float64() >= sampleRate:
|
||||
Logger.Printf("Skipping transaction profiling: ProfilesSampleRate is: %f\n", sampleRate)
|
||||
default:
|
||||
startProfilerOnce.Do(startGlobalProfiler)
|
||||
if globalProfiler == nil {
|
||||
Logger.Println("Skipping transaction profiling: the profiler couldn't be started")
|
||||
} else {
|
||||
s.collectProfile = collectTransactionProfile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// transactionProfiler collects a profile for a given span.
|
||||
type transactionProfiler func(span *Span) *profileInfo
|
||||
|
||||
var startProfilerOnce sync.Once
|
||||
var globalProfiler profiler
|
||||
|
||||
func startGlobalProfiler() {
|
||||
globalProfiler = startProfiling(time.Now())
|
||||
}
|
||||
|
||||
func collectTransactionProfile(span *Span) *profileInfo {
|
||||
result := globalProfiler.GetSlice(span.StartTime, span.EndTime)
|
||||
if result == nil || result.trace == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
info := &profileInfo{
|
||||
Version: "1",
|
||||
EventID: uuid(),
|
||||
// See https://github.com/getsentry/sentry-go/pull/626#discussion_r1204870340 for explanation why we use the Transaction time.
|
||||
Timestamp: span.StartTime,
|
||||
Trace: result.trace,
|
||||
Transaction: profileTransaction{
|
||||
DurationNS: uint64(span.EndTime.Sub(span.StartTime).Nanoseconds()),
|
||||
Name: span.Name,
|
||||
TraceID: span.TraceID.String(),
|
||||
},
|
||||
}
|
||||
if len(info.Transaction.Name) == 0 {
|
||||
// Name is required by Relay so use the operation name if the span name is empty.
|
||||
info.Transaction.Name = span.Op
|
||||
}
|
||||
if result.callerGoID > 0 {
|
||||
info.Transaction.ActiveThreadID = result.callerGoID
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func (info *profileInfo) UpdateFromEvent(event *Event) {
|
||||
info.Environment = event.Environment
|
||||
info.Platform = event.Platform
|
||||
info.Release = event.Release
|
||||
info.Dist = event.Dist
|
||||
info.Transaction.ID = event.EventID
|
||||
|
||||
getStringFromContext := func(context map[string]interface{}, originalValue, key string) string {
|
||||
v, ok := context[key]
|
||||
if !ok {
|
||||
return originalValue
|
||||
}
|
||||
|
||||
if s, ok := v.(string); ok {
|
||||
return s
|
||||
}
|
||||
|
||||
return originalValue
|
||||
}
|
||||
|
||||
if runtimeContext, ok := event.Contexts["runtime"]; ok {
|
||||
info.Runtime.Name = getStringFromContext(runtimeContext, info.Runtime.Name, "name")
|
||||
info.Runtime.Version = getStringFromContext(runtimeContext, info.Runtime.Version, "version")
|
||||
}
|
||||
if osContext, ok := event.Contexts["os"]; ok {
|
||||
info.OS.Name = getStringFromContext(osContext, info.OS.Name, "name")
|
||||
}
|
||||
if deviceContext, ok := event.Contexts["device"]; ok {
|
||||
info.Device.Architecture = getStringFromContext(deviceContext, info.Device.Architecture, "arch")
|
||||
}
|
||||
}
|
||||
11
vendor/github.com/getsentry/sentry-go/tracing.go
generated
vendored
11
vendor/github.com/getsentry/sentry-go/tracing.go
generated
vendored
|
|
@ -68,8 +68,6 @@ type Span struct { //nolint: maligned // prefer readability over optimal memory
|
|||
recorder *spanRecorder
|
||||
// span context, can only be set on transactions
|
||||
contexts map[string]Context
|
||||
// collectProfile is a function that collects a profile of the current transaction. May be nil.
|
||||
collectProfile transactionProfiler
|
||||
// a Once instance to make sure that Finish() is only called once.
|
||||
finishOnce sync.Once
|
||||
}
|
||||
|
|
@ -202,11 +200,6 @@ func StartSpan(ctx context.Context, operation string, options ...SpanOption) *Sp
|
|||
hub.Scope().SetSpan(&span)
|
||||
}
|
||||
|
||||
// Start profiling only if it's a sampled root transaction.
|
||||
if span.IsTransaction() && span.Sampled.Bool() {
|
||||
span.sampleTransactionProfile()
|
||||
}
|
||||
|
||||
return &span
|
||||
}
|
||||
|
||||
|
|
@ -373,10 +366,6 @@ func (s *Span) doFinish() {
|
|||
return
|
||||
}
|
||||
|
||||
if s.collectProfile != nil {
|
||||
event.sdkMetaData.transactionProfile = s.collectProfile(s)
|
||||
}
|
||||
|
||||
// TODO(tracing): add breadcrumbs
|
||||
// (see https://github.com/getsentry/sentry-python/blob/f6f3525f8812f609/sentry_sdk/tracing.py#L372)
|
||||
|
||||
|
|
|
|||
144
vendor/github.com/getsentry/sentry-go/transport.go
generated
vendored
144
vendor/github.com/getsentry/sentry-go/transport.go
generated
vendored
|
|
@ -35,6 +35,7 @@ type Transport interface {
|
|||
Flush(timeout time.Duration) bool
|
||||
Configure(options ClientOptions)
|
||||
SendEvent(event *Event)
|
||||
Close()
|
||||
}
|
||||
|
||||
func getProxyConfig(options ClientOptions) func(*http.Request) (*url.URL, error) {
|
||||
|
|
@ -95,55 +96,6 @@ func getRequestBodyFromEvent(event *Event) []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
func marshalMetrics(metrics []Metric) []byte {
|
||||
var b bytes.Buffer
|
||||
for i, metric := range metrics {
|
||||
b.WriteString(metric.GetKey())
|
||||
if unit := metric.GetUnit(); unit != "" {
|
||||
b.WriteString(fmt.Sprintf("@%s", unit))
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("%s|%s", metric.SerializeValue(), metric.GetType()))
|
||||
if serializedTags := metric.SerializeTags(); serializedTags != "" {
|
||||
b.WriteString(fmt.Sprintf("|#%s", serializedTags))
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("|T%d", metric.GetTimestamp()))
|
||||
|
||||
if i < len(metrics)-1 {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func encodeMetric(enc *json.Encoder, b io.Writer, metrics []Metric) error {
|
||||
body := marshalMetrics(metrics)
|
||||
// Item header
|
||||
err := enc.Encode(struct {
|
||||
Type string `json:"type"`
|
||||
Length int `json:"length"`
|
||||
}{
|
||||
Type: metricType,
|
||||
Length: len(body),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// metric payload
|
||||
if _, err = b.Write(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// "Envelopes should be terminated with a trailing newline."
|
||||
//
|
||||
// [1]: https://develop.sentry.dev/sdk/envelopes/#envelopes
|
||||
if _, err := b.Write([]byte("\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeAttachment(enc *json.Encoder, b io.Writer, attachment *Attachment) error {
|
||||
// Attachment header
|
||||
err := enc.Encode(struct {
|
||||
|
|
@ -228,8 +180,6 @@ func envelopeFromBody(event *Event, dsn *Dsn, sentAt time.Time, body json.RawMes
|
|||
switch event.Type {
|
||||
case transactionType, checkInType:
|
||||
err = encodeEnvelopeItem(enc, event.Type, body)
|
||||
case metricType:
|
||||
err = encodeMetric(enc, &b, event.Metrics)
|
||||
default:
|
||||
err = encodeEnvelopeItem(enc, eventType, body)
|
||||
}
|
||||
|
|
@ -245,18 +195,6 @@ func envelopeFromBody(event *Event, dsn *Dsn, sentAt time.Time, body json.RawMes
|
|||
}
|
||||
}
|
||||
|
||||
// Profile data
|
||||
if event.sdkMetaData.transactionProfile != nil {
|
||||
body, err = json.Marshal(event.sdkMetaData.transactionProfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = encodeEnvelopeItem(enc, profileType, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
|
|
@ -352,6 +290,9 @@ type HTTPTransport struct {
|
|||
|
||||
mu sync.RWMutex
|
||||
limits ratelimit.Map
|
||||
|
||||
// receiving signal will terminate worker.
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// NewHTTPTransport returns a new pre-configured instance of HTTPTransport.
|
||||
|
|
@ -359,6 +300,7 @@ func NewHTTPTransport() *HTTPTransport {
|
|||
transport := HTTPTransport{
|
||||
BufferSize: defaultBufferSize,
|
||||
Timeout: defaultTimeout,
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
return &transport
|
||||
}
|
||||
|
|
@ -524,6 +466,15 @@ fail:
|
|||
return false
|
||||
}
|
||||
|
||||
// Close will terminate events sending loop.
|
||||
// It useful to prevent goroutines leak in case of multiple HTTPTransport instances initiated.
|
||||
//
|
||||
// Close should be called after Flush and before terminating the program
|
||||
// otherwise some events may be lost.
|
||||
func (t *HTTPTransport) Close() {
|
||||
close(t.done)
|
||||
}
|
||||
|
||||
func (t *HTTPTransport) worker() {
|
||||
for b := range t.buffer {
|
||||
// Signal that processing of the current batch has started.
|
||||
|
|
@ -534,35 +485,44 @@ func (t *HTTPTransport) worker() {
|
|||
t.buffer <- b
|
||||
|
||||
// Process all batch items.
|
||||
for item := range b.items {
|
||||
if t.disabled(item.category) {
|
||||
continue
|
||||
}
|
||||
|
||||
response, err := t.client.Do(item.request)
|
||||
if err != nil {
|
||||
Logger.Printf("There was an issue with sending an event: %v", err)
|
||||
continue
|
||||
}
|
||||
if response.StatusCode >= 400 && response.StatusCode <= 599 {
|
||||
b, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
Logger.Printf("Error while reading response code: %v", err)
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case <-t.done:
|
||||
return
|
||||
case item, open := <-b.items:
|
||||
if !open {
|
||||
break loop
|
||||
}
|
||||
if t.disabled(item.category) {
|
||||
continue
|
||||
}
|
||||
Logger.Printf("Sending %s failed with the following error: %s", eventType, string(b))
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
if t.limits == nil {
|
||||
t.limits = make(ratelimit.Map)
|
||||
}
|
||||
t.limits.Merge(ratelimit.FromResponse(response))
|
||||
t.mu.Unlock()
|
||||
response, err := t.client.Do(item.request)
|
||||
if err != nil {
|
||||
Logger.Printf("There was an issue with sending an event: %v", err)
|
||||
continue
|
||||
}
|
||||
if response.StatusCode >= 400 && response.StatusCode <= 599 {
|
||||
b, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
Logger.Printf("Error while reading response code: %v", err)
|
||||
}
|
||||
Logger.Printf("Sending %s failed with the following error: %s", eventType, string(b))
|
||||
}
|
||||
|
||||
// Drain body up to a limit and close it, allowing the
|
||||
// transport to reuse TCP connections.
|
||||
_, _ = io.CopyN(io.Discard, response.Body, maxDrainResponseBytes)
|
||||
response.Body.Close()
|
||||
t.mu.Lock()
|
||||
if t.limits == nil {
|
||||
t.limits = make(ratelimit.Map)
|
||||
}
|
||||
t.limits.Merge(ratelimit.FromResponse(response))
|
||||
t.mu.Unlock()
|
||||
|
||||
// Drain body up to a limit and close it, allowing the
|
||||
// transport to reuse TCP connections.
|
||||
_, _ = io.CopyN(io.Discard, response.Body, maxDrainResponseBytes)
|
||||
response.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Signal that processing of the batch is done.
|
||||
|
|
@ -650,6 +610,8 @@ func (t *HTTPSyncTransport) SendEvent(event *Event) {
|
|||
t.SendEventWithContext(context.Background(), event)
|
||||
}
|
||||
|
||||
func (t *HTTPSyncTransport) Close() {}
|
||||
|
||||
// SendEventWithContext assembles a new packet out of Event and sends it to the remote server.
|
||||
func (t *HTTPSyncTransport) SendEventWithContext(ctx context.Context, event *Event) {
|
||||
if t.dsn == nil {
|
||||
|
|
@ -669,8 +631,6 @@ func (t *HTTPSyncTransport) SendEventWithContext(ctx context.Context, event *Eve
|
|||
switch {
|
||||
case event.Type == transactionType:
|
||||
eventType = "transaction"
|
||||
case event.Type == metricType:
|
||||
eventType = metricType
|
||||
default:
|
||||
eventType = fmt.Sprintf("%s event", event.Level)
|
||||
}
|
||||
|
|
@ -745,3 +705,5 @@ func (noopTransport) SendEvent(*Event) {
|
|||
func (noopTransport) Flush(time.Duration) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (noopTransport) Close() {}
|
||||
|
|
|
|||
338
vendor/github.com/hashicorp/golang-lru/v2/expirable/expirable_lru.go
generated
vendored
338
vendor/github.com/hashicorp/golang-lru/v2/expirable/expirable_lru.go
generated
vendored
|
|
@ -1,338 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package expirable
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/internal"
|
||||
)
|
||||
|
||||
// EvictCallback is used to get a callback when a cache entry is evicted
|
||||
type EvictCallback[K comparable, V any] func(key K, value V)
|
||||
|
||||
// LRU implements a thread-safe LRU with expirable entries.
|
||||
type LRU[K comparable, V any] struct {
|
||||
size int
|
||||
evictList *internal.LruList[K, V]
|
||||
items map[K]*internal.Entry[K, V]
|
||||
onEvict EvictCallback[K, V]
|
||||
|
||||
// expirable options
|
||||
mu sync.Mutex
|
||||
ttl time.Duration
|
||||
done chan struct{}
|
||||
|
||||
// buckets for expiration
|
||||
buckets []bucket[K, V]
|
||||
// uint8 because it's number between 0 and numBuckets
|
||||
nextCleanupBucket uint8
|
||||
}
|
||||
|
||||
// bucket is a container for holding entries to be expired
|
||||
type bucket[K comparable, V any] struct {
|
||||
entries map[K]*internal.Entry[K, V]
|
||||
newestEntry time.Time
|
||||
}
|
||||
|
||||
// noEvictionTTL - very long ttl to prevent eviction
|
||||
const noEvictionTTL = time.Hour * 24 * 365 * 10
|
||||
|
||||
// because of uint8 usage for nextCleanupBucket, should not exceed 256.
|
||||
// casting it as uint8 explicitly requires type conversions in multiple places
|
||||
const numBuckets = 100
|
||||
|
||||
// NewLRU returns a new thread-safe cache with expirable entries.
|
||||
//
|
||||
// Size parameter set to 0 makes cache of unlimited size, e.g. turns LRU mechanism off.
|
||||
//
|
||||
// Providing 0 TTL turns expiring off.
|
||||
//
|
||||
// Delete expired entries every 1/100th of ttl value. Goroutine which deletes expired entries runs indefinitely.
|
||||
func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V], ttl time.Duration) *LRU[K, V] {
|
||||
if size < 0 {
|
||||
size = 0
|
||||
}
|
||||
if ttl <= 0 {
|
||||
ttl = noEvictionTTL
|
||||
}
|
||||
|
||||
res := LRU[K, V]{
|
||||
ttl: ttl,
|
||||
size: size,
|
||||
evictList: internal.NewList[K, V](),
|
||||
items: make(map[K]*internal.Entry[K, V]),
|
||||
onEvict: onEvict,
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
// initialize the buckets
|
||||
res.buckets = make([]bucket[K, V], numBuckets)
|
||||
for i := 0; i < numBuckets; i++ {
|
||||
res.buckets[i] = bucket[K, V]{entries: make(map[K]*internal.Entry[K, V])}
|
||||
}
|
||||
|
||||
// enable deleteExpired() running in separate goroutine for cache with non-zero TTL
|
||||
//
|
||||
// Important: done channel is never closed, so deleteExpired() goroutine will never exit,
|
||||
// it's decided to add functionality to close it in the version later than v2.
|
||||
if res.ttl != noEvictionTTL {
|
||||
go func(done <-chan struct{}) {
|
||||
ticker := time.NewTicker(res.ttl / numBuckets)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-ticker.C:
|
||||
res.deleteExpired()
|
||||
}
|
||||
}
|
||||
}(res.done)
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
// Purge clears the cache completely.
|
||||
// onEvict is called for each evicted key.
|
||||
func (c *LRU[K, V]) Purge() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
for k, v := range c.items {
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(k, v.Value)
|
||||
}
|
||||
delete(c.items, k)
|
||||
}
|
||||
for _, b := range c.buckets {
|
||||
for _, ent := range b.entries {
|
||||
delete(b.entries, ent.Key)
|
||||
}
|
||||
}
|
||||
c.evictList.Init()
|
||||
}
|
||||
|
||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
||||
// Returns false if there was no eviction: the item was already in the cache,
|
||||
// or the size was not exceeded.
|
||||
func (c *LRU[K, V]) Add(key K, value V) (evicted bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
now := time.Now()
|
||||
|
||||
// Check for existing item
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.evictList.MoveToFront(ent)
|
||||
c.removeFromBucket(ent) // remove the entry from its current bucket as expiresAt is renewed
|
||||
ent.Value = value
|
||||
ent.ExpiresAt = now.Add(c.ttl)
|
||||
c.addToBucket(ent)
|
||||
return false
|
||||
}
|
||||
|
||||
// Add new item
|
||||
ent := c.evictList.PushFrontExpirable(key, value, now.Add(c.ttl))
|
||||
c.items[key] = ent
|
||||
c.addToBucket(ent) // adds the entry to the appropriate bucket and sets entry.expireBucket
|
||||
|
||||
evict := c.size > 0 && c.evictList.Length() > c.size
|
||||
// Verify size not exceeded
|
||||
if evict {
|
||||
c.removeOldest()
|
||||
}
|
||||
return evict
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *LRU[K, V]) Get(key K) (value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
var ent *internal.Entry[K, V]
|
||||
if ent, ok = c.items[key]; ok {
|
||||
// Expired item check
|
||||
if time.Now().After(ent.ExpiresAt) {
|
||||
return value, false
|
||||
}
|
||||
c.evictList.MoveToFront(ent)
|
||||
return ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Contains checks if a key is in the cache, without updating the recent-ness
|
||||
// or deleting it for being stale.
|
||||
func (c *LRU[K, V]) Contains(key K) (ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
_, ok = c.items[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Peek returns the key value (or undefined if not found) without updating
|
||||
// the "recently used"-ness of the key.
|
||||
func (c *LRU[K, V]) Peek(key K) (value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
var ent *internal.Entry[K, V]
|
||||
if ent, ok = c.items[key]; ok {
|
||||
// Expired item check
|
||||
if time.Now().After(ent.ExpiresAt) {
|
||||
return value, false
|
||||
}
|
||||
return ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache, returning if the
|
||||
// key was contained.
|
||||
func (c *LRU[K, V]) Remove(key K) bool {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.removeElement(ent)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveOldest removes the oldest item from the cache.
|
||||
func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
c.removeElement(ent)
|
||||
return ent.Key, ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetOldest returns the oldest entry
|
||||
func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
return ent.Key, ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
||||
func (c *LRU[K, V]) Keys() []K {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
keys := make([]K, 0, len(c.items))
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() {
|
||||
keys = append(keys, ent.Key)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Values returns a slice of the values in the cache, from oldest to newest.
|
||||
// Expired entries are filtered out.
|
||||
func (c *LRU[K, V]) Values() []V {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
values := make([]V, len(c.items))
|
||||
i := 0
|
||||
now := time.Now()
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() {
|
||||
if now.After(ent.ExpiresAt) {
|
||||
continue
|
||||
}
|
||||
values[i] = ent.Value
|
||||
i++
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *LRU[K, V]) Len() int {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.evictList.Length()
|
||||
}
|
||||
|
||||
// Resize changes the cache size. Size of 0 means unlimited.
|
||||
func (c *LRU[K, V]) Resize(size int) (evicted int) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if size <= 0 {
|
||||
c.size = 0
|
||||
return 0
|
||||
}
|
||||
diff := c.evictList.Length() - size
|
||||
if diff < 0 {
|
||||
diff = 0
|
||||
}
|
||||
for i := 0; i < diff; i++ {
|
||||
c.removeOldest()
|
||||
}
|
||||
c.size = size
|
||||
return diff
|
||||
}
|
||||
|
||||
// Close destroys cleanup goroutine. To clean up the cache, run Purge() before Close().
|
||||
// func (c *LRU[K, V]) Close() {
|
||||
// c.mu.Lock()
|
||||
// defer c.mu.Unlock()
|
||||
// select {
|
||||
// case <-c.done:
|
||||
// return
|
||||
// default:
|
||||
// }
|
||||
// close(c.done)
|
||||
// }
|
||||
|
||||
// removeOldest removes the oldest item from the cache. Has to be called with lock!
|
||||
func (c *LRU[K, V]) removeOldest() {
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
c.removeElement(ent)
|
||||
}
|
||||
}
|
||||
|
||||
// removeElement is used to remove a given list element from the cache. Has to be called with lock!
|
||||
func (c *LRU[K, V]) removeElement(e *internal.Entry[K, V]) {
|
||||
c.evictList.Remove(e)
|
||||
delete(c.items, e.Key)
|
||||
c.removeFromBucket(e)
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(e.Key, e.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// deleteExpired deletes expired records from the oldest bucket, waiting for the newest entry
|
||||
// in it to expire first.
|
||||
func (c *LRU[K, V]) deleteExpired() {
|
||||
c.mu.Lock()
|
||||
bucketIdx := c.nextCleanupBucket
|
||||
timeToExpire := time.Until(c.buckets[bucketIdx].newestEntry)
|
||||
// wait for newest entry to expire before cleanup without holding lock
|
||||
if timeToExpire > 0 {
|
||||
c.mu.Unlock()
|
||||
time.Sleep(timeToExpire)
|
||||
c.mu.Lock()
|
||||
}
|
||||
for _, ent := range c.buckets[bucketIdx].entries {
|
||||
c.removeElement(ent)
|
||||
}
|
||||
c.nextCleanupBucket = (c.nextCleanupBucket + 1) % numBuckets
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// addToBucket adds entry to expire bucket so that it will be cleaned up when the time comes. Has to be called with lock!
|
||||
func (c *LRU[K, V]) addToBucket(e *internal.Entry[K, V]) {
|
||||
bucketID := (numBuckets + c.nextCleanupBucket - 1) % numBuckets
|
||||
e.ExpireBucket = bucketID
|
||||
c.buckets[bucketID].entries[e.Key] = e
|
||||
if c.buckets[bucketID].newestEntry.Before(e.ExpiresAt) {
|
||||
c.buckets[bucketID].newestEntry = e.ExpiresAt
|
||||
}
|
||||
}
|
||||
|
||||
// removeFromBucket removes the entry from its corresponding bucket. Has to be called with lock!
|
||||
func (c *LRU[K, V]) removeFromBucket(e *internal.Entry[K, V]) {
|
||||
delete(c.buckets[e.ExpireBucket].entries, e.Key)
|
||||
}
|
||||
38
vendor/github.com/mattn/go-colorable/colorable_appengine.go
generated
vendored
38
vendor/github.com/mattn/go-colorable/colorable_appengine.go
generated
vendored
|
|
@ -1,38 +0,0 @@
|
|||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
_ "github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
// NewColorable returns new instance of Writer which handles escape sequence.
|
||||
func NewColorable(file *os.File) io.Writer {
|
||||
if file == nil {
|
||||
panic("nil passed instead of *os.File to NewColorable()")
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||
func NewColorableStdout() io.Writer {
|
||||
return os.Stdout
|
||||
}
|
||||
|
||||
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||
func NewColorableStderr() io.Writer {
|
||||
return os.Stderr
|
||||
}
|
||||
|
||||
// EnableColorsStdout enable colors if possible.
|
||||
func EnableColorsStdout(enabled *bool) func() {
|
||||
if enabled != nil {
|
||||
*enabled = true
|
||||
}
|
||||
return func() {}
|
||||
}
|
||||
4
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
4
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
|
|
@ -1,5 +1,5 @@
|
|||
//go:build !windows && !appengine
|
||||
// +build !windows,!appengine
|
||||
//go:build !windows || appengine
|
||||
// +build !windows appengine
|
||||
|
||||
package colorable
|
||||
|
||||
|
|
|
|||
22
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
22
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
syscall "golang.org/x/sys/windows"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
|
|
@ -73,7 +73,7 @@ type consoleCursorInfo struct {
|
|||
}
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
kernel32 = syscall.NewLazySystemDLL("kernel32.dll")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
||||
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
||||
|
|
@ -87,8 +87,8 @@ var (
|
|||
procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer")
|
||||
)
|
||||
|
||||
// Writer provides colorable Writer to the console
|
||||
type Writer struct {
|
||||
// writer provides colorable Writer to the console
|
||||
type writer struct {
|
||||
out io.Writer
|
||||
handle syscall.Handle
|
||||
althandle syscall.Handle
|
||||
|
|
@ -98,7 +98,7 @@ type Writer struct {
|
|||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// NewColorable returns new instance of Writer which handles escape sequence from File.
|
||||
// NewColorable returns new instance of writer which handles escape sequence from File.
|
||||
func NewColorable(file *os.File) io.Writer {
|
||||
if file == nil {
|
||||
panic("nil passed instead of *os.File to NewColorable()")
|
||||
|
|
@ -112,17 +112,17 @@ func NewColorable(file *os.File) io.Writer {
|
|||
var csbi consoleScreenBufferInfo
|
||||
handle := syscall.Handle(file.Fd())
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
|
||||
return &writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||
// NewColorableStdout returns new instance of writer which handles escape sequence for stdout.
|
||||
func NewColorableStdout() io.Writer {
|
||||
return NewColorable(os.Stdout)
|
||||
}
|
||||
|
||||
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||
// NewColorableStderr returns new instance of writer which handles escape sequence for stderr.
|
||||
func NewColorableStderr() io.Writer {
|
||||
return NewColorable(os.Stderr)
|
||||
}
|
||||
|
|
@ -434,7 +434,7 @@ func atoiWithDefault(s string, def int) (int, error) {
|
|||
}
|
||||
|
||||
// Write writes data on console
|
||||
func (w *Writer) Write(data []byte) (n int, err error) {
|
||||
func (w *writer) Write(data []byte) (n int, err error) {
|
||||
w.mutex.Lock()
|
||||
defer w.mutex.Unlock()
|
||||
var csbi consoleScreenBufferInfo
|
||||
|
|
@ -560,7 +560,7 @@ loop:
|
|||
}
|
||||
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'E':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
n, err = atoiWithDefault(buf.String(), 1)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -569,7 +569,7 @@ loop:
|
|||
csbi.cursorPosition.y += short(n)
|
||||
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||
case 'F':
|
||||
n, err = strconv.Atoi(buf.String())
|
||||
n, err = atoiWithDefault(buf.String(), 1)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
4
vendor/go.mau.fi/util/confusable/skeleton.go
vendored
4
vendor/go.mau.fi/util/confusable/skeleton.go
vendored
|
|
@ -29,7 +29,7 @@ func Skeleton(input string) string {
|
|||
var builder strings.Builder
|
||||
builder.Grow(len(input))
|
||||
for _, r := range input {
|
||||
if !unicode.IsGraphic(r) {
|
||||
if !unicode.IsGraphic(r) && r != 0xfffd {
|
||||
continue
|
||||
}
|
||||
repl := GetReplacement(r)
|
||||
|
|
@ -48,7 +48,7 @@ func SkeletonBytes(input string) []byte {
|
|||
var builder bytes.Buffer
|
||||
builder.Grow(len(input))
|
||||
for _, r := range input {
|
||||
if !unicode.IsGraphic(r) {
|
||||
if !unicode.IsGraphic(r) && r != 0xfffd {
|
||||
continue
|
||||
}
|
||||
repl := GetReplacement(r)
|
||||
|
|
|
|||
26
vendor/go.mau.fi/util/dbutil/connlog.go
vendored
26
vendor/go.mau.fi/util/dbutil/connlog.go
vendored
|
|
@ -118,9 +118,10 @@ type internalTxnStarter interface {
|
|||
}
|
||||
|
||||
type TxnOptions struct {
|
||||
Isolation sql.IsolationLevel
|
||||
ReadOnly bool
|
||||
Conn Conn
|
||||
Isolation sql.IsolationLevel
|
||||
ReadOnly bool
|
||||
Conn Conn
|
||||
RetryBegin func(error, int) bool
|
||||
}
|
||||
|
||||
func (ld *loggingDB) BeginTx(ctx context.Context, opts *TxnOptions) (*LoggingTxn, error) {
|
||||
|
|
@ -134,14 +135,19 @@ func (ld *loggingDB) BeginTx(ctx context.Context, opts *TxnOptions) (*LoggingTxn
|
|||
var tx *sql.Tx
|
||||
var err error
|
||||
start := time.Now()
|
||||
if opts.Conn != nil {
|
||||
tx, err = opts.Conn.beginTx(ctx, sqlOpts)
|
||||
} else {
|
||||
targetDB := ld.db.RawDB
|
||||
if opts.ReadOnly && ld.db.ReadOnlyDB != nil {
|
||||
targetDB = ld.db.ReadOnlyDB
|
||||
for i := 0; ; i++ {
|
||||
if opts.Conn != nil {
|
||||
tx, err = opts.Conn.beginTx(ctx, sqlOpts)
|
||||
} else {
|
||||
targetDB := ld.db.RawDB
|
||||
if opts.ReadOnly && ld.db.ReadOnlyDB != nil {
|
||||
targetDB = ld.db.ReadOnlyDB
|
||||
}
|
||||
tx, err = targetDB.BeginTx(ctx, sqlOpts)
|
||||
}
|
||||
if opts.RetryBegin == nil || err == nil || !opts.RetryBegin(err, i) {
|
||||
break
|
||||
}
|
||||
tx, err = targetDB.BeginTx(ctx, sqlOpts)
|
||||
}
|
||||
ld.db.Log.QueryTiming(ctx, "Begin", "", nil, -1, time.Since(start), err)
|
||||
if err != nil {
|
||||
|
|
|
|||
38
vendor/go.mau.fi/util/dbutil/iter.go
vendored
38
vendor/go.mau.fi/util/dbutil/iter.go
vendored
|
|
@ -58,6 +58,44 @@ type rowIterImpl[T any] struct {
|
|||
}
|
||||
|
||||
// NewRowIter creates a new RowIter from the given Rows and scanner function.
|
||||
//
|
||||
// Deprecated: use NewRowIterWithError instead to avoid an unnecessary separate error check on the Query result.
|
||||
//
|
||||
// Instead of
|
||||
//
|
||||
// func DoQuery(...) (dbutil.RowIter, error) {
|
||||
// rows, err := db.Query(...)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return dbutil.NewRowIter(rows, convertFn), nil
|
||||
// }
|
||||
//
|
||||
// you should use
|
||||
//
|
||||
// func DoQuery(...) dbutil.RowIter {
|
||||
// rows, err := db.Query(...)
|
||||
// return dbutil.NewRowIterWithError(rows, convertFn, err)
|
||||
// }
|
||||
//
|
||||
// or alternatively pre-wrap the convertFn
|
||||
//
|
||||
// var converter = dbutil.ConvertRowFn(convertFn)
|
||||
// func DoQuery(...) dbutil.RowIter {
|
||||
// return converter.NewRowIter(db.Query(...))
|
||||
// }
|
||||
//
|
||||
// Embedding the error in the iterator allows the caller to do only one error check instead of two:
|
||||
//
|
||||
// iter, err := DoQuery(...)
|
||||
// if err != nil { ... }
|
||||
// result, err := iter.Iter(...)
|
||||
// if err != nil { ... }
|
||||
//
|
||||
// vs
|
||||
//
|
||||
// result, err := DoQuery(...).Iter(...)
|
||||
// if err != nil { ... }
|
||||
func NewRowIter[T any](rows Rows, convertFn ConvertRowFn[T]) RowIter[T] {
|
||||
return newRowIterWithError(rows, convertFn, nil)
|
||||
}
|
||||
|
|
|
|||
13
vendor/go.mau.fi/util/dbutil/queryhelper.go
vendored
13
vendor/go.mau.fi/util/dbutil/queryhelper.go
vendored
|
|
@ -126,9 +126,12 @@ func (qh *QueryHelper[T]) QueryOne(ctx context.Context, query string, args ...an
|
|||
// to scan each row, and returns the values. If the query returns no rows, it
|
||||
// returns a non-nil zero-length slice and no error.
|
||||
func (qh *QueryHelper[T]) QueryMany(ctx context.Context, query string, args ...any) ([]T, error) {
|
||||
rows, err := qh.db.Query(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRowIter(rows, qh.scanNew).AsList()
|
||||
return qh.QueryManyIter(ctx, query, args...).AsList()
|
||||
}
|
||||
|
||||
// QueryManyIter executes a query with QueryContext and returns a RowIter
|
||||
// that will use the associated DataStruct to scan each row.
|
||||
func (qh *QueryHelper[T]) QueryManyIter(ctx context.Context, query string, args ...any) RowIter[T] {
|
||||
rows, err := qh.db.Query(ctx, query, args...)
|
||||
return NewRowIterWithError(rows, qh.scanNew, err)
|
||||
}
|
||||
|
|
|
|||
78
vendor/go.mau.fi/util/exbytes/writer.go
vendored
Normal file
78
vendor/go.mau.fi/util/exbytes/writer.go
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2024 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package exbytes
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Writer is a simple byte writer that does not allow extending the buffer.
|
||||
//
|
||||
// Writes always go after the current len() and will fail if the slice capacity is too low.
|
||||
//
|
||||
// The correct way to use this is to create a slice with sufficient capacity and zero length:
|
||||
//
|
||||
// x := make([]byte, 0, 11)
|
||||
// w := (*Writer)(&x)
|
||||
// w.Write([]byte("hello"))
|
||||
// w.WriteByte(' ')
|
||||
// w.WriteString("world")
|
||||
// fmt.Println(string(x)) // "hello world"
|
||||
type Writer []byte
|
||||
|
||||
var ErrWriterBufferFull = errors.New("exbytes.Writer: buffer full")
|
||||
|
||||
var (
|
||||
_ io.Writer = (*Writer)(nil)
|
||||
_ io.StringWriter = (*Writer)(nil)
|
||||
_ io.ByteWriter = (*Writer)(nil)
|
||||
)
|
||||
|
||||
func (w *Writer) extendLen(n int) (int, error) {
|
||||
ptr := len(*w)
|
||||
if ptr+n > cap(*w) {
|
||||
return 0, fmt.Errorf("%w (%d + %d > %d)", ErrWriterBufferFull, ptr, n, cap(*w))
|
||||
}
|
||||
*w = (*w)[:ptr+n]
|
||||
return ptr, nil
|
||||
}
|
||||
|
||||
func (w *Writer) Write(b []byte) (n int, err error) {
|
||||
ptr, err := w.extendLen(len(b))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
copy((*w)[ptr:], b)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (w *Writer) WriteString(s string) (n int, err error) {
|
||||
ptr, err := w.extendLen(len(s))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
copy((*w)[ptr:], s)
|
||||
return len(s), nil
|
||||
}
|
||||
|
||||
func (w *Writer) WriteByte(r byte) error {
|
||||
ptr, err := w.extendLen(1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
(*w)[ptr] = r
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Writer) String() string {
|
||||
if w == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return string(*w)
|
||||
}
|
||||
11
vendor/go.mau.fi/util/exslices/cast.go
vendored
11
vendor/go.mau.fi/util/exslices/cast.go
vendored
|
|
@ -14,6 +14,17 @@ func CastFunc[To, From any](source []From, conv func(From) To) []To {
|
|||
return result
|
||||
}
|
||||
|
||||
func CastFuncFilter[To, From any](source []From, conv func(From) (To, bool)) []To {
|
||||
result := make([]To, 0, len(source))
|
||||
for _, v := range source {
|
||||
res, ok := conv(v)
|
||||
if ok {
|
||||
result = append(result, res)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func CastToString[To, From ~string](source []From) []To {
|
||||
result := make([]To, len(source))
|
||||
for i, v := range source {
|
||||
|
|
|
|||
48
vendor/go.mau.fi/util/glob/regex.go
vendored
48
vendor/go.mau.fi/util/glob/regex.go
vendored
|
|
@ -2,6 +2,7 @@ package glob
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -14,26 +15,59 @@ func (rg *RegexGlob) Match(s string) bool {
|
|||
return rg.regex.MatchString(s)
|
||||
}
|
||||
|
||||
func CompileRegex(pattern string) (*RegexGlob, error) {
|
||||
var buf strings.Builder
|
||||
buf.WriteRune('^')
|
||||
type swWriter interface {
|
||||
io.StringWriter
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// ToRegexPattern converts a glob pattern to a regex pattern and writes it to the given buffer.
|
||||
//
|
||||
// Only errors returned by the Write calls are returned by this function
|
||||
// (so if a non-erroring writer is used, this function will always return nil).
|
||||
func ToRegexPattern(pattern string, buf swWriter) error {
|
||||
for _, part := range SplitPattern(pattern) {
|
||||
if strings.ContainsRune(part, '*') || strings.ContainsRune(part, '?') {
|
||||
questions := strings.Count(part, "?")
|
||||
star := strings.ContainsRune(part, '*')
|
||||
if star {
|
||||
if questions > 0 {
|
||||
_, _ = fmt.Fprintf(&buf, ".{%d,}", questions)
|
||||
_, err := fmt.Fprintf(buf, ".{%d,}", questions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
buf.WriteString(".*")
|
||||
_, err := buf.WriteString(".*")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if questions > 0 {
|
||||
_, _ = fmt.Fprintf(&buf, ".{%d}", questions)
|
||||
_, err := fmt.Fprintf(buf, ".{%d}", questions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf.WriteString(regexp.QuoteMeta(part))
|
||||
_, err := buf.WriteString(regexp.QuoteMeta(part))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompileRegex compiles the given glob pattern into a regex pattern.
|
||||
//
|
||||
// If you want the raw regex string, use [ToRegexPattern] instead
|
||||
func CompileRegex(pattern string) (*RegexGlob, error) {
|
||||
var buf strings.Builder
|
||||
buf.WriteRune('^')
|
||||
err := ToRegexPattern(pattern, &buf)
|
||||
if err != nil {
|
||||
// This will never actually happen
|
||||
return nil, err
|
||||
}
|
||||
buf.WriteRune('$')
|
||||
regex, err := regexp.Compile(buf.String())
|
||||
if err != nil {
|
||||
|
|
|
|||
155
vendor/go.mau.fi/util/jsontime/duration.go
vendored
Normal file
155
vendor/go.mau.fi/util/jsontime/duration.go
vendored
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
// Copyright (c) 2025 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package jsontime
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func unmarshalDuration(into *time.Duration, jsonData []byte, unit time.Duration) error {
|
||||
val, err := strconv.ParseInt(string(jsonData), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*into = time.Duration(val) * unit
|
||||
return nil
|
||||
}
|
||||
|
||||
func anyIntegerToDuration(src any, unit time.Duration, into *time.Duration) error {
|
||||
i64, err := anyIntegerTo64(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*into = time.Duration(i64) * unit
|
||||
return nil
|
||||
}
|
||||
|
||||
type Seconds struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func S(dur time.Duration) Seconds {
|
||||
return Seconds{Duration: dur}
|
||||
}
|
||||
|
||||
func SInt(dur int) Seconds {
|
||||
return Seconds{Duration: time.Duration(dur) * time.Second}
|
||||
}
|
||||
|
||||
func (s Seconds) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.FormatInt(int64(s.Seconds()), 10)), nil
|
||||
}
|
||||
|
||||
func (s Seconds) Value() (driver.Value, error) {
|
||||
return int64(s.Seconds()), nil
|
||||
}
|
||||
|
||||
func (s *Seconds) UnmarshalJSON(data []byte) error {
|
||||
return unmarshalDuration(&s.Duration, data, time.Second)
|
||||
}
|
||||
|
||||
func (s *Seconds) Scan(src interface{}) error {
|
||||
return anyIntegerToDuration(src, time.Second, &s.Duration)
|
||||
}
|
||||
|
||||
func (s *Seconds) Get() time.Duration {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
return s.Duration
|
||||
}
|
||||
|
||||
type Milliseconds struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func MS(dur time.Duration) Milliseconds {
|
||||
return Milliseconds{Duration: dur}
|
||||
}
|
||||
|
||||
func MSInt(dur int64) Milliseconds {
|
||||
return Milliseconds{Duration: time.Duration(dur) * time.Millisecond}
|
||||
}
|
||||
|
||||
func (s Milliseconds) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.FormatInt(s.Milliseconds(), 10)), nil
|
||||
}
|
||||
|
||||
func (s Milliseconds) Value() (driver.Value, error) {
|
||||
return s.Milliseconds(), nil
|
||||
}
|
||||
|
||||
func (s *Milliseconds) UnmarshalJSON(data []byte) error {
|
||||
return unmarshalDuration(&s.Duration, data, time.Millisecond)
|
||||
}
|
||||
|
||||
func (s *Milliseconds) Scan(src interface{}) error {
|
||||
return anyIntegerToDuration(src, time.Millisecond, &s.Duration)
|
||||
}
|
||||
|
||||
func (s *Milliseconds) Get() time.Duration {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
return s.Duration
|
||||
}
|
||||
|
||||
type Microseconds struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func (s Microseconds) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.FormatInt(s.Microseconds(), 10)), nil
|
||||
}
|
||||
|
||||
func (s Microseconds) Value() (driver.Value, error) {
|
||||
return s.Microseconds(), nil
|
||||
}
|
||||
|
||||
func (s *Microseconds) UnmarshalJSON(data []byte) error {
|
||||
return unmarshalDuration(&s.Duration, data, time.Microsecond)
|
||||
}
|
||||
|
||||
func (s *Microseconds) Scan(src interface{}) error {
|
||||
return anyIntegerToDuration(src, time.Microsecond, &s.Duration)
|
||||
}
|
||||
|
||||
func (s *Microseconds) Get() time.Duration {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
return s.Duration
|
||||
}
|
||||
|
||||
type Nanoseconds struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func (s Nanoseconds) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.FormatInt(s.Nanoseconds(), 10)), nil
|
||||
}
|
||||
|
||||
func (s Nanoseconds) Value() (driver.Value, error) {
|
||||
return s.Nanoseconds(), nil
|
||||
}
|
||||
|
||||
func (s *Nanoseconds) UnmarshalJSON(data []byte) error {
|
||||
return unmarshalDuration(&s.Duration, data, time.Nanosecond)
|
||||
}
|
||||
|
||||
func (s *Nanoseconds) Scan(src interface{}) error {
|
||||
return anyIntegerToDuration(src, time.Nanosecond, &s.Duration)
|
||||
}
|
||||
|
||||
func (s *Nanoseconds) Get() time.Duration {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
return s.Duration
|
||||
}
|
||||
21
vendor/go.mau.fi/util/jsontime/integer.go
vendored
21
vendor/go.mau.fi/util/jsontime/integer.go
vendored
|
|
@ -31,22 +31,29 @@ func parseTime(data []byte, unixConv func(int64) time.Time, into *time.Time) err
|
|||
return nil
|
||||
}
|
||||
|
||||
func anyIntegerToTime(src any, unixConv func(int64) time.Time, into *time.Time) error {
|
||||
func anyIntegerTo64(src any) (int64, error) {
|
||||
switch v := src.(type) {
|
||||
case int:
|
||||
*into = unixConv(int64(v))
|
||||
return int64(v), nil
|
||||
case int8:
|
||||
*into = unixConv(int64(v))
|
||||
return int64(v), nil
|
||||
case int16:
|
||||
*into = unixConv(int64(v))
|
||||
return int64(v), nil
|
||||
case int32:
|
||||
*into = unixConv(int64(v))
|
||||
return int64(v), nil
|
||||
case int64:
|
||||
*into = unixConv(int64(v))
|
||||
return v, nil
|
||||
default:
|
||||
return fmt.Errorf("%w: %T", ErrNotInteger, src)
|
||||
return 0, fmt.Errorf("%w: %T", ErrNotInteger, src)
|
||||
}
|
||||
}
|
||||
|
||||
func anyIntegerToTime(src any, unixConv func(int64) time.Time, into *time.Time) error {
|
||||
i64, err := anyIntegerTo64(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*into = unixConv(i64)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
14
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
14
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
|
|
@ -80,6 +80,7 @@ type handshakeTransport struct {
|
|||
pendingPackets [][]byte // Used when a key exchange is in progress.
|
||||
writePacketsLeft uint32
|
||||
writeBytesLeft int64
|
||||
userAuthComplete bool // whether the user authentication phase is complete
|
||||
|
||||
// If the read loop wants to schedule a kex, it pings this
|
||||
// channel, and the write loop will send out a kex
|
||||
|
|
@ -552,16 +553,25 @@ func (t *handshakeTransport) sendKexInit() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase")
|
||||
|
||||
func (t *handshakeTransport) writePacket(p []byte) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
switch p[0] {
|
||||
case msgKexInit:
|
||||
return errors.New("ssh: only handshakeTransport can send kexInit")
|
||||
case msgNewKeys:
|
||||
return errors.New("ssh: only handshakeTransport can send newKeys")
|
||||
case msgUserAuthBanner:
|
||||
if t.userAuthComplete {
|
||||
return errSendBannerPhase
|
||||
}
|
||||
case msgUserAuthSuccess:
|
||||
t.userAuthComplete = true
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
if t.writeError != nil {
|
||||
return t.writeError
|
||||
}
|
||||
|
|
|
|||
50
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
50
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
|
|
@ -59,6 +59,27 @@ type GSSAPIWithMICConfig struct {
|
|||
Server GSSAPIServer
|
||||
}
|
||||
|
||||
// SendAuthBanner implements [ServerPreAuthConn].
|
||||
func (s *connection) SendAuthBanner(msg string) error {
|
||||
return s.transport.writePacket(Marshal(&userAuthBannerMsg{
|
||||
Message: msg,
|
||||
}))
|
||||
}
|
||||
|
||||
func (*connection) unexportedMethodForFutureProofing() {}
|
||||
|
||||
// ServerPreAuthConn is the interface available on an incoming server
|
||||
// connection before authentication has completed.
|
||||
type ServerPreAuthConn interface {
|
||||
unexportedMethodForFutureProofing() // permits growing ServerPreAuthConn safely later, ala testing.TB
|
||||
|
||||
ConnMetadata
|
||||
|
||||
// SendAuthBanner sends a banner message to the client.
|
||||
// It returns an error once the authentication phase has ended.
|
||||
SendAuthBanner(string) error
|
||||
}
|
||||
|
||||
// ServerConfig holds server specific configuration data.
|
||||
type ServerConfig struct {
|
||||
// Config contains configuration shared between client and server.
|
||||
|
|
@ -118,6 +139,12 @@ type ServerConfig struct {
|
|||
// attempts.
|
||||
AuthLogCallback func(conn ConnMetadata, method string, err error)
|
||||
|
||||
// PreAuthConnCallback, if non-nil, is called upon receiving a new connection
|
||||
// before any authentication has started. The provided ServerPreAuthConn
|
||||
// can be used at any time before authentication is complete, including
|
||||
// after this callback has returned.
|
||||
PreAuthConnCallback func(ServerPreAuthConn)
|
||||
|
||||
// ServerVersion is the version identification string to announce in
|
||||
// the public handshake.
|
||||
// If empty, a reasonable default is used.
|
||||
|
|
@ -488,6 +515,10 @@ func (b *BannerError) Error() string {
|
|||
}
|
||||
|
||||
func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
|
||||
if config.PreAuthConnCallback != nil {
|
||||
config.PreAuthConnCallback(s)
|
||||
}
|
||||
|
||||
sessionID := s.transport.getSessionID()
|
||||
var cache pubKeyCache
|
||||
var perms *Permissions
|
||||
|
|
@ -495,7 +526,7 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err
|
|||
authFailures := 0
|
||||
noneAuthCount := 0
|
||||
var authErrs []error
|
||||
var displayedBanner bool
|
||||
var calledBannerCallback bool
|
||||
partialSuccessReturned := false
|
||||
// Set the initial authentication callbacks from the config. They can be
|
||||
// changed if a PartialSuccessError is returned.
|
||||
|
|
@ -542,14 +573,10 @@ userAuthLoop:
|
|||
|
||||
s.user = userAuthReq.User
|
||||
|
||||
if !displayedBanner && config.BannerCallback != nil {
|
||||
displayedBanner = true
|
||||
msg := config.BannerCallback(s)
|
||||
if msg != "" {
|
||||
bannerMsg := &userAuthBannerMsg{
|
||||
Message: msg,
|
||||
}
|
||||
if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
|
||||
if !calledBannerCallback && config.BannerCallback != nil {
|
||||
calledBannerCallback = true
|
||||
if msg := config.BannerCallback(s); msg != "" {
|
||||
if err := s.SendAuthBanner(msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -762,10 +789,7 @@ userAuthLoop:
|
|||
var bannerErr *BannerError
|
||||
if errors.As(authErr, &bannerErr) {
|
||||
if bannerErr.Message != "" {
|
||||
bannerMsg := &userAuthBannerMsg{
|
||||
Message: bannerErr.Message,
|
||||
}
|
||||
if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
|
||||
if err := s.SendAuthBanner(bannerErr.Message); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
3
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
|
|
@ -72,6 +72,9 @@ var X86 struct {
|
|||
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||
HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add
|
||||
HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions
|
||||
HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
|
|
|
|||
21
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
21
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
|
|
@ -53,6 +53,9 @@ func initOptions() {
|
|||
{Name: "sse41", Feature: &X86.HasSSE41},
|
||||
{Name: "sse42", Feature: &X86.HasSSE42},
|
||||
{Name: "ssse3", Feature: &X86.HasSSSE3},
|
||||
{Name: "avxifma", Feature: &X86.HasAVXIFMA},
|
||||
{Name: "avxvnni", Feature: &X86.HasAVXVNNI},
|
||||
{Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8},
|
||||
|
||||
// These capabilities should always be enabled on amd64:
|
||||
{Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"},
|
||||
|
|
@ -106,7 +109,7 @@ func archInit() {
|
|||
return
|
||||
}
|
||||
|
||||
_, ebx7, ecx7, edx7 := cpuid(7, 0)
|
||||
eax7, ebx7, ecx7, edx7 := cpuid(7, 0)
|
||||
X86.HasBMI1 = isSet(3, ebx7)
|
||||
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
|
||||
X86.HasBMI2 = isSet(8, ebx7)
|
||||
|
|
@ -134,14 +137,24 @@ func archInit() {
|
|||
X86.HasAVX512VAES = isSet(9, ecx7)
|
||||
X86.HasAVX512VBMI2 = isSet(6, ecx7)
|
||||
X86.HasAVX512BITALG = isSet(12, ecx7)
|
||||
|
||||
eax71, _, _, _ := cpuid(7, 1)
|
||||
X86.HasAVX512BF16 = isSet(5, eax71)
|
||||
}
|
||||
|
||||
X86.HasAMXTile = isSet(24, edx7)
|
||||
X86.HasAMXInt8 = isSet(25, edx7)
|
||||
X86.HasAMXBF16 = isSet(22, edx7)
|
||||
|
||||
// These features depend on the second level of extended features.
|
||||
if eax7 >= 1 {
|
||||
eax71, _, _, edx71 := cpuid(7, 1)
|
||||
if X86.HasAVX512 {
|
||||
X86.HasAVX512BF16 = isSet(5, eax71)
|
||||
}
|
||||
if X86.HasAVX {
|
||||
X86.HasAVXIFMA = isSet(23, eax71)
|
||||
X86.HasAVXVNNI = isSet(4, eax71)
|
||||
X86.HasAVXVNNIInt8 = isSet(4, edx71)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isSet(bitpos uint, value uint32) bool {
|
||||
|
|
|
|||
36
vendor/golang.org/x/sys/unix/auxv.go
generated
vendored
Normal file
36
vendor/golang.org/x/sys/unix/auxv.go
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2025 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.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:linkname runtime_getAuxv runtime.getAuxv
|
||||
func runtime_getAuxv() []uintptr
|
||||
|
||||
// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs.
|
||||
// The returned slice is always a fresh copy, owned by the caller.
|
||||
// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed,
|
||||
// which happens in some locked-down environments and build modes.
|
||||
func Auxv() ([][2]uintptr, error) {
|
||||
vec := runtime_getAuxv()
|
||||
vecLen := len(vec)
|
||||
|
||||
if vecLen == 0 {
|
||||
return nil, syscall.ENOENT
|
||||
}
|
||||
|
||||
if vecLen%2 != 0 {
|
||||
return nil, syscall.EINVAL
|
||||
}
|
||||
|
||||
result := make([]uintptr, vecLen)
|
||||
copy(result, vec)
|
||||
return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil
|
||||
}
|
||||
13
vendor/golang.org/x/sys/unix/auxv_unsupported.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/auxv_unsupported.go
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2025 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.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
func Auxv() ([][2]uintptr, error) {
|
||||
return nil, syscall.ENOTSUP
|
||||
}
|
||||
12
vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
12
vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
|
|
@ -246,6 +246,18 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
|||
return sendfile(outfd, infd, offset, count)
|
||||
}
|
||||
|
||||
func Dup3(oldfd, newfd, flags int) error {
|
||||
if oldfd == newfd || flags&^O_CLOEXEC != 0 {
|
||||
return EINVAL
|
||||
}
|
||||
how := F_DUP2FD
|
||||
if flags&O_CLOEXEC != 0 {
|
||||
how = F_DUP2FD_CLOEXEC
|
||||
}
|
||||
_, err := fcntl(oldfd, how, newfd)
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
* Exposed directly
|
||||
*/
|
||||
|
|
|
|||
87
vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
87
vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
|
|
@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) {
|
|||
func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) {
|
||||
return ioctlPtrRet(fd, req, unsafe.Pointer(s))
|
||||
}
|
||||
|
||||
// Ucred Helpers
|
||||
// See ucred(3c) and getpeerucred(3c)
|
||||
|
||||
//sys getpeerucred(fd uintptr, ucred *uintptr) (err error)
|
||||
//sys ucredFree(ucred uintptr) = ucred_free
|
||||
//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get
|
||||
//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid
|
||||
//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid
|
||||
//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid
|
||||
//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid
|
||||
//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid
|
||||
//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid
|
||||
//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid
|
||||
|
||||
// Ucred is an opaque struct that holds user credentials.
|
||||
type Ucred struct {
|
||||
ucred uintptr
|
||||
}
|
||||
|
||||
// We need to ensure that ucredFree is called on the underlying ucred
|
||||
// when the Ucred is garbage collected.
|
||||
func ucredFinalizer(u *Ucred) {
|
||||
ucredFree(u.ucred)
|
||||
}
|
||||
|
||||
func GetPeerUcred(fd uintptr) (*Ucred, error) {
|
||||
var ucred uintptr
|
||||
err := getpeerucred(fd, &ucred)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &Ucred{
|
||||
ucred: ucred,
|
||||
}
|
||||
// set the finalizer on the result so that the ucred will be freed
|
||||
runtime.SetFinalizer(result, ucredFinalizer)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func UcredGet(pid int) (*Ucred, error) {
|
||||
ucred, err := ucredGet(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &Ucred{
|
||||
ucred: ucred,
|
||||
}
|
||||
// set the finalizer on the result so that the ucred will be freed
|
||||
runtime.SetFinalizer(result, ucredFinalizer)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (u *Ucred) Geteuid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGeteuid(u.ucred)
|
||||
}
|
||||
|
||||
func (u *Ucred) Getruid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGetruid(u.ucred)
|
||||
}
|
||||
|
||||
func (u *Ucred) Getsuid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGetsuid(u.ucred)
|
||||
}
|
||||
|
||||
func (u *Ucred) Getegid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGetegid(u.ucred)
|
||||
}
|
||||
|
||||
func (u *Ucred) Getrgid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGetrgid(u.ucred)
|
||||
}
|
||||
|
||||
func (u *Ucred) Getsgid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGetsgid(u.ucred)
|
||||
}
|
||||
|
||||
func (u *Ucred) Getpid() int {
|
||||
defer runtime.KeepAlive(u)
|
||||
return ucredGetpid(u.ucred)
|
||||
}
|
||||
|
|
|
|||
20
vendor/golang.org/x/sys/unix/zerrors_linux.go
generated
vendored
20
vendor/golang.org/x/sys/unix/zerrors_linux.go
generated
vendored
|
|
@ -1245,6 +1245,7 @@ const (
|
|||
FAN_REPORT_DFID_NAME = 0xc00
|
||||
FAN_REPORT_DFID_NAME_TARGET = 0x1e00
|
||||
FAN_REPORT_DIR_FID = 0x400
|
||||
FAN_REPORT_FD_ERROR = 0x2000
|
||||
FAN_REPORT_FID = 0x200
|
||||
FAN_REPORT_NAME = 0x800
|
||||
FAN_REPORT_PIDFD = 0x80
|
||||
|
|
@ -1330,8 +1331,10 @@ const (
|
|||
FUSE_SUPER_MAGIC = 0x65735546
|
||||
FUTEXFS_SUPER_MAGIC = 0xbad1dea
|
||||
F_ADD_SEALS = 0x409
|
||||
F_CREATED_QUERY = 0x404
|
||||
F_DUPFD = 0x0
|
||||
F_DUPFD_CLOEXEC = 0x406
|
||||
F_DUPFD_QUERY = 0x403
|
||||
F_EXLCK = 0x4
|
||||
F_GETFD = 0x1
|
||||
F_GETFL = 0x3
|
||||
|
|
@ -1551,6 +1554,7 @@ const (
|
|||
IPPROTO_ROUTING = 0x2b
|
||||
IPPROTO_RSVP = 0x2e
|
||||
IPPROTO_SCTP = 0x84
|
||||
IPPROTO_SMC = 0x100
|
||||
IPPROTO_TCP = 0x6
|
||||
IPPROTO_TP = 0x1d
|
||||
IPPROTO_UDP = 0x11
|
||||
|
|
@ -1623,6 +1627,8 @@ const (
|
|||
IPV6_UNICAST_IF = 0x4c
|
||||
IPV6_USER_FLOW = 0xe
|
||||
IPV6_V6ONLY = 0x1a
|
||||
IPV6_VERSION = 0x60
|
||||
IPV6_VERSION_MASK = 0xf0
|
||||
IPV6_XFRM_POLICY = 0x23
|
||||
IP_ADD_MEMBERSHIP = 0x23
|
||||
IP_ADD_SOURCE_MEMBERSHIP = 0x27
|
||||
|
|
@ -1867,6 +1873,7 @@ const (
|
|||
MADV_UNMERGEABLE = 0xd
|
||||
MADV_WILLNEED = 0x3
|
||||
MADV_WIPEONFORK = 0x12
|
||||
MAP_DROPPABLE = 0x8
|
||||
MAP_FILE = 0x0
|
||||
MAP_FIXED = 0x10
|
||||
MAP_FIXED_NOREPLACE = 0x100000
|
||||
|
|
@ -1967,6 +1974,7 @@ const (
|
|||
MSG_PEEK = 0x2
|
||||
MSG_PROXY = 0x10
|
||||
MSG_RST = 0x1000
|
||||
MSG_SOCK_DEVMEM = 0x2000000
|
||||
MSG_SYN = 0x400
|
||||
MSG_TRUNC = 0x20
|
||||
MSG_TRYHARD = 0x4
|
||||
|
|
@ -2083,6 +2091,7 @@ const (
|
|||
NFC_ATR_REQ_MAXSIZE = 0x40
|
||||
NFC_ATR_RES_GB_MAXSIZE = 0x2f
|
||||
NFC_ATR_RES_MAXSIZE = 0x40
|
||||
NFC_ATS_MAXSIZE = 0x14
|
||||
NFC_COMM_ACTIVE = 0x0
|
||||
NFC_COMM_PASSIVE = 0x1
|
||||
NFC_DEVICE_NAME_MAXSIZE = 0x8
|
||||
|
|
@ -2163,6 +2172,7 @@ const (
|
|||
NFNL_SUBSYS_QUEUE = 0x3
|
||||
NFNL_SUBSYS_ULOG = 0x4
|
||||
NFS_SUPER_MAGIC = 0x6969
|
||||
NFT_BITWISE_BOOL = 0x0
|
||||
NFT_CHAIN_FLAGS = 0x7
|
||||
NFT_CHAIN_MAXNAMELEN = 0x100
|
||||
NFT_CT_MAX = 0x17
|
||||
|
|
@ -2491,6 +2501,7 @@ const (
|
|||
PR_GET_PDEATHSIG = 0x2
|
||||
PR_GET_SECCOMP = 0x15
|
||||
PR_GET_SECUREBITS = 0x1b
|
||||
PR_GET_SHADOW_STACK_STATUS = 0x4a
|
||||
PR_GET_SPECULATION_CTRL = 0x34
|
||||
PR_GET_TAGGED_ADDR_CTRL = 0x38
|
||||
PR_GET_THP_DISABLE = 0x2a
|
||||
|
|
@ -2499,6 +2510,7 @@ const (
|
|||
PR_GET_TIMING = 0xd
|
||||
PR_GET_TSC = 0x19
|
||||
PR_GET_UNALIGN = 0x5
|
||||
PR_LOCK_SHADOW_STACK_STATUS = 0x4c
|
||||
PR_MCE_KILL = 0x21
|
||||
PR_MCE_KILL_CLEAR = 0x0
|
||||
PR_MCE_KILL_DEFAULT = 0x2
|
||||
|
|
@ -2525,6 +2537,8 @@ const (
|
|||
PR_PAC_GET_ENABLED_KEYS = 0x3d
|
||||
PR_PAC_RESET_KEYS = 0x36
|
||||
PR_PAC_SET_ENABLED_KEYS = 0x3c
|
||||
PR_PMLEN_MASK = 0x7f000000
|
||||
PR_PMLEN_SHIFT = 0x18
|
||||
PR_PPC_DEXCR_CTRL_CLEAR = 0x4
|
||||
PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10
|
||||
PR_PPC_DEXCR_CTRL_EDITABLE = 0x1
|
||||
|
|
@ -2592,6 +2606,7 @@ const (
|
|||
PR_SET_PTRACER = 0x59616d61
|
||||
PR_SET_SECCOMP = 0x16
|
||||
PR_SET_SECUREBITS = 0x1c
|
||||
PR_SET_SHADOW_STACK_STATUS = 0x4b
|
||||
PR_SET_SPECULATION_CTRL = 0x35
|
||||
PR_SET_SYSCALL_USER_DISPATCH = 0x3b
|
||||
PR_SET_TAGGED_ADDR_CTRL = 0x37
|
||||
|
|
@ -2602,6 +2617,9 @@ const (
|
|||
PR_SET_UNALIGN = 0x6
|
||||
PR_SET_VMA = 0x53564d41
|
||||
PR_SET_VMA_ANON_NAME = 0x0
|
||||
PR_SHADOW_STACK_ENABLE = 0x1
|
||||
PR_SHADOW_STACK_PUSH = 0x4
|
||||
PR_SHADOW_STACK_WRITE = 0x2
|
||||
PR_SME_GET_VL = 0x40
|
||||
PR_SME_SET_VL = 0x3f
|
||||
PR_SME_SET_VL_ONEXEC = 0x40000
|
||||
|
|
@ -2911,7 +2929,6 @@ const (
|
|||
RTM_NEWNEXTHOP = 0x68
|
||||
RTM_NEWNEXTHOPBUCKET = 0x74
|
||||
RTM_NEWNSID = 0x58
|
||||
RTM_NEWNVLAN = 0x70
|
||||
RTM_NEWPREFIX = 0x34
|
||||
RTM_NEWQDISC = 0x24
|
||||
RTM_NEWROUTE = 0x18
|
||||
|
|
@ -2920,6 +2937,7 @@ const (
|
|||
RTM_NEWTCLASS = 0x28
|
||||
RTM_NEWTFILTER = 0x2c
|
||||
RTM_NEWTUNNEL = 0x78
|
||||
RTM_NEWVLAN = 0x70
|
||||
RTM_NR_FAMILIES = 0x1b
|
||||
RTM_NR_MSGTYPES = 0x6c
|
||||
RTM_SETDCB = 0x4f
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
|
|
@ -116,6 +116,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -304,6 +306,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
|
|
@ -116,6 +116,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -305,6 +307,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -310,6 +312,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
|
|
@ -109,6 +109,7 @@ const (
|
|||
F_SETOWN = 0x8
|
||||
F_UNLCK = 0x2
|
||||
F_WRLCK = 0x1
|
||||
GCS_MAGIC = 0x47435300
|
||||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
|
|
@ -119,6 +120,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -302,6 +305,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
generated
vendored
|
|
@ -116,6 +116,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -297,6 +299,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x80
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -303,6 +305,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x80
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -303,6 +305,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x80
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -303,6 +305,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x80
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -303,6 +305,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||
ISIG = 0x80
|
||||
IUCLC = 0x1000
|
||||
IXOFF = 0x400
|
||||
|
|
@ -358,6 +360,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||
ISIG = 0x80
|
||||
IUCLC = 0x1000
|
||||
IXOFF = 0x400
|
||||
|
|
@ -362,6 +364,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x80
|
||||
IUCLC = 0x1000
|
||||
IXOFF = 0x400
|
||||
|
|
@ -362,6 +364,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -294,6 +296,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
|
|
@ -115,6 +115,8 @@ const (
|
|||
IN_CLOEXEC = 0x80000
|
||||
IN_NONBLOCK = 0x800
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -366,6 +368,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TS_OPT_ID = 0x51
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
|
|
|
|||
3
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
generated
vendored
|
|
@ -119,6 +119,8 @@ const (
|
|||
IN_CLOEXEC = 0x400000
|
||||
IN_NONBLOCK = 0x4000
|
||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||
ISIG = 0x1
|
||||
IUCLC = 0x200
|
||||
IXOFF = 0x1000
|
||||
|
|
@ -357,6 +359,7 @@ const (
|
|||
SCM_TIMESTAMPING_OPT_STATS = 0x38
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3c
|
||||
SCM_TIMESTAMPNS = 0x21
|
||||
SCM_TS_OPT_ID = 0x5a
|
||||
SCM_TXTIME = 0x3f
|
||||
SCM_WIFI_STATUS = 0x25
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
|
|
|
|||
114
vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
generated
vendored
114
vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
generated
vendored
|
|
@ -141,6 +141,16 @@ import (
|
|||
//go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so"
|
||||
//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so"
|
||||
//go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
|
||||
//go:cgo_import_dynamic libc_getpeerucred getpeerucred "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_get ucred_get "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_geteuid ucred_geteuid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_getegid ucred_getegid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_getruid ucred_getruid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_getrgid ucred_getrgid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_getsuid ucred_getsuid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_getsgid ucred_getsgid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_getpid ucred_getpid "libc.so"
|
||||
//go:cgo_import_dynamic libc_ucred_free ucred_free "libc.so"
|
||||
//go:cgo_import_dynamic libc_port_create port_create "libc.so"
|
||||
//go:cgo_import_dynamic libc_port_associate port_associate "libc.so"
|
||||
//go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so"
|
||||
|
|
@ -280,6 +290,16 @@ import (
|
|||
//go:linkname procgetpeername libc_getpeername
|
||||
//go:linkname procsetsockopt libc_setsockopt
|
||||
//go:linkname procrecvfrom libc_recvfrom
|
||||
//go:linkname procgetpeerucred libc_getpeerucred
|
||||
//go:linkname procucred_get libc_ucred_get
|
||||
//go:linkname procucred_geteuid libc_ucred_geteuid
|
||||
//go:linkname procucred_getegid libc_ucred_getegid
|
||||
//go:linkname procucred_getruid libc_ucred_getruid
|
||||
//go:linkname procucred_getrgid libc_ucred_getrgid
|
||||
//go:linkname procucred_getsuid libc_ucred_getsuid
|
||||
//go:linkname procucred_getsgid libc_ucred_getsgid
|
||||
//go:linkname procucred_getpid libc_ucred_getpid
|
||||
//go:linkname procucred_free libc_ucred_free
|
||||
//go:linkname procport_create libc_port_create
|
||||
//go:linkname procport_associate libc_port_associate
|
||||
//go:linkname procport_dissociate libc_port_dissociate
|
||||
|
|
@ -420,6 +440,16 @@ var (
|
|||
procgetpeername,
|
||||
procsetsockopt,
|
||||
procrecvfrom,
|
||||
procgetpeerucred,
|
||||
procucred_get,
|
||||
procucred_geteuid,
|
||||
procucred_getegid,
|
||||
procucred_getruid,
|
||||
procucred_getrgid,
|
||||
procucred_getsuid,
|
||||
procucred_getsgid,
|
||||
procucred_getpid,
|
||||
procucred_free,
|
||||
procport_create,
|
||||
procport_associate,
|
||||
procport_dissociate,
|
||||
|
|
@ -2029,6 +2059,90 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func getpeerucred(fd uintptr, ucred *uintptr) (err error) {
|
||||
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetpeerucred)), 2, uintptr(fd), uintptr(unsafe.Pointer(ucred)), 0, 0, 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGet(pid int) (ucred uintptr, err error) {
|
||||
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procucred_get)), 1, uintptr(pid), 0, 0, 0, 0, 0)
|
||||
ucred = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGeteuid(ucred uintptr) (uid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_geteuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGetegid(ucred uintptr) (gid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getegid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
gid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGetruid(ucred uintptr) (uid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getruid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGetrgid(ucred uintptr) (gid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getrgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
gid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGetsuid(ucred uintptr) (uid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGetsgid(ucred uintptr) (gid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
gid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredGetpid(ucred uintptr) (pid int) {
|
||||
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getpid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
pid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ucredFree(ucred uintptr) {
|
||||
sysvicall6(uintptr(unsafe.Pointer(&procucred_free)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func port_create() (n int, err error) {
|
||||
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0)
|
||||
n = int(r0)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
generated
vendored
|
|
@ -458,4 +458,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
generated
vendored
|
|
@ -381,4 +381,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
generated
vendored
|
|
@ -422,4 +422,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
generated
vendored
|
|
@ -325,4 +325,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
generated
vendored
|
|
@ -321,4 +321,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
generated
vendored
|
|
@ -442,4 +442,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 4460
|
||||
SYS_LSM_LIST_MODULES = 4461
|
||||
SYS_MSEAL = 4462
|
||||
SYS_SETXATTRAT = 4463
|
||||
SYS_GETXATTRAT = 4464
|
||||
SYS_LISTXATTRAT = 4465
|
||||
SYS_REMOVEXATTRAT = 4466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
generated
vendored
|
|
@ -372,4 +372,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 5460
|
||||
SYS_LSM_LIST_MODULES = 5461
|
||||
SYS_MSEAL = 5462
|
||||
SYS_SETXATTRAT = 5463
|
||||
SYS_GETXATTRAT = 5464
|
||||
SYS_LISTXATTRAT = 5465
|
||||
SYS_REMOVEXATTRAT = 5466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
generated
vendored
|
|
@ -372,4 +372,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 5460
|
||||
SYS_LSM_LIST_MODULES = 5461
|
||||
SYS_MSEAL = 5462
|
||||
SYS_SETXATTRAT = 5463
|
||||
SYS_GETXATTRAT = 5464
|
||||
SYS_LISTXATTRAT = 5465
|
||||
SYS_REMOVEXATTRAT = 5466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
generated
vendored
|
|
@ -442,4 +442,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 4460
|
||||
SYS_LSM_LIST_MODULES = 4461
|
||||
SYS_MSEAL = 4462
|
||||
SYS_SETXATTRAT = 4463
|
||||
SYS_GETXATTRAT = 4464
|
||||
SYS_LISTXATTRAT = 4465
|
||||
SYS_REMOVEXATTRAT = 4466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
generated
vendored
|
|
@ -449,4 +449,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
generated
vendored
|
|
@ -421,4 +421,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
generated
vendored
|
|
@ -421,4 +421,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
generated
vendored
|
|
@ -326,4 +326,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
generated
vendored
|
|
@ -387,4 +387,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
4
vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
generated
vendored
|
|
@ -400,4 +400,8 @@ const (
|
|||
SYS_LSM_SET_SELF_ATTR = 460
|
||||
SYS_LSM_LIST_MODULES = 461
|
||||
SYS_MSEAL = 462
|
||||
SYS_SETXATTRAT = 463
|
||||
SYS_GETXATTRAT = 464
|
||||
SYS_LISTXATTRAT = 465
|
||||
SYS_REMOVEXATTRAT = 466
|
||||
)
|
||||
|
|
|
|||
6
vendor/golang.org/x/sys/unix/ztypes_linux.go
generated
vendored
6
vendor/golang.org/x/sys/unix/ztypes_linux.go
generated
vendored
|
|
@ -4747,7 +4747,7 @@ const (
|
|||
NL80211_ATTR_MAC_HINT = 0xc8
|
||||
NL80211_ATTR_MAC_MASK = 0xd7
|
||||
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
|
||||
NL80211_ATTR_MAX = 0x14c
|
||||
NL80211_ATTR_MAX = 0x14d
|
||||
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
|
||||
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
|
||||
NL80211_ATTR_MAX_MATCH_SETS = 0x85
|
||||
|
|
@ -5519,7 +5519,7 @@ const (
|
|||
NL80211_MNTR_FLAG_CONTROL = 0x3
|
||||
NL80211_MNTR_FLAG_COOK_FRAMES = 0x5
|
||||
NL80211_MNTR_FLAG_FCSFAIL = 0x1
|
||||
NL80211_MNTR_FLAG_MAX = 0x6
|
||||
NL80211_MNTR_FLAG_MAX = 0x7
|
||||
NL80211_MNTR_FLAG_OTHER_BSS = 0x4
|
||||
NL80211_MNTR_FLAG_PLCPFAIL = 0x2
|
||||
NL80211_MPATH_FLAG_ACTIVE = 0x1
|
||||
|
|
@ -6174,3 +6174,5 @@ type SockDiagReq struct {
|
|||
Family uint8
|
||||
Protocol uint8
|
||||
}
|
||||
|
||||
const RTM_NEWNVLAN = 0x70
|
||||
|
|
|
|||
11
vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
11
vendor/golang.org/x/sys/windows/dll_windows.go
generated
vendored
|
|
@ -43,8 +43,8 @@ type DLL struct {
|
|||
// LoadDLL loads DLL file into memory.
|
||||
//
|
||||
// Warning: using LoadDLL without an absolute path name is subject to
|
||||
// DLL preloading attacks. To safely load a system DLL, use LazyDLL
|
||||
// with System set to true, or use LoadLibraryEx directly.
|
||||
// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL],
|
||||
// or use [LoadLibraryEx] directly.
|
||||
func LoadDLL(name string) (dll *DLL, err error) {
|
||||
namep, err := UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
|
|
@ -271,6 +271,9 @@ func (d *LazyDLL) NewProc(name string) *LazyProc {
|
|||
}
|
||||
|
||||
// NewLazyDLL creates new LazyDLL associated with DLL file.
|
||||
//
|
||||
// Warning: using NewLazyDLL without an absolute path name is subject to
|
||||
// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL].
|
||||
func NewLazyDLL(name string) *LazyDLL {
|
||||
return &LazyDLL{Name: name}
|
||||
}
|
||||
|
|
@ -410,7 +413,3 @@ func loadLibraryEx(name string, system bool) (*DLL, error) {
|
|||
}
|
||||
return &DLL{Name: name, Handle: h}, nil
|
||||
}
|
||||
|
||||
type errString string
|
||||
|
||||
func (s errString) Error() string { return string(s) }
|
||||
|
|
|
|||
53
vendor/maunium.net/go/mautrix/CHANGELOG.md
generated
vendored
53
vendor/maunium.net/go/mautrix/CHANGELOG.md
generated
vendored
|
|
@ -1,3 +1,56 @@
|
|||
## v0.23.1 (2025-02-16)
|
||||
|
||||
* *(client)* Added `FullStateEvent` method to get a state event including
|
||||
metadata (using the `?format=event` query parameter).
|
||||
* *(client)* Added wrapper method for [MSC4194]'s redact endpoint.
|
||||
* *(pushrules)* Fixed content rules not considering word boundaries and being
|
||||
case-sensitive.
|
||||
* *(crypto)* Fixed bugs that would cause key exports to fail for no reason.
|
||||
* *(crypto)* Deprecated `ResolveTrust` in favor of `ResolveTrustContext`.
|
||||
* *(crypto)* Stopped accepting secret shares from unverified devices.
|
||||
* **Breaking change *(crypto)*** Changed `GetAndVerifyLatestKeyBackupVersion`
|
||||
to take an optional private key parameter. The method will now trust the
|
||||
public key if it matches the provided private key even if there are no valid
|
||||
signatures.
|
||||
* **Breaking change *(crypto)*** Added context parameter to `IsDeviceTrusted`.
|
||||
|
||||
[MSC4194]: https://github.com/matrix-org/matrix-spec-proposals/pull/4194
|
||||
|
||||
## v0.23.0 (2025-01-16)
|
||||
|
||||
* **Breaking change *(client)*** Changed `JoinRoom` parameters to allow multiple
|
||||
`via`s.
|
||||
* **Breaking change *(bridgev2)*** Updated capability system.
|
||||
* The return type of `NetworkAPI.GetCapabilities` is now different.
|
||||
* Media type capabilities are enforced automatically by bridgev2.
|
||||
* Capabilities are now sent to Matrix rooms using the
|
||||
`com.beeper.room_features` state event.
|
||||
* *(client)* Added `GetRoomSummary` to implement [MSC3266].
|
||||
* *(client)* Added support for arbitrary profile fields to implement [MSC4133]
|
||||
(thanks to [@nexy7574] in [#337]).
|
||||
* *(crypto)* Started storing olm message hashes to prevent decryption errors
|
||||
if messages are repeated (e.g. if the app crashes right after decrypting).
|
||||
* *(crypto)* Improved olm session unwedging to check when the last session was
|
||||
created instead of only relying on an in-memory map.
|
||||
* *(crypto/verificationhelper)* Fixed emoji verification not doing cross-signing
|
||||
properly after a successful verification.
|
||||
* *(bridgev2/config)* Moved MSC4190 flag from `appservice` to `encryption`.
|
||||
* *(bridgev2/space)* Fixed failing to add rooms to spaces if the room create
|
||||
call was made with a temporary context.
|
||||
* *(bridgev2/commands)* Changed `help` command to hide commands which require
|
||||
interfaces that aren't implemented by the network connector.
|
||||
* *(bridgev2/matrixinterface)* Moved deterministic room ID generation to Matrix
|
||||
connector.
|
||||
* *(bridgev2)* Fixed service member state event not being set correctly when
|
||||
creating a DM by inviting a ghost user.
|
||||
* *(bridgev2)* Fixed `RemoteReactionSync` events replacing all reactions every
|
||||
time instead of only changed ones.
|
||||
|
||||
[MSC3266]: https://github.com/matrix-org/matrix-spec-proposals/pull/3266
|
||||
[MSC4133]: https://github.com/matrix-org/matrix-spec-proposals/pull/4133
|
||||
[@nexy7574]: https://github.com/nexy7574
|
||||
[#337]: https://github.com/mautrix/go/pull/337
|
||||
|
||||
## v0.22.1 (2024-12-16)
|
||||
|
||||
* *(crypto)* Added automatic cleanup when there are too many olm sessions with
|
||||
|
|
|
|||
125
vendor/maunium.net/go/mautrix/client.go
generated
vendored
125
vendor/maunium.net/go/mautrix/client.go
generated
vendored
|
|
@ -76,18 +76,19 @@ type VerificationHelper interface {
|
|||
|
||||
// Client represents a Matrix client.
|
||||
type Client struct {
|
||||
HomeserverURL *url.URL // The base homeserver URL
|
||||
UserID id.UserID // The user ID of the client. Used for forming HTTP paths which use the client's user ID.
|
||||
DeviceID id.DeviceID // The device ID of the client.
|
||||
AccessToken string // The access_token for the client.
|
||||
UserAgent string // The value for the User-Agent header
|
||||
Client *http.Client // The underlying HTTP client which will be used to make HTTP requests.
|
||||
Syncer Syncer // The thing which can process /sync responses
|
||||
Store SyncStore // The thing which can store tokens/ids
|
||||
StateStore StateStore
|
||||
Crypto CryptoHelper
|
||||
Verification VerificationHelper
|
||||
SpecVersions *RespVersions
|
||||
HomeserverURL *url.URL // The base homeserver URL
|
||||
UserID id.UserID // The user ID of the client. Used for forming HTTP paths which use the client's user ID.
|
||||
DeviceID id.DeviceID // The device ID of the client.
|
||||
AccessToken string // The access_token for the client.
|
||||
UserAgent string // The value for the User-Agent header
|
||||
Client *http.Client // The underlying HTTP client which will be used to make HTTP requests.
|
||||
Syncer Syncer // The thing which can process /sync responses
|
||||
Store SyncStore // The thing which can store tokens/ids
|
||||
StateStore StateStore
|
||||
Crypto CryptoHelper
|
||||
Verification VerificationHelper
|
||||
SpecVersions *RespVersions
|
||||
ExternalClient *http.Client // The HTTP client used for external (not matrix) media HTTP requests.
|
||||
|
||||
Log zerolog.Logger
|
||||
|
||||
|
|
@ -951,20 +952,19 @@ func (cli *Client) Capabilities(ctx context.Context) (resp *RespCapabilities, er
|
|||
return
|
||||
}
|
||||
|
||||
// JoinRoom joins the client to a room ID or alias. See https://spec.matrix.org/v1.2/client-server-api/#post_matrixclientv3joinroomidoralias
|
||||
// JoinRoom joins the client to a room ID or alias. See https://spec.matrix.org/v1.13/client-server-api/#post_matrixclientv3joinroomidoralias
|
||||
//
|
||||
// If serverName is specified, this will be added as a query param to instruct the homeserver to join via that server. If content is specified, it will
|
||||
// be JSON encoded and used as the request body.
|
||||
func (cli *Client) JoinRoom(ctx context.Context, roomIDorAlias, serverName string, content interface{}) (resp *RespJoinRoom, err error) {
|
||||
var urlPath string
|
||||
if serverName != "" {
|
||||
urlPath = cli.BuildURLWithQuery(ClientURLPath{"v3", "join", roomIDorAlias}, map[string]string{
|
||||
"via": serverName,
|
||||
})
|
||||
} else {
|
||||
urlPath = cli.BuildClientURL("v3", "join", roomIDorAlias)
|
||||
// The last parameter contains optional extra fields and can be left nil.
|
||||
func (cli *Client) JoinRoom(ctx context.Context, roomIDorAlias string, req *ReqJoinRoom) (resp *RespJoinRoom, err error) {
|
||||
if req == nil {
|
||||
req = &ReqJoinRoom{}
|
||||
}
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPost, urlPath, content, &resp)
|
||||
urlPath := cli.BuildURLWithFullQuery(ClientURLPath{"v3", "join", roomIDorAlias}, func(q url.Values) {
|
||||
if len(req.Via) > 0 {
|
||||
q["via"] = req.Via
|
||||
}
|
||||
})
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPost, urlPath, req, &resp)
|
||||
if err == nil && cli.StateStore != nil {
|
||||
err = cli.StateStore.SetMembership(ctx, resp.RoomID, cli.UserID, event.MembershipJoin)
|
||||
if err != nil {
|
||||
|
|
@ -1011,6 +1011,17 @@ func (cli *Client) GetMutualRooms(ctx context.Context, otherUserID id.UserID, ex
|
|||
return
|
||||
}
|
||||
|
||||
func (cli *Client) GetRoomSummary(ctx context.Context, roomIDOrAlias string, via ...string) (resp *RespRoomSummary, err error) {
|
||||
// TODO add version check after one is added to MSC3266
|
||||
urlPath := cli.BuildURLWithFullQuery(ClientURLPath{"unstable", "im.nheko.summary", "summary", roomIDOrAlias}, func(q url.Values) {
|
||||
if len(via) > 0 {
|
||||
q["via"] = via
|
||||
}
|
||||
})
|
||||
_, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp)
|
||||
return
|
||||
}
|
||||
|
||||
// GetDisplayName returns the display name of the user with the specified MXID. See https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3profileuseriddisplayname
|
||||
func (cli *Client) GetDisplayName(ctx context.Context, mxid id.UserID) (resp *RespUserDisplayName, err error) {
|
||||
urlPath := cli.BuildClientURL("v3", "profile", mxid, "displayname")
|
||||
|
|
@ -1033,6 +1044,22 @@ func (cli *Client) SetDisplayName(ctx context.Context, displayName string) (err
|
|||
return
|
||||
}
|
||||
|
||||
// UnstableSetProfileField sets an arbitrary MSC4133 profile field. See https://github.com/matrix-org/matrix-spec-proposals/pull/4133
|
||||
func (cli *Client) UnstableSetProfileField(ctx context.Context, key string, value any) (err error) {
|
||||
urlPath := cli.BuildClientURL("unstable", "uk.tcpip.msc4133", "profile", cli.UserID, key)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPut, urlPath, map[string]any{
|
||||
key: value,
|
||||
}, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// UnstableDeleteProfileField deletes an arbitrary MSC4133 profile field. See https://github.com/matrix-org/matrix-spec-proposals/pull/4133
|
||||
func (cli *Client) UnstableDeleteProfileField(ctx context.Context, key string) (err error) {
|
||||
urlPath := cli.BuildClientURL("unstable", "uk.tcpip.msc4133", "profile", cli.UserID, key)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodDelete, urlPath, nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAvatarURL gets the avatar URL of the user with the specified MXID. See https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3profileuseridavatar_url
|
||||
func (cli *Client) GetAvatarURL(ctx context.Context, mxid id.UserID) (url id.ContentURI, err error) {
|
||||
urlPath := cli.BuildClientURL("v3", "profile", mxid, "avatar_url")
|
||||
|
|
@ -1250,6 +1277,19 @@ func (cli *Client) RedactEvent(ctx context.Context, roomID id.RoomID, eventID id
|
|||
return
|
||||
}
|
||||
|
||||
func (cli *Client) UnstableRedactUserEvents(ctx context.Context, roomID id.RoomID, userID id.UserID, req *ReqRedactUser) (resp *RespRedactUserEvents, err error) {
|
||||
if req == nil {
|
||||
req = &ReqRedactUser{}
|
||||
}
|
||||
query := map[string]string{}
|
||||
if req.Limit > 0 {
|
||||
query["limit"] = strconv.Itoa(req.Limit)
|
||||
}
|
||||
urlPath := cli.BuildURLWithQuery(ClientURLPath{"unstable", "org.matrix.msc4194", "rooms", roomID, "redact", "user", userID}, query)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPost, urlPath, req, &resp)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateRoom creates a new Matrix room. See https://spec.matrix.org/v1.2/client-server-api/#post_matrixclientv3createroom
|
||||
//
|
||||
// resp, err := cli.CreateRoom(&mautrix.ReqCreateRoom{
|
||||
|
|
@ -1394,10 +1434,9 @@ func (cli *Client) GetOwnPresence(ctx context.Context) (resp *RespPresence, err
|
|||
return cli.GetPresence(ctx, cli.UserID)
|
||||
}
|
||||
|
||||
func (cli *Client) SetPresence(ctx context.Context, status event.Presence) (err error) {
|
||||
req := ReqPresence{Presence: status}
|
||||
func (cli *Client) SetPresence(ctx context.Context, presence ReqPresence) (err error) {
|
||||
u := cli.BuildClientURL("v3", "presence", cli.UserID, "status")
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPut, u, req, nil)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPut, u, presence, nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -1434,8 +1473,8 @@ func (cli *Client) updateStoreWithOutgoingEvent(ctx context.Context, roomID id.R
|
|||
UpdateStateStore(ctx, cli.StateStore, fakeEvt)
|
||||
}
|
||||
|
||||
// StateEvent gets a single state event in a room. It will attempt to JSON unmarshal into the given "outContent" struct with
|
||||
// the HTTP response body, or return an error.
|
||||
// StateEvent gets the content of a single state event in a room.
|
||||
// It will attempt to JSON unmarshal into the given "outContent" struct with the HTTP response body, or return an error.
|
||||
// See https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3roomsroomidstateeventtypestatekey
|
||||
func (cli *Client) StateEvent(ctx context.Context, roomID id.RoomID, eventType event.Type, stateKey string, outContent interface{}) (err error) {
|
||||
u := cli.BuildClientURL("v3", "rooms", roomID, "state", eventType.String(), stateKey)
|
||||
|
|
@ -1446,6 +1485,23 @@ func (cli *Client) StateEvent(ctx context.Context, roomID id.RoomID, eventType e
|
|||
return
|
||||
}
|
||||
|
||||
// FullStateEvent gets a single state event in a room. Unlike [StateEvent], this gets the entire event
|
||||
// (including details like the sender and timestamp).
|
||||
// This requires the server to support the ?format=event query parameter, which is currently missing from the spec.
|
||||
// See https://github.com/matrix-org/matrix-spec/issues/1047 for more info
|
||||
func (cli *Client) FullStateEvent(ctx context.Context, roomID id.RoomID, eventType event.Type, stateKey string) (evt *event.Event, err error) {
|
||||
u := cli.BuildURLWithQuery(ClientURLPath{"v3", "rooms", roomID, "state", eventType.String(), stateKey}, map[string]string{
|
||||
"format": "event",
|
||||
})
|
||||
_, err = cli.MakeRequest(ctx, http.MethodGet, u, nil, &evt)
|
||||
if err == nil && cli.StateStore != nil {
|
||||
UpdateStateStore(ctx, cli.StateStore, evt)
|
||||
}
|
||||
evt.Type.Class = event.StateEventType
|
||||
_ = evt.Content.ParseRaw(evt.Type)
|
||||
return
|
||||
}
|
||||
|
||||
// parseRoomStateArray parses a JSON array as a stream and stores the events inside it in a room state map.
|
||||
func parseRoomStateArray(_ *http.Request, res *http.Response, responseJSON interface{}) ([]byte, error) {
|
||||
response := make(RoomStateMap)
|
||||
|
|
@ -1531,6 +1587,11 @@ func (cli *Client) GetMediaConfig(ctx context.Context) (resp *RespMediaConfig, e
|
|||
return
|
||||
}
|
||||
|
||||
func (cli *Client) RequestOpenIDToken(ctx context.Context) (resp *RespOpenIDToken, err error) {
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPost, cli.BuildClientURL("v3", "user", cli.UserID, "openid", "request_token"), nil, &resp)
|
||||
return
|
||||
}
|
||||
|
||||
// UploadLink uploads an HTTP URL and then returns an MXC URI.
|
||||
func (cli *Client) UploadLink(ctx context.Context, link string) (*RespMediaUpload, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, link, nil)
|
||||
|
|
@ -1663,7 +1724,11 @@ func (cli *Client) tryUploadMediaToURL(ctx context.Context, url, contentType str
|
|||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Set("User-Agent", cli.UserAgent+" (external media uploader)")
|
||||
|
||||
return http.DefaultClient.Do(req)
|
||||
if cli.ExternalClient != nil {
|
||||
return cli.ExternalClient.Do(req)
|
||||
} else {
|
||||
return http.DefaultClient.Do(req)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) uploadMediaToURL(ctx context.Context, data ReqUploadMedia) (*RespMediaUpload, error) {
|
||||
|
|
|
|||
11
vendor/maunium.net/go/mautrix/crypto/cross_sign_validation.go
generated
vendored
11
vendor/maunium.net/go/mautrix/crypto/cross_sign_validation.go
generated
vendored
|
|
@ -13,6 +13,9 @@ import (
|
|||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// ResolveTrust resolves the trust state of the device from cross-signing.
|
||||
//
|
||||
// Deprecated: This method doesn't take a context. Use [OlmMachine.ResolveTrustContext] instead.
|
||||
func (mach *OlmMachine) ResolveTrust(device *id.Device) id.TrustState {
|
||||
state, _ := mach.ResolveTrustContext(context.Background(), device)
|
||||
return state
|
||||
|
|
@ -77,8 +80,12 @@ func (mach *OlmMachine) ResolveTrustContext(ctx context.Context, device *id.Devi
|
|||
}
|
||||
|
||||
// IsDeviceTrusted returns whether a device has been determined to be trusted either through verification or cross-signing.
|
||||
func (mach *OlmMachine) IsDeviceTrusted(device *id.Device) bool {
|
||||
switch mach.ResolveTrust(device) {
|
||||
//
|
||||
// Note: this will return false if resolving the trust state fails due to database errors.
|
||||
// Use [OlmMachine.ResolveTrustContext] if special error handling is required.
|
||||
func (mach *OlmMachine) IsDeviceTrusted(ctx context.Context, device *id.Device) bool {
|
||||
trust, _ := mach.ResolveTrustContext(ctx, device)
|
||||
switch trust {
|
||||
case id.TrustStateVerified, id.TrustStateCrossSignedTOFU, id.TrustStateCrossSignedVerified:
|
||||
return true
|
||||
default:
|
||||
|
|
|
|||
10
vendor/maunium.net/go/mautrix/crypto/cryptohelper/cryptohelper.go
generated
vendored
10
vendor/maunium.net/go/mautrix/crypto/cryptohelper/cryptohelper.go
generated
vendored
|
|
@ -36,6 +36,7 @@ type CryptoHelper struct {
|
|||
|
||||
DecryptErrorCallback func(*event.Event, error)
|
||||
|
||||
MSC4190 bool
|
||||
LoginAs *mautrix.ReqLogin
|
||||
|
||||
ASEventProcessor crypto.ASEventProcessor
|
||||
|
|
@ -151,7 +152,14 @@ func (helper *CryptoHelper) Init(ctx context.Context) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to find existing device ID: %w", err)
|
||||
}
|
||||
if helper.LoginAs != nil && helper.LoginAs.Type == mautrix.AuthTypeAppservice && helper.client.SetAppServiceDeviceID {
|
||||
if helper.MSC4190 {
|
||||
helper.log.Debug().Msg("Creating bot device with MSC4190")
|
||||
err = helper.client.CreateDeviceMSC4190(ctx, storedDeviceID, helper.LoginAs.InitialDeviceDisplayName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create device for bot: %w", err)
|
||||
}
|
||||
rawCryptoStore.DeviceID = helper.client.DeviceID
|
||||
} else if helper.LoginAs != nil && helper.LoginAs.Type == mautrix.AuthTypeAppservice && helper.client.SetAppServiceDeviceID {
|
||||
if storedDeviceID == "" {
|
||||
helper.log.Debug().
|
||||
Str("username", helper.LoginAs.Identifier.User).
|
||||
|
|
|
|||
58
vendor/maunium.net/go/mautrix/crypto/decryptolm.go
generated
vendored
58
vendor/maunium.net/go/mautrix/crypto/decryptolm.go
generated
vendored
|
|
@ -8,6 +8,8 @@ package crypto
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -29,6 +31,7 @@ var (
|
|||
SenderMismatch = errors.New("mismatched sender in olm payload")
|
||||
RecipientMismatch = errors.New("mismatched recipient in olm payload")
|
||||
RecipientKeyMismatch = errors.New("mismatched recipient key in olm payload")
|
||||
ErrDuplicateMessage = errors.New("duplicate olm message")
|
||||
)
|
||||
|
||||
// DecryptedOlmEvent represents an event that was decrypted from an event encrypted with the m.olm.v1.curve25519-aes-sha2 algorithm.
|
||||
|
|
@ -113,14 +116,35 @@ func (mach *OlmMachine) decryptAndParseOlmCiphertext(ctx context.Context, evt *e
|
|||
return &olmEvt, nil
|
||||
}
|
||||
|
||||
func olmMessageHash(ciphertext string) ([32]byte, error) {
|
||||
ciphertextBytes, err := base64.RawStdEncoding.DecodeString(ciphertext)
|
||||
return sha256.Sum256(ciphertextBytes), err
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) tryDecryptOlmCiphertext(ctx context.Context, sender id.UserID, senderKey id.SenderKey, olmType id.OlmMsgType, ciphertext string) ([]byte, error) {
|
||||
ciphertextHash, err := olmMessageHash(ciphertext)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to hash olm ciphertext: %w", err)
|
||||
}
|
||||
|
||||
log := *zerolog.Ctx(ctx)
|
||||
endTimeTrace := mach.timeTrace(ctx, "waiting for olm lock", 5*time.Second)
|
||||
mach.olmLock.Lock()
|
||||
endTimeTrace()
|
||||
defer mach.olmLock.Unlock()
|
||||
|
||||
plaintext, err := mach.tryDecryptOlmCiphertextWithExistingSession(ctx, senderKey, olmType, ciphertext)
|
||||
duplicateTS, err := mach.CryptoStore.GetOlmHash(ctx, ciphertextHash)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to check for duplicate olm message")
|
||||
} else if !duplicateTS.IsZero() {
|
||||
log.Warn().
|
||||
Hex("ciphertext_hash", ciphertextHash[:]).
|
||||
Time("duplicate_ts", duplicateTS).
|
||||
Msg("Ignoring duplicate olm message")
|
||||
return nil, ErrDuplicateMessage
|
||||
}
|
||||
|
||||
plaintext, err := mach.tryDecryptOlmCiphertextWithExistingSession(ctx, senderKey, olmType, ciphertext, ciphertextHash)
|
||||
if err != nil {
|
||||
if err == DecryptionFailedWithMatchingSession {
|
||||
log.Warn().Msg("Found matching session, but decryption failed")
|
||||
|
|
@ -153,6 +177,7 @@ func (mach *OlmMachine) tryDecryptOlmCiphertext(ctx context.Context, sender id.U
|
|||
}
|
||||
log = log.With().Str("new_olm_session_id", session.ID().String()).Logger()
|
||||
log.Debug().
|
||||
Hex("ciphertext_hash", ciphertextHash[:]).
|
||||
Str("olm_session_description", session.Describe()).
|
||||
Msg("Created inbound olm session")
|
||||
ctx = log.WithContext(ctx)
|
||||
|
|
@ -166,6 +191,10 @@ func (mach *OlmMachine) tryDecryptOlmCiphertext(ctx context.Context, sender id.U
|
|||
}
|
||||
|
||||
endTimeTrace = mach.timeTrace(ctx, "updating new session in database", time.Second)
|
||||
err = mach.CryptoStore.PutOlmHash(ctx, ciphertextHash, time.Now())
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to store olm message hash after decrypting")
|
||||
}
|
||||
err = mach.CryptoStore.UpdateSession(ctx, senderKey, session)
|
||||
endTimeTrace()
|
||||
if err != nil {
|
||||
|
|
@ -176,7 +205,9 @@ func (mach *OlmMachine) tryDecryptOlmCiphertext(ctx context.Context, sender id.U
|
|||
|
||||
const MaxOlmSessionsPerDevice = 5
|
||||
|
||||
func (mach *OlmMachine) tryDecryptOlmCiphertextWithExistingSession(ctx context.Context, senderKey id.SenderKey, olmType id.OlmMsgType, ciphertext string) ([]byte, error) {
|
||||
func (mach *OlmMachine) tryDecryptOlmCiphertextWithExistingSession(
|
||||
ctx context.Context, senderKey id.SenderKey, olmType id.OlmMsgType, ciphertext string, ciphertextHash [32]byte,
|
||||
) ([]byte, error) {
|
||||
log := *zerolog.Ctx(ctx)
|
||||
endTimeTrace := mach.timeTrace(ctx, "getting sessions with sender key", time.Second)
|
||||
sessions, err := mach.CryptoStore.GetSessions(ctx, senderKey)
|
||||
|
|
@ -229,6 +260,7 @@ func (mach *OlmMachine) tryDecryptOlmCiphertextWithExistingSession(ctx context.C
|
|||
endTimeTrace()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).
|
||||
Hex("ciphertext_hash", ciphertextHash[:]).
|
||||
Str("session_description", session.Describe()).
|
||||
Msg("Failed to decrypt olm message")
|
||||
if olmType == id.OlmMsgTypePreKey {
|
||||
|
|
@ -236,12 +268,19 @@ func (mach *OlmMachine) tryDecryptOlmCiphertextWithExistingSession(ctx context.C
|
|||
}
|
||||
} else {
|
||||
endTimeTrace = mach.timeTrace(ctx, "updating session in database", time.Second)
|
||||
err = mach.CryptoStore.PutOlmHash(ctx, ciphertextHash, time.Now())
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to store olm message hash after decrypting")
|
||||
}
|
||||
err = mach.CryptoStore.UpdateSession(ctx, senderKey, session)
|
||||
endTimeTrace()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to update olm session in crypto store after decrypting")
|
||||
}
|
||||
log.Debug().Str("session_description", session.Describe()).Msg("Decrypted olm message")
|
||||
log.Debug().
|
||||
Hex("ciphertext_hash", ciphertextHash[:]).
|
||||
Str("session_description", session.Describe()).
|
||||
Msg("Decrypted olm message")
|
||||
return plaintext, nil
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +304,7 @@ const MinUnwedgeInterval = 1 * time.Hour
|
|||
|
||||
func (mach *OlmMachine) unwedgeDevice(log zerolog.Logger, sender id.UserID, senderKey id.SenderKey) {
|
||||
log = log.With().Str("action", "unwedge olm session").Logger()
|
||||
ctx := log.WithContext(context.TODO())
|
||||
ctx := log.WithContext(mach.BackgroundCtx)
|
||||
mach.recentlyUnwedgedLock.Lock()
|
||||
prevUnwedge, ok := mach.recentlyUnwedged[senderKey]
|
||||
delta := time.Now().Sub(prevUnwedge)
|
||||
|
|
@ -279,6 +318,17 @@ func (mach *OlmMachine) unwedgeDevice(log zerolog.Logger, sender id.UserID, send
|
|||
mach.recentlyUnwedged[senderKey] = time.Now()
|
||||
mach.recentlyUnwedgedLock.Unlock()
|
||||
|
||||
lastCreatedAt, err := mach.CryptoStore.GetNewestSessionCreationTS(ctx, senderKey)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to get newest session creation timestamp")
|
||||
return
|
||||
} else if time.Since(lastCreatedAt) < MinUnwedgeInterval {
|
||||
log.Debug().
|
||||
Time("last_created_at", lastCreatedAt).
|
||||
Msg("Not creating new Olm session as it was already recreated recently")
|
||||
return
|
||||
}
|
||||
|
||||
deviceIdentity, err := mach.GetOrFetchDeviceByKey(ctx, sender, senderKey)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to find device info by identity key")
|
||||
|
|
|
|||
2
vendor/maunium.net/go/mautrix/crypto/encryptmegolm.go
generated
vendored
2
vendor/maunium.net/go/mautrix/crypto/encryptmegolm.go
generated
vendored
|
|
@ -417,7 +417,7 @@ func (mach *OlmMachine) findOlmSessionsForUser(ctx context.Context, session *Out
|
|||
Reason: "Device is blacklisted",
|
||||
}}
|
||||
session.Users[userKey] = OGSIgnored
|
||||
} else if trustState := mach.ResolveTrust(device); trustState < mach.SendKeysMinTrust {
|
||||
} else if trustState, _ := mach.ResolveTrustContext(ctx, device); trustState < mach.SendKeysMinTrust {
|
||||
log.Debug().
|
||||
Str("min_trust", mach.SendKeysMinTrust.String()).
|
||||
Str("device_trust", trustState.String()).
|
||||
|
|
|
|||
10
vendor/maunium.net/go/mautrix/crypto/goolm/account/account.go
generated
vendored
10
vendor/maunium.net/go/mautrix/crypto/goolm/account/account.go
generated
vendored
|
|
@ -8,11 +8,9 @@ import (
|
|||
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/goolm/cipher"
|
||||
"maunium.net/go/mautrix/crypto/goolm/crypto"
|
||||
"maunium.net/go/mautrix/crypto/goolm/libolmpickle"
|
||||
"maunium.net/go/mautrix/crypto/goolm/session"
|
||||
"maunium.net/go/mautrix/crypto/goolm/utilities"
|
||||
"maunium.net/go/mautrix/crypto/olm"
|
||||
)
|
||||
|
||||
|
|
@ -76,12 +74,12 @@ func NewAccount() (*Account, error) {
|
|||
|
||||
// PickleAsJSON returns an Account as a base64 string encrypted using the supplied key. The unencrypted representation of the Account is in JSON format.
|
||||
func (a *Account) PickleAsJSON(key []byte) ([]byte, error) {
|
||||
return utilities.PickleAsJSON(a, accountPickleVersionJSON, key)
|
||||
return libolmpickle.PickleAsJSON(a, accountPickleVersionJSON, key)
|
||||
}
|
||||
|
||||
// UnpickleAsJSON updates an Account by a base64 encrypted string using the supplied key. The unencrypted representation has to be in JSON format.
|
||||
func (a *Account) UnpickleAsJSON(pickled, key []byte) error {
|
||||
return utilities.UnpickleAsJSON(a, pickled, key, accountPickleVersionJSON)
|
||||
return libolmpickle.UnpickleAsJSON(a, pickled, key, accountPickleVersionJSON)
|
||||
}
|
||||
|
||||
// IdentityKeysJSON returns the public parts of the identity keys for the Account in a JSON string.
|
||||
|
|
@ -322,7 +320,7 @@ func (a *Account) ForgetOldFallbackKey() {
|
|||
// Unpickle decodes the base64 encoded string and decrypts the result with the key.
|
||||
// The decrypted value is then passed to UnpickleLibOlm.
|
||||
func (a *Account) Unpickle(pickled, key []byte) error {
|
||||
decrypted, err := cipher.Unpickle(key, pickled)
|
||||
decrypted, err := libolmpickle.Unpickle(key, pickled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -410,7 +408,7 @@ func (a *Account) Pickle(key []byte) ([]byte, error) {
|
|||
if len(key) == 0 {
|
||||
return nil, olm.ErrNoKeyProvided
|
||||
}
|
||||
return cipher.Pickle(key, a.PickleLibOlm())
|
||||
return libolmpickle.Pickle(key, a.PickleLibOlm())
|
||||
}
|
||||
|
||||
// PickleLibOlm pickles the [Account] and returns the raw bytes.
|
||||
|
|
|
|||
59
vendor/maunium.net/go/mautrix/crypto/goolm/aessha2/aessha2.go
generated
vendored
Normal file
59
vendor/maunium.net/go/mautrix/crypto/goolm/aessha2/aessha2.go
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2024 Sumner Evans
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// Package aessha2 implements the m.megolm.v1.aes-sha2 encryption algorithm
|
||||
// described in [Section 10.12.4.3] in the Spec
|
||||
//
|
||||
// [Section 10.12.4.3]: https://spec.matrix.org/v1.12/client-server-api/#mmegolmv1aes-sha2
|
||||
package aessha2
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/hkdf"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/aescbc"
|
||||
)
|
||||
|
||||
type AESSHA2 struct {
|
||||
aesKey, hmacKey, iv []byte
|
||||
}
|
||||
|
||||
func NewAESSHA2(secret, info []byte) (AESSHA2, error) {
|
||||
kdf := hkdf.New(sha256.New, secret, nil, info)
|
||||
keymatter := make([]byte, 80)
|
||||
_, err := io.ReadFull(kdf, keymatter)
|
||||
return AESSHA2{
|
||||
keymatter[:32], // AES Key
|
||||
keymatter[32:64], // HMAC Key
|
||||
keymatter[64:], // IV
|
||||
}, err
|
||||
}
|
||||
|
||||
func (a *AESSHA2) Encrypt(plaintext []byte) ([]byte, error) {
|
||||
return aescbc.Encrypt(a.aesKey, a.iv, plaintext)
|
||||
}
|
||||
|
||||
func (a *AESSHA2) Decrypt(ciphertext []byte) ([]byte, error) {
|
||||
return aescbc.Decrypt(a.aesKey, a.iv, ciphertext)
|
||||
}
|
||||
|
||||
func (a *AESSHA2) MAC(ciphertext []byte) ([]byte, error) {
|
||||
hash := hmac.New(sha256.New, a.hmacKey)
|
||||
_, err := hash.Write(ciphertext)
|
||||
return hash.Sum(nil), err
|
||||
}
|
||||
|
||||
func (a *AESSHA2) VerifyMAC(ciphertext, theirMAC []byte) (bool, error) {
|
||||
if mac, err := a.MAC(ciphertext); err != nil {
|
||||
return false, err
|
||||
} else {
|
||||
return subtle.ConstantTimeCompare(mac[:len(theirMAC)], theirMAC) == 1, nil
|
||||
}
|
||||
}
|
||||
81
vendor/maunium.net/go/mautrix/crypto/goolm/cipher/aes_sha256.go
generated
vendored
81
vendor/maunium.net/go/mautrix/crypto/goolm/cipher/aes_sha256.go
generated
vendored
|
|
@ -1,81 +0,0 @@
|
|||
package cipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/hkdf"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/aescbc"
|
||||
)
|
||||
|
||||
// derivedAESKeys stores the derived keys for the AESSHA256 cipher
|
||||
type derivedAESKeys struct {
|
||||
key []byte
|
||||
hmacKey []byte
|
||||
iv []byte
|
||||
}
|
||||
|
||||
// deriveAESKeys derives three keys for the AESSHA256 cipher
|
||||
func deriveAESKeys(kdfInfo []byte, key []byte) (derivedAESKeys, error) {
|
||||
kdf := hkdf.New(sha256.New, key, nil, kdfInfo)
|
||||
keymatter := make([]byte, 80)
|
||||
_, err := io.ReadFull(kdf, keymatter)
|
||||
return derivedAESKeys{
|
||||
key: keymatter[:32],
|
||||
hmacKey: keymatter[32:64],
|
||||
iv: keymatter[64:],
|
||||
}, err
|
||||
}
|
||||
|
||||
// AESSHA256 is a valid cipher using AES with CBC and HKDFSha256.
|
||||
type AESSHA256 struct {
|
||||
kdfInfo []byte
|
||||
}
|
||||
|
||||
// NewAESSHA256 returns a new AESSHA256 cipher with the key derive function info (kdfInfo).
|
||||
func NewAESSHA256(kdfInfo []byte) *AESSHA256 {
|
||||
return &AESSHA256{
|
||||
kdfInfo: kdfInfo,
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt encrypts the plaintext with the key. The key is used to derive the actual encryption key (32 bytes) as well as the iv (16 bytes).
|
||||
func (c AESSHA256) Encrypt(key, plaintext []byte) (ciphertext []byte, err error) {
|
||||
keys, err := deriveAESKeys(c.kdfInfo, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return aescbc.Encrypt(keys.key, keys.iv, plaintext)
|
||||
}
|
||||
|
||||
// Decrypt decrypts the ciphertext with the key. The key is used to derive the actual encryption key (32 bytes) as well as the iv (16 bytes).
|
||||
func (c AESSHA256) Decrypt(key, ciphertext []byte) (plaintext []byte, err error) {
|
||||
keys, err := deriveAESKeys(c.kdfInfo, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return aescbc.Decrypt(keys.key, keys.iv, ciphertext)
|
||||
}
|
||||
|
||||
// MAC returns the MAC for the message using the key. The key is used to derive the actual mac key (32 bytes).
|
||||
func (c AESSHA256) MAC(key, message []byte) ([]byte, error) {
|
||||
keys, err := deriveAESKeys(c.kdfInfo, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash := hmac.New(sha256.New, keys.hmacKey)
|
||||
_, err = hash.Write(message)
|
||||
return hash.Sum(nil), err
|
||||
}
|
||||
|
||||
// Verify checks the MAC of the message using the key against the givenMAC. The key is used to derive the actual mac key (32 bytes).
|
||||
func (c AESSHA256) Verify(key, message, givenMAC []byte) (bool, error) {
|
||||
mac, err := c.MAC(key, message)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return bytes.Equal(givenMAC, mac[:len(givenMAC)]), nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue