diff --git a/go.mod b/go.mod
index 4f0e75e0b56..7881a904026 100644
--- a/go.mod
+++ b/go.mod
@@ -4,35 +4,35 @@ go 1.22.7
require (
github.com/ahmetb/gen-crd-api-reference-docs v0.3.1-0.20210420163308-c1402a70e2f1
- github.com/cloudevents/conformance v0.2.0
+ github.com/cloudevents/conformance v0.4.1
github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.15.2
github.com/cloudevents/sdk-go/protocol/mqtt_paho/v2 v2.0.0-20240508060731-1ed9471c98bd
- github.com/cloudevents/sdk-go/sql/v2 v2.0.0-20240712172937-3ce6b2f1f011
+ github.com/cloudevents/sdk-go/sql/v2 v2.15.2
github.com/cloudevents/sdk-go/v2 v2.15.2
- github.com/coreos/go-oidc/v3 v3.9.0
- github.com/eclipse/paho.golang v0.12.0
+ github.com/coreos/go-oidc/v3 v3.12.0
+ github.com/eclipse/paho.golang v0.22.0
github.com/go-jose/go-jose/v3 v3.0.3
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.6.0
- github.com/gorilla/websocket v1.5.1
+ github.com/gorilla/websocket v1.5.3
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/hashicorp/golang-lru v1.0.2
github.com/kelseyhightower/envconfig v1.4.0
github.com/mitchellh/go-homedir v1.1.0
github.com/openzipkin/zipkin-go v0.4.3
- github.com/pelletier/go-toml/v2 v2.0.5
+ github.com/pelletier/go-toml/v2 v2.2.3
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/pkg/errors v0.9.1
- github.com/rickb777/date v1.13.0
+ github.com/rickb777/date v1.21.1
github.com/robfig/cron/v3 v3.0.1
- github.com/stretchr/testify v1.9.0
+ github.com/stretchr/testify v1.10.0
github.com/wavesoftware/go-ensure v1.0.0
go.opencensus.io v0.24.0
- go.opentelemetry.io/otel v1.31.0
- go.opentelemetry.io/otel/trace v1.31.0
- go.uber.org/atomic v1.10.0
+ go.opentelemetry.io/otel v1.34.0
+ go.opentelemetry.io/otel/trace v1.34.0
+ go.uber.org/atomic v1.11.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.34.0
@@ -64,6 +64,7 @@ require (
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
+ github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
@@ -90,7 +91,8 @@ require (
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/statsd_exporter v0.22.7 // indirect
- github.com/rickb777/plural v1.2.1 // indirect
+ github.com/rickb777/plural v1.4.2 // indirect
+ github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
diff --git a/go.sum b/go.sum
index cb22c007f88..5146ee404c4 100644
--- a/go.sum
+++ b/go.sum
@@ -13,6 +13,20 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
+cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
+cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
+cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
+cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
+cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
+cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
+cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
+cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
+cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
+cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
+cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -21,6 +35,7 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -39,6 +54,8 @@ contrib.go.opencensus.io/exporter/zipkin v0.1.2/go.mod h1:mP5xM3rrgOjpn79MM8fZbj
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/ahmetb/gen-crd-api-reference-docs v0.3.1-0.20210420163308-c1402a70e2f1 h1:mh2wBXE8rRSJkYz87b9YBTOOTzLUex1kuV+ar4r2j1c=
@@ -52,18 +69,25 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
-github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE=
github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -71,24 +95,34 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
+github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudevents/conformance v0.2.0 h1:NvSXOKlagcsOWMEbi8U7Ex/0oQ4JZE1HQ45bnxYf2zk=
-github.com/cloudevents/conformance v0.2.0/go.mod h1:rHKDwylBH89Rns6U3wL9ww8bg9/4GbwRCDNuyoC6bcc=
+github.com/cloudevents/conformance v0.4.1 h1:MMq+jviOHHNINGWQdvr2yj4g8CdeL59M81ODjEs9M20=
+github.com/cloudevents/conformance v0.4.1/go.mod h1:bOMTKxs/Aqx4rM/dp+AYvdGTHU6tEa9+R5ORr5cJnqc=
github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.15.2 h1:AbtPqiUDzKup5JpTZzO297/QXgL/TAdpdXQCNwLzlaM=
github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.15.2/go.mod h1:ZbYLE+yaEQ2j4vbRc9qzvGmg30A9LhwFt/1bSebNnbU=
github.com/cloudevents/sdk-go/protocol/mqtt_paho/v2 v2.0.0-20240508060731-1ed9471c98bd h1:MGVlnkCz/b0vjfkM5tSVLD+4oaUnYuVEjiW6lAMJ9IM=
github.com/cloudevents/sdk-go/protocol/mqtt_paho/v2 v2.0.0-20240508060731-1ed9471c98bd/go.mod h1:s+KZsVZst0bVW6vuKYb8CH49CcSJDO09+ZiIeKzJmqE=
-github.com/cloudevents/sdk-go/sql/v2 v2.0.0-20240712172937-3ce6b2f1f011 h1:mx6avAROtrV9yTlBBH4Y8IAmspmcz9v44Pkcrjq0tAA=
-github.com/cloudevents/sdk-go/sql/v2 v2.0.0-20240712172937-3ce6b2f1f011/go.mod h1:oqJ9+L9IXySYb8PN6M/g/K8y/WdVQunmmZhJnlLFcCk=
+github.com/cloudevents/sdk-go/sql/v2 v2.15.2 h1:TNaTeWIbDaci89xgXbmmNVGccawQOvEfWYLWrr7Fk/k=
+github.com/cloudevents/sdk-go/sql/v2 v2.15.2/go.mod h1:us+PSk8OXdk8pDbRfvxy5w8ub5goKE7UP9PjKDY7TPw=
github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc=
github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
-github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo=
-github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
+github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -97,22 +131,33 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
-github.com/eclipse/paho.golang v0.12.0 h1:EXQFJbJklDnUqW6lyAknMWRhM2NgpHxwrrL8riUmp3Q=
-github.com/eclipse/paho.golang v0.12.0/go.mod h1:TSDCUivu9JnoR9Hl+H7sQMcHkejWH2/xKK1NJGtLbIE=
+github.com/eclipse/paho.golang v0.22.0 h1:JhhUngr8TBlyUZDZw/L6WVayPi9qmSmdWeki48i5AVE=
+github.com/eclipse/paho.golang v0.22.0/go.mod h1:9ZiYJ93iEfGRJri8tErNeStPKLXIGBHiqbHV74t5pqI=
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -121,6 +166,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
+github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
+github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@@ -150,6 +197,7 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4=
github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -168,6 +216,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -183,10 +233,12 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
@@ -198,9 +250,12 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
@@ -211,6 +266,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -218,6 +275,13 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
@@ -226,26 +290,57 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
+github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
-github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 h1:CWyXh/jylQWp2dtiV33mY4iSSp6yf4lmn+c7/tN+ObI=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0/go.mod h1:nCLIt0w3Ept2NwF8ThLmrppXsfT07oC8k0XNDxd8sVU=
+github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
+github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
+github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
+github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
+github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
+github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
+github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
+github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
+github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
@@ -255,6 +350,7 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -269,6 +365,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -278,21 +375,40 @@ 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=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac h1:+2b6iGRJe3hvV/yVXrd41yVEjxuFHxasJqDhkIjS4gk=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M=
+github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
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.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
+github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
+github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
+github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -304,24 +420,22 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
-github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
-github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
+github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
@@ -330,13 +444,17 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
@@ -351,6 +469,7 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
@@ -360,6 +479,7 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
@@ -369,35 +489,37 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0=
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rickb777/date v1.13.0 h1:+8AmwLuY1d/rldzdqvqTEg7107bZ8clW37x4nsdG3Hs=
-github.com/rickb777/date v1.13.0/go.mod h1:GZf3LoGnxPWjX+/1TXOuzHefZFDovTyNLHDMd3qH70k=
-github.com/rickb777/plural v1.2.1 h1:UitRAgR70+yHFt26Tmj/F9dU9aV6UfjGXSbO1DcC9/U=
-github.com/rickb777/plural v1.2.1/go.mod h1:j058+3M5QQFgcZZ2oKIOekcygoZUL8gKW5yRO14BuAw=
+github.com/rickb777/date v1.21.1 h1:tUcQS8riIRoYK5kUAv5aevllFEYUEk2x8OYDyoldOn4=
+github.com/rickb777/date v1.21.1/go.mod h1:gnDexsbXViZr2fCKMrY3m6IfAF5U2vSkEaiGJcNFaLQ=
+github.com/rickb777/plural v1.4.2 h1:Kl/syFGLFZ5EbuV8c9SVud8s5HI2HpCCtOMw2U1kS+A=
+github.com/rickb777/plural v1.4.2/go.mod h1:kdmXUpmKBJTS0FtG/TFumd//VBWsNTD7zOw7x4umxNw=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
-github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
-github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
+github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A=
+github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -406,65 +528,80 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/wavesoftware/go-ensure v1.0.0 h1:6X3gQL5psBWwtu/H9a+69xQ+JGTUELaLhgOB/iB3AQk=
github.com/wavesoftware/go-ensure v1.0.0/go.mod h1:K2UAFSwMTvpiRGay/M3aEYYuurcR8S4A6HkQlJPV8k4=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
-github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
+go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
-go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
-go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
-go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
+go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
+go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
-go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
-go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
+go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
-go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
@@ -493,6 +630,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -501,6 +640,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
@@ -508,6 +651,7 @@ golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -520,6 +664,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -531,15 +676,22 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
+golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -552,7 +704,18 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
@@ -566,17 +729,20 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -585,14 +751,18 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -606,12 +776,36 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -634,6 +828,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
@@ -659,6 +855,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -681,7 +878,6 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512001501-aaeff5de670a/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -689,7 +885,18 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
@@ -717,6 +924,22 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
+google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
+google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
+google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
+google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
+google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
+google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
+google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
+google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
+google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
google.golang.org/api v0.183.0 h1:PNMeRDwo1pJdgNcFQ9GstuLe/noWKIc89pRWRLMvLwE=
google.golang.org/api v0.183.0/go.mod h1:q43adC5/pHoSZTx5h2mSmdF7NcyfW9JuDyIOJAgS9ZQ=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -725,6 +948,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -756,6 +980,39 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
+google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
+google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
+google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U=
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
@@ -773,9 +1030,24 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -788,6 +1060,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
@@ -804,6 +1077,7 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWM
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -815,6 +1089,7 @@ gopkg.in/yaml.v2 v2.3.0/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=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/cloudevents/conformance/pkg/event/event.go b/vendor/github.com/cloudevents/conformance/pkg/event/event.go
index c02c9777671..dae125821ba 100644
--- a/vendor/github.com/cloudevents/conformance/pkg/event/event.go
+++ b/vendor/github.com/cloudevents/conformance/pkg/event/event.go
@@ -1,3 +1,8 @@
+/*
+ Copyright 2022 The CloudEvents Authors
+ SPDX-License-Identifier: Apache-2.0
+*/
+
package event
type MutationFn func(Event) (Event, error)
@@ -11,12 +16,40 @@ const (
type Event struct {
Mode string `yaml:"Mode,omitempty"`
- Attributes ContextAttributes `yaml:"ContextAttributes"`
+ Attributes ContextAttributes `yaml:"ContextAttributes,omitempty"`
TransportExtensions Extensions `yaml:"TransportExtensions,omitempty"`
- Data string `yaml:"Data"`
+ Data string `yaml:"Data,omitempty"`
// TODO: add support for data_base64
}
+// Get returns the value of the attribute or extension named `key`.
+func (e *Event) Get(key string) string {
+ switch key {
+ case "specversion":
+ return e.Attributes.SpecVersion
+ case "type":
+ return e.Attributes.Type
+ case "time":
+ return e.Attributes.Time
+ case "id":
+ return e.Attributes.ID
+ case "source":
+ return e.Attributes.Source
+ case "subject":
+ return e.Attributes.Subject
+ case "schemaurl":
+ return e.Attributes.SchemaURL
+ case "dataschema":
+ return e.Attributes.DataSchema
+ case "dataecontentncoding":
+ return e.Attributes.DataContentEncoding
+ case "datacontenttype":
+ return e.Attributes.DataContentType
+ default:
+ return e.Attributes.Extensions[key]
+ }
+}
+
type ContextAttributes struct {
SpecVersion string `yaml:"specversion,omitempty"`
Type string `yaml:"type,omitempty"`
diff --git a/vendor/github.com/cloudevents/conformance/pkg/event/read.go b/vendor/github.com/cloudevents/conformance/pkg/event/read.go
index 3cfc9e6bd6d..88de8e2e3f2 100644
--- a/vendor/github.com/cloudevents/conformance/pkg/event/read.go
+++ b/vendor/github.com/cloudevents/conformance/pkg/event/read.go
@@ -1,3 +1,8 @@
+/*
+ Copyright 2022 The CloudEvents Authors
+ SPDX-License-Identifier: Apache-2.0
+*/
+
package event
import (
diff --git a/vendor/github.com/cloudevents/conformance/pkg/event/write.go b/vendor/github.com/cloudevents/conformance/pkg/event/write.go
index 51f548d1d5c..1ca50c64a37 100644
--- a/vendor/github.com/cloudevents/conformance/pkg/event/write.go
+++ b/vendor/github.com/cloudevents/conformance/pkg/event/write.go
@@ -1,3 +1,8 @@
+/*
+ Copyright 2022 The CloudEvents Authors
+ SPDX-License-Identifier: Apache-2.0
+*/
+
package event
import (
diff --git a/vendor/github.com/cloudevents/conformance/pkg/http/http.go b/vendor/github.com/cloudevents/conformance/pkg/http/http.go
index e326463f0e7..c5efbd2dfec 100644
--- a/vendor/github.com/cloudevents/conformance/pkg/http/http.go
+++ b/vendor/github.com/cloudevents/conformance/pkg/http/http.go
@@ -1,3 +1,8 @@
+/*
+ Copyright 2022 The CloudEvents Authors
+ SPDX-License-Identifier: Apache-2.0
+*/
+
package http
import (
diff --git a/vendor/github.com/cloudevents/conformance/pkg/http/raw.go b/vendor/github.com/cloudevents/conformance/pkg/http/raw.go
index dd7b7f477fa..acfd2e8d16e 100644
--- a/vendor/github.com/cloudevents/conformance/pkg/http/raw.go
+++ b/vendor/github.com/cloudevents/conformance/pkg/http/raw.go
@@ -1,3 +1,8 @@
+/*
+ Copyright 2022 The CloudEvents Authors
+ SPDX-License-Identifier: Apache-2.0
+*/
+
package http
import (
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/CESQLLexer.g4 b/vendor/github.com/cloudevents/sdk-go/sql/v2/CESQLLexer.g4
index d83124abd3b..a889c058a46 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/CESQLLexer.g4
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/CESQLLexer.g4
@@ -70,7 +70,7 @@ FALSE: 'FALSE';
DQUOTED_STRING_LITERAL: DQUOTA_STRING;
SQUOTED_STRING_LITERAL: SQUOTA_STRING;
-INTEGER_LITERAL: ('+' | '-')? INT_DIGIT+;
+INTEGER_LITERAL: INT_DIGIT+;
// Identifiers
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/README.md b/vendor/github.com/cloudevents/sdk-go/sql/v2/README.md
index 948f48f416d..f45641d973d 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/README.md
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/README.md
@@ -18,54 +18,6 @@ expression, err := cesqlparser.Parse("subject = 'Hello world'")
res, err := expression.Evaluate(event)
```
-Add a user defined function
-```go
-import (
- cesql "github.com/cloudevents/sdk-go/sql/v2"
- cefn "github.com/cloudevents/sdk-go/sql/v2/function"
- cesqlparser "github.com/cloudevents/sdk-go/sql/v2/parser"
- ceruntime "github.com/cloudevents/sdk-go/sql/v2/runtime"
- cloudevents "github.com/cloudevents/sdk-go/v2"
-)
-
-// Create a test event
-event := cloudevents.NewEvent()
-event.SetID("aaaa-bbbb-dddd")
-event.SetSource("https://my-source")
-event.SetType("dev.tekton.event")
-
-// Create and add a new user defined function
-var HasPrefixFunction cesql.Function = cefn.NewFunction(
- "HASPREFIX",
- []cesql.Type{cesql.StringType, cesql.StringType},
- nil,
- func(event cloudevents.Event, i []interface{}) (interface{}, error) {
- str := i[0].(string)
- prefix := i[1].(string)
-
- return strings.HasPrefix(str, prefix), nil
- },
-)
-
-err := ceruntime.AddFunction(HasPrefixFunction)
-
-// parse the expression
-expression, err := cesqlparser.Parse("HASPREFIX(type, 'dev.tekton.event')")
- if err != nil {
- fmt.Println("parser err: ", err)
- os.Exit(1)
- }
-
-// Evalute the expression with the test event
-res, err := expression.Evaluate(event)
-
-if res.(bool) {
- fmt.Println("Event type has the prefix")
-} else {
- fmt.Println("Event type doesn't have the prefix")
-}
-```
-
## Development guide
To regenerate the parser, make sure you have [ANTLR4 installed](https://github.com/antlr/antlr4/blob/master/doc/getting-started.md) and then run:
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/errors/errors.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/errors/errors.go
deleted file mode 100644
index 207ce55f34e..00000000000
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/errors/errors.go
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- Copyright 2024 The CloudEvents Authors
- SPDX-License-Identifier: Apache-2.0
-*/
-
-package errors
-
-import (
- "fmt"
- "strings"
-)
-
-type errorKind int
-
-const (
- parseError = iota
- mathError
- castError
- missingAttributeError
- missingFunctionError
- functionEvaluationError
- dummyLastError // always add new error classes ABOVE this error
-)
-
-type cesqlError struct {
- kind errorKind
- message string
-}
-
-func (eKind errorKind) String() string {
- switch eKind {
- case parseError:
- return "parse error"
- case mathError:
- return "math error"
- case castError:
- return "cast error"
- case missingAttributeError:
- return "missing attribute error"
- case missingFunctionError:
- return "missing function error"
- case functionEvaluationError:
- return "function evaluation error"
- default:
- return "generic error"
- }
-
-}
-
-func (cerr cesqlError) Error() string {
- return fmt.Sprintf("%s: %s", cerr.kind, cerr.message)
-}
-
-func NewParseError(errs []error) error {
- if len(errs) == 0 {
- return nil
- }
-
- errorMessages := make([]string, 0, len(errs))
- for _, err := range errs {
- errorMessages = append(errorMessages, err.Error())
- }
-
- return cesqlError{
- kind: parseError,
- message: strings.Join(errorMessages, "|"),
- }
-}
-
-func IsParseError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind == parseError
- }
- return false
-}
-
-func IsMathError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind == mathError
- }
- return false
-}
-
-func NewMathError(message string) error {
- return cesqlError{
- kind: mathError,
- message: message,
- }
-}
-
-func IsCastError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind == castError
- }
- return false
-}
-
-func NewCastError(err error) error {
- return cesqlError{
- kind: castError,
- message: err.Error(),
- }
-}
-
-func IsMissingAttributeError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind == missingAttributeError
- }
- return false
-}
-
-func NewMissingAttributeError(attribute string) error {
- return cesqlError{
- kind: missingAttributeError,
- message: attribute,
- }
-}
-
-func IsMissingFunctionError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind == missingFunctionError
- }
- return false
-}
-
-func NewMissingFunctionError(function string) error {
- return cesqlError{
- kind: missingFunctionError,
- message: function,
- }
-}
-
-func IsFunctionEvaluationError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind == functionEvaluationError
- }
- return false
-}
-
-func NewFunctionEvaluationError(err error) error {
- return cesqlError{
- kind: functionEvaluationError,
- message: err.Error(),
- }
-}
-
-func IsGenericError(err error) bool {
- if cesqlErr, ok := err.(cesqlError); ok {
- return cesqlErr.kind < 0 || cesqlErr.kind >= dummyLastError
- }
- return false
-}
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/comparison_expressions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/comparison_expressions.go
index a39ad3ce793..97449073738 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/comparison_expressions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/comparison_expressions.go
@@ -19,17 +19,17 @@ type equalExpression struct {
func (s equalExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
leftVal, err := s.left.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
rightVal, err := s.right.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
leftVal, err = utils.Cast(leftVal, cesql.TypeFromVal(rightVal))
if err != nil {
- return false, err
+ return nil, err
}
return (leftVal == rightVal) == s.equal, nil
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/function_invocation_expression.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/function_invocation_expression.go
index 577272f268f..94e383aa158 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/function_invocation_expression.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/function_invocation_expression.go
@@ -9,7 +9,6 @@ import (
"fmt"
cesql "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
"github.com/cloudevents/sdk-go/sql/v2/runtime"
"github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2"
@@ -23,44 +22,31 @@ type functionInvocationExpression struct {
func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
fn := runtime.ResolveFunction(expr.name, len(expr.argumentsExpression))
if fn == nil {
- return false, sqlerrors.NewMissingFunctionError(expr.name)
+ return nil, fmt.Errorf("cannot resolve function %s", expr.name)
}
args := make([]interface{}, len(expr.argumentsExpression))
- defaultVal := fn.ReturnType().ZeroValue()
-
for i, expr := range expr.argumentsExpression {
arg, err := expr.Evaluate(event)
if err != nil {
- return defaultVal, err
+ return nil, err
}
argType := fn.ArgType(i)
if argType == nil {
- return defaultVal, sqlerrors.NewFunctionEvaluationError(fmt.Errorf("cannot resolve arg type at index %d for function %s", i, fn.Name()))
+ return nil, fmt.Errorf("cannot resolve arg type at index %d", i)
}
arg, err = utils.Cast(arg, *argType)
if err != nil {
- return defaultVal, err
+ return nil, err
}
args[i] = arg
}
- result, err := fn.Run(event, args)
- if result == nil {
- if err != nil {
- err = sqlerrors.NewFunctionEvaluationError(fmt.Errorf("function %s encountered error %w and did not return any value, defaulting to the default value for the function", fn.Name(), err))
- } else {
- err = sqlerrors.NewFunctionEvaluationError(fmt.Errorf("function %s did not return any value, defaulting to the default value for the function", fn.Name()))
- }
-
- return defaultVal, err
- }
-
- return result, err
+ return fn.Run(event, args)
}
func NewFunctionInvocationExpression(name string, argumentsExpression []cesql.Expression) cesql.Expression {
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/identifier_expression.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/identifier_expression.go
index fe85052f9c6..265a3b463f5 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/identifier_expression.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/identifier_expression.go
@@ -6,8 +6,9 @@
package expression
import (
+ "fmt"
+
cesql "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
"github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2"
)
@@ -19,7 +20,7 @@ type identifierExpression struct {
func (l identifierExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
value := utils.GetAttribute(event, l.identifier)
if value == nil {
- return false, sqlerrors.NewMissingAttributeError(l.identifier)
+ return nil, fmt.Errorf("missing attribute '%s'", l.identifier)
}
return value, nil
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/in_expression.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/in_expression.go
index ef1c587c04c..b45a421ceab 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/in_expression.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/in_expression.go
@@ -19,18 +19,18 @@ type inExpression struct {
func (l inExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
leftValue, err := l.leftExpression.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
for _, rightExpression := range l.setExpression {
rightValue, err := rightExpression.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
rightValue, err = utils.Cast(rightValue, cesql.TypeFromVal(leftValue))
if err != nil {
- return false, err
+ return nil, err
}
if leftValue == rightValue {
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/integer_comparison_expressions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/integer_comparison_expressions.go
index 12e529b79a1..13a70a974c0 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/integer_comparison_expressions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/integer_comparison_expressions.go
@@ -19,22 +19,22 @@ type integerComparisonExpression struct {
func (s integerComparisonExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
leftVal, err := s.left.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
rightVal, err := s.right.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
leftVal, err = utils.Cast(leftVal, cesql.IntegerType)
if err != nil {
- return false, err
+ return nil, err
}
rightVal, err = utils.Cast(rightVal, cesql.IntegerType)
if err != nil {
- return false, err
+ return nil, err
}
return s.fn(leftVal.(int32), rightVal.(int32)), nil
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/like_expression.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/like_expression.go
index ed43db49415..5f557fa5ac7 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/like_expression.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/like_expression.go
@@ -6,6 +6,9 @@
package expression
import (
+ "regexp"
+ "strings"
+
cesql "github.com/cloudevents/sdk-go/sql/v2"
"github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2"
@@ -13,79 +16,84 @@ import (
type likeExpression struct {
baseUnaryExpression
- pattern string
+ pattern *regexp.Regexp
}
func (l likeExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
val, err := l.child.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
val, err = utils.Cast(val, cesql.StringType)
if err != nil {
- return false, err
+ return nil, err
}
- return matchString(val.(string), l.pattern), nil
-
+ return l.pattern.MatchString(val.(string)), nil
}
func NewLikeExpression(child cesql.Expression, pattern string) (cesql.Expression, error) {
+ // Converting to regex is not the most performant impl, but it works
+ p, err := convertLikePatternToRegex(pattern)
+ if err != nil {
+ return nil, err
+ }
+
return likeExpression{
baseUnaryExpression: baseUnaryExpression{
child: child,
},
- pattern: pattern,
+ pattern: p,
}, nil
}
-func matchString(text, pattern string) bool {
- textLen := len(text)
- patternLen := len(pattern)
- textIdx := 0
- patternIdx := 0
- lastWildcardIdx := -1
- lastMatchIdx := 0
+func convertLikePatternToRegex(pattern string) (*regexp.Regexp, error) {
+ var chunks []string
+ chunks = append(chunks, "^")
- if patternLen == 0 {
- return patternLen == textLen
- }
+ var chunk strings.Builder
- for textIdx < textLen {
- if patternIdx < patternLen-1 && pattern[patternIdx] == '\\' &&
- ((pattern[patternIdx+1] == '_' || pattern[patternIdx+1] == '%') &&
- pattern[patternIdx+1] == text[textIdx]) {
- // handle escaped characters -> pattern needs to increment two places here
- patternIdx += 2
- textIdx += 1
- } else if patternIdx < patternLen && (pattern[patternIdx] == '_' || pattern[patternIdx] == text[textIdx]) {
- // handle non escaped characters
- textIdx += 1
- patternIdx += 1
- } else if patternIdx < patternLen && pattern[patternIdx] == '%' {
- // handle wildcard characters
- lastWildcardIdx = patternIdx
- lastMatchIdx = textIdx
- patternIdx += 1
- } else if lastWildcardIdx != -1 {
- // greedy match didn't work, try again from the last known match
- patternIdx = lastWildcardIdx + 1
- lastMatchIdx += 1
- textIdx = lastMatchIdx
+ for i := 0; i < len(pattern); i++ {
+ if pattern[i] == '\\' && i < len(pattern)-1 {
+ if pattern[i+1] == '%' {
+ // \% case
+ chunk.WriteRune('%')
+ chunks = append(chunks, "\\Q"+chunk.String()+"\\E")
+ chunk.Reset()
+ i++
+ continue
+ } else if pattern[i+1] == '_' {
+ // \_ case
+ chunk.WriteRune('_')
+ chunks = append(chunks, "\\Q"+chunk.String()+"\\E")
+ chunk.Reset()
+ i++
+ continue
+ } else {
+ // if there is an actual literal \ character, we need to include that in the string
+ chunk.WriteRune('\\')
+ }
+ } else if pattern[i] == '_' {
+ // replace with .
+ chunks = append(chunks, "\\Q"+chunk.String()+"\\E")
+ chunk.Reset()
+ chunks = append(chunks, ".")
+ } else if pattern[i] == '%' {
+ // replace with .*
+ chunks = append(chunks, "\\Q"+chunk.String()+"\\E")
+ chunk.Reset()
+ chunks = append(chunks, ".*")
} else {
- return false
+ chunk.WriteByte(pattern[i])
}
}
- // consume remaining pattern characters as long as they are wildcards
- for patternIdx < patternLen {
- if pattern[patternIdx] != '%' {
- return false
- }
-
- patternIdx += 1
+ if chunk.Len() != 0 {
+ chunks = append(chunks, "\\Q"+chunk.String()+"\\E")
}
- return true
+ chunks = append(chunks, "$")
+
+ return regexp.Compile(strings.Join(chunks, ""))
}
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/logic_expressions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/logic_expressions.go
index 4812debf221..f75a0f9c4e3 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/logic_expressions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/logic_expressions.go
@@ -20,12 +20,12 @@ type logicExpression struct {
func (s logicExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
leftVal, err := s.left.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
leftVal, err = utils.Cast(leftVal, cesql.BooleanType)
if err != nil {
- return false, err
+ return nil, err
}
// Don't bother to check the other expression unless we need to
@@ -38,12 +38,12 @@ func (s logicExpression) Evaluate(event cloudevents.Event) (interface{}, error)
rightVal, err := s.right.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
rightVal, err = utils.Cast(rightVal, cesql.BooleanType)
if err != nil {
- return false, err
+ return nil, err
}
return s.fn(leftVal.(bool), rightVal.(bool)), nil
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/math_expressions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/math_expressions.go
index 50b45d70b03..d0378201132 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/math_expressions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/math_expressions.go
@@ -6,8 +6,9 @@
package expression
import (
+ "errors"
+
cesql "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
"github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2"
)
@@ -20,22 +21,22 @@ type mathExpression struct {
func (s mathExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
leftVal, err := s.left.Evaluate(event)
if err != nil {
- return int32(0), err
+ return nil, err
}
rightVal, err := s.right.Evaluate(event)
if err != nil {
- return int32(0), err
+ return nil, err
}
leftVal, err = utils.Cast(leftVal, cesql.IntegerType)
if err != nil {
- return int32(0), err
+ return nil, err
}
rightVal, err = utils.Cast(rightVal, cesql.IntegerType)
if err != nil {
- return int32(0), err
+ return nil, err
}
return s.fn(leftVal.(int32), rightVal.(int32))
@@ -85,7 +86,7 @@ func NewModuleExpression(left cesql.Expression, right cesql.Expression) cesql.Ex
},
fn: func(x, y int32) (int32, error) {
if y == 0 {
- return 0, sqlerrors.NewMathError("division by zero")
+ return 0, errors.New("math error: division by zero")
}
return x % y, nil
},
@@ -100,7 +101,7 @@ func NewDivisionExpression(left cesql.Expression, right cesql.Expression) cesql.
},
fn: func(x, y int32) (int32, error) {
if y == 0 {
- return 0, sqlerrors.NewMathError("division by zero")
+ return 0, errors.New("math error: division by zero")
}
return x / y, nil
},
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/negate_expression.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/negate_expression.go
index d271f324389..f917a83bf49 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/negate_expression.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/negate_expression.go
@@ -16,12 +16,12 @@ type negateExpression baseUnaryExpression
func (l negateExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
val, err := l.child.Evaluate(event)
if err != nil {
- return int32(0), err
+ return nil, err
}
val, err = utils.Cast(val, cesql.IntegerType)
if err != nil {
- return int32(0), err
+ return nil, err
}
return -(val.(int32)), nil
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/not_expression.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/not_expression.go
index a1bedac10ba..7f5e95b9f8c 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/not_expression.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/expression/not_expression.go
@@ -16,12 +16,12 @@ type notExpression baseUnaryExpression
func (l notExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
val, err := l.child.Evaluate(event)
if err != nil {
- return false, err
+ return nil, err
}
val, err = utils.Cast(val, cesql.BooleanType)
if err != nil {
- return false, err
+ return nil, err
}
return !(val.(bool)), nil
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/function.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/function.go
index fb7efb65552..1502a3d2f8d 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/function.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/function.go
@@ -12,7 +12,6 @@ type Function interface {
Arity() int
IsVariadic() bool
ArgType(index int) *Type
- ReturnType() Type
Run(event cloudevents.Event, arguments []interface{}) (interface{}, error)
}
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/casting_functions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/casting_functions.go
index 35c1d562eba..91069de8096 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/casting_functions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/casting_functions.go
@@ -15,7 +15,6 @@ var IntFunction function = function{
name: "INT",
fixedArgs: []cesql.Type{cesql.AnyType},
variadicArgs: nil,
- returnType: cesql.IntegerType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return utils.Cast(i[0], cesql.IntegerType)
},
@@ -25,7 +24,6 @@ var BoolFunction function = function{
name: "BOOL",
fixedArgs: []cesql.Type{cesql.AnyType},
variadicArgs: nil,
- returnType: cesql.BooleanType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return utils.Cast(i[0], cesql.BooleanType)
},
@@ -35,7 +33,6 @@ var StringFunction function = function{
name: "STRING",
fixedArgs: []cesql.Type{cesql.AnyType},
variadicArgs: nil,
- returnType: cesql.StringType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return utils.Cast(i[0], cesql.StringType)
},
@@ -45,7 +42,6 @@ var IsIntFunction function = function{
name: "IS_INT",
fixedArgs: []cesql.Type{cesql.AnyType},
variadicArgs: nil,
- returnType: cesql.BooleanType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return utils.CanCast(i[0], cesql.IntegerType), nil
},
@@ -55,7 +51,6 @@ var IsBoolFunction function = function{
name: "IS_BOOL",
fixedArgs: []cesql.Type{cesql.AnyType},
variadicArgs: nil,
- returnType: cesql.BooleanType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return utils.CanCast(i[0], cesql.BooleanType), nil
},
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/function.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/function.go
index ddc3d0489fe..4ad61faed6b 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/function.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/function.go
@@ -10,14 +10,11 @@ import (
cloudevents "github.com/cloudevents/sdk-go/v2"
)
-type FuncType func(cloudevents.Event, []interface{}) (interface{}, error)
-
type function struct {
name string
fixedArgs []cesql.Type
variadicArgs *cesql.Type
- returnType cesql.Type
- fn FuncType
+ fn func(cloudevents.Event, []interface{}) (interface{}, error)
}
func (f function) Name() string {
@@ -39,24 +36,6 @@ func (f function) ArgType(index int) *cesql.Type {
return f.variadicArgs
}
-func (f function) ReturnType() cesql.Type {
- return f.returnType
-}
-
func (f function) Run(event cloudevents.Event, arguments []interface{}) (interface{}, error) {
return f.fn(event, arguments)
}
-
-func NewFunction(name string,
- fixedArgs []cesql.Type,
- variadicArgs *cesql.Type,
- returnType cesql.Type,
- fn FuncType) cesql.Function {
- return function{
- name: name,
- fixedArgs: fixedArgs,
- variadicArgs: variadicArgs,
- returnType: returnType,
- fn: fn,
- }
-}
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/integer_functions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/integer_functions.go
index f7f3f7225b7..4aaf64f2272 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/integer_functions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/integer_functions.go
@@ -7,21 +7,15 @@ package function
import (
cesql "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
cloudevents "github.com/cloudevents/sdk-go/v2"
- "math"
)
var AbsFunction function = function{
name: "ABS",
fixedArgs: []cesql.Type{cesql.IntegerType},
variadicArgs: nil,
- returnType: cesql.IntegerType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
x := i[0].(int32)
- if x == math.MinInt32 {
- return int32(math.MaxInt32), sqlerrors.NewMathError("integer overflow while computing ABS")
- }
if x < 0 {
return -x, nil
}
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/string_functions.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/string_functions.go
index 66eeb2c1637..2d0d7e4a93e 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/function/string_functions.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/function/string_functions.go
@@ -10,7 +10,6 @@ import (
"strings"
cesql "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
cloudevents "github.com/cloudevents/sdk-go/v2"
)
@@ -18,7 +17,6 @@ var LengthFunction function = function{
name: "LENGTH",
fixedArgs: []cesql.Type{cesql.StringType},
variadicArgs: nil,
- returnType: cesql.IntegerType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return int32(len(i[0].(string))), nil
},
@@ -27,7 +25,6 @@ var LengthFunction function = function{
var ConcatFunction function = function{
name: "CONCAT",
variadicArgs: cesql.TypePtr(cesql.StringType),
- returnType: cesql.StringType,
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
var sb strings.Builder
for _, v := range i {
@@ -41,7 +38,6 @@ var ConcatWSFunction function = function{
name: "CONCAT_WS",
fixedArgs: []cesql.Type{cesql.StringType},
variadicArgs: cesql.TypePtr(cesql.StringType),
- returnType: cesql.StringType,
fn: func(event cloudevents.Event, args []interface{}) (interface{}, error) {
if len(args) == 1 {
return "", nil
@@ -59,36 +55,32 @@ var ConcatWSFunction function = function{
}
var LowerFunction function = function{
- name: "LOWER",
- fixedArgs: []cesql.Type{cesql.StringType},
- returnType: cesql.StringType,
+ name: "LOWER",
+ fixedArgs: []cesql.Type{cesql.StringType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return strings.ToLower(i[0].(string)), nil
},
}
var UpperFunction function = function{
- name: "UPPER",
- fixedArgs: []cesql.Type{cesql.StringType},
- returnType: cesql.StringType,
+ name: "UPPER",
+ fixedArgs: []cesql.Type{cesql.StringType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return strings.ToUpper(i[0].(string)), nil
},
}
var TrimFunction function = function{
- name: "TRIM",
- fixedArgs: []cesql.Type{cesql.StringType},
- returnType: cesql.StringType,
+ name: "TRIM",
+ fixedArgs: []cesql.Type{cesql.StringType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
return strings.TrimSpace(i[0].(string)), nil
},
}
var LeftFunction function = function{
- name: "LEFT",
- fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType},
- returnType: cesql.StringType,
+ name: "LEFT",
+ fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
str := i[0].(string)
y := int(i[1].(int32))
@@ -98,7 +90,7 @@ var LeftFunction function = function{
}
if y < 0 {
- return str, sqlerrors.NewFunctionEvaluationError(fmt.Errorf("LEFT y argument is < 0: %d", y))
+ return nil, fmt.Errorf("LEFT y argument is < 0: %d", y)
}
return str[0:y], nil
@@ -106,9 +98,8 @@ var LeftFunction function = function{
}
var RightFunction function = function{
- name: "RIGHT",
- fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType},
- returnType: cesql.StringType,
+ name: "RIGHT",
+ fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
str := i[0].(string)
y := int(i[1].(int32))
@@ -118,7 +109,7 @@ var RightFunction function = function{
}
if y < 0 {
- return str, sqlerrors.NewFunctionEvaluationError(fmt.Errorf("RIGHT y argument is < 0: %d", y))
+ return nil, fmt.Errorf("RIGHT y argument is < 0: %d", y)
}
return str[len(str)-y:], nil
@@ -126,9 +117,8 @@ var RightFunction function = function{
}
var SubstringFunction function = function{
- name: "SUBSTRING",
- fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType},
- returnType: cesql.StringType,
+ name: "SUBSTRING",
+ fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
str := i[0].(string)
pos := int(i[1].(int32))
@@ -138,7 +128,7 @@ var SubstringFunction function = function{
}
if pos < -len(str) || pos > len(str) {
- return "", sqlerrors.NewFunctionEvaluationError(fmt.Errorf("SUBSTRING invalid pos argument: %d", pos))
+ return "", fmt.Errorf("SUBSTRING invalid pos argument: %d", pos)
}
var beginning int
@@ -153,9 +143,8 @@ var SubstringFunction function = function{
}
var SubstringWithLengthFunction function = function{
- name: "SUBSTRING",
- fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType, cesql.IntegerType},
- returnType: cesql.StringType,
+ name: "SUBSTRING",
+ fixedArgs: []cesql.Type{cesql.StringType, cesql.IntegerType, cesql.IntegerType},
fn: func(event cloudevents.Event, i []interface{}) (interface{}, error) {
str := i[0].(string)
pos := int(i[1].(int32))
@@ -166,7 +155,7 @@ var SubstringWithLengthFunction function = function{
}
if pos < -len(str) || pos > len(str) {
- return "", sqlerrors.NewFunctionEvaluationError(fmt.Errorf("SUBSTRING invalid pos argument: %d", pos))
+ return "", fmt.Errorf("SUBSTRING invalid pos argument: %d", pos)
}
var beginning int
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/CESQLParserLexer.interp b/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/CESQLParserLexer.interp
index befa543b494..f758513dbe9 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/CESQLParserLexer.interp
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/CESQLParserLexer.interp
@@ -119,4 +119,4 @@ mode names:
DEFAULT_MODE
atn:
-[4, 0, 33, 238, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 1, 0, 4, 0, 81, 8, 0, 11, 0, 12, 0, 82, 1, 0, 1, 0, 1, 1, 4, 1, 88, 8, 1, 11, 1, 12, 1, 89, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 98, 8, 2, 10, 2, 12, 2, 101, 9, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 111, 8, 3, 10, 3, 12, 3, 114, 9, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 5, 5, 122, 8, 5, 10, 5, 12, 5, 125, 9, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 3, 11, 139, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 3, 35, 215, 8, 35, 1, 35, 4, 35, 218, 8, 35, 11, 35, 12, 35, 219, 1, 36, 4, 36, 223, 8, 36, 11, 36, 12, 36, 224, 1, 37, 4, 37, 228, 8, 37, 11, 37, 12, 37, 229, 1, 38, 1, 38, 5, 38, 234, 8, 38, 10, 38, 12, 38, 237, 9, 38, 0, 0, 39, 1, 1, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 13, 2, 15, 3, 17, 4, 19, 5, 21, 6, 23, 0, 25, 7, 27, 8, 29, 9, 31, 10, 33, 11, 35, 12, 37, 13, 39, 14, 41, 15, 43, 16, 45, 17, 47, 18, 49, 19, 51, 20, 53, 21, 55, 22, 57, 23, 59, 24, 61, 25, 63, 26, 65, 27, 67, 28, 69, 29, 71, 30, 73, 31, 75, 32, 77, 33, 1, 0, 9, 3, 0, 9, 10, 13, 13, 32, 32, 3, 0, 48, 57, 65, 90, 97, 122, 2, 0, 34, 34, 92, 92, 2, 0, 39, 39, 92, 92, 1, 0, 48, 57, 1, 0, 65, 90, 2, 0, 65, 90, 95, 95, 2, 0, 43, 43, 45, 45, 2, 0, 65, 90, 97, 122, 246, 0, 1, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 1, 80, 1, 0, 0, 0, 3, 87, 1, 0, 0, 0, 5, 91, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 117, 1, 0, 0, 0, 11, 119, 1, 0, 0, 0, 13, 126, 1, 0, 0, 0, 15, 128, 1, 0, 0, 0, 17, 130, 1, 0, 0, 0, 19, 132, 1, 0, 0, 0, 21, 134, 1, 0, 0, 0, 23, 138, 1, 0, 0, 0, 25, 140, 1, 0, 0, 0, 27, 144, 1, 0, 0, 0, 29, 147, 1, 0, 0, 0, 31, 151, 1, 0, 0, 0, 33, 155, 1, 0, 0, 0, 35, 157, 1, 0, 0, 0, 37, 159, 1, 0, 0, 0, 39, 161, 1, 0, 0, 0, 41, 163, 1, 0, 0, 0, 43, 165, 1, 0, 0, 0, 45, 167, 1, 0, 0, 0, 47, 170, 1, 0, 0, 0, 49, 172, 1, 0, 0, 0, 51, 175, 1, 0, 0, 0, 53, 177, 1, 0, 0, 0, 55, 180, 1, 0, 0, 0, 57, 183, 1, 0, 0, 0, 59, 188, 1, 0, 0, 0, 61, 195, 1, 0, 0, 0, 63, 198, 1, 0, 0, 0, 65, 203, 1, 0, 0, 0, 67, 209, 1, 0, 0, 0, 69, 211, 1, 0, 0, 0, 71, 214, 1, 0, 0, 0, 73, 222, 1, 0, 0, 0, 75, 227, 1, 0, 0, 0, 77, 231, 1, 0, 0, 0, 79, 81, 7, 0, 0, 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 85, 6, 0, 0, 0, 85, 2, 1, 0, 0, 0, 86, 88, 7, 1, 0, 0, 87, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 87, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 4, 1, 0, 0, 0, 91, 99, 5, 34, 0, 0, 92, 93, 5, 92, 0, 0, 93, 98, 9, 0, 0, 0, 94, 95, 5, 34, 0, 0, 95, 98, 5, 34, 0, 0, 96, 98, 8, 2, 0, 0, 97, 92, 1, 0, 0, 0, 97, 94, 1, 0, 0, 0, 97, 96, 1, 0, 0, 0, 98, 101, 1, 0, 0, 0, 99, 97, 1, 0, 0, 0, 99, 100, 1, 0, 0, 0, 100, 102, 1, 0, 0, 0, 101, 99, 1, 0, 0, 0, 102, 103, 5, 34, 0, 0, 103, 6, 1, 0, 0, 0, 104, 112, 5, 39, 0, 0, 105, 106, 5, 92, 0, 0, 106, 111, 9, 0, 0, 0, 107, 108, 5, 39, 0, 0, 108, 111, 5, 39, 0, 0, 109, 111, 8, 3, 0, 0, 110, 105, 1, 0, 0, 0, 110, 107, 1, 0, 0, 0, 110, 109, 1, 0, 0, 0, 111, 114, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 112, 113, 1, 0, 0, 0, 113, 115, 1, 0, 0, 0, 114, 112, 1, 0, 0, 0, 115, 116, 5, 39, 0, 0, 116, 8, 1, 0, 0, 0, 117, 118, 7, 4, 0, 0, 118, 10, 1, 0, 0, 0, 119, 123, 7, 5, 0, 0, 120, 122, 7, 6, 0, 0, 121, 120, 1, 0, 0, 0, 122, 125, 1, 0, 0, 0, 123, 121, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 12, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 126, 127, 5, 40, 0, 0, 127, 14, 1, 0, 0, 0, 128, 129, 5, 41, 0, 0, 129, 16, 1, 0, 0, 0, 130, 131, 5, 44, 0, 0, 131, 18, 1, 0, 0, 0, 132, 133, 5, 39, 0, 0, 133, 20, 1, 0, 0, 0, 134, 135, 5, 34, 0, 0, 135, 22, 1, 0, 0, 0, 136, 139, 3, 19, 9, 0, 137, 139, 3, 21, 10, 0, 138, 136, 1, 0, 0, 0, 138, 137, 1, 0, 0, 0, 139, 24, 1, 0, 0, 0, 140, 141, 5, 65, 0, 0, 141, 142, 5, 78, 0, 0, 142, 143, 5, 68, 0, 0, 143, 26, 1, 0, 0, 0, 144, 145, 5, 79, 0, 0, 145, 146, 5, 82, 0, 0, 146, 28, 1, 0, 0, 0, 147, 148, 5, 88, 0, 0, 148, 149, 5, 79, 0, 0, 149, 150, 5, 82, 0, 0, 150, 30, 1, 0, 0, 0, 151, 152, 5, 78, 0, 0, 152, 153, 5, 79, 0, 0, 153, 154, 5, 84, 0, 0, 154, 32, 1, 0, 0, 0, 155, 156, 5, 42, 0, 0, 156, 34, 1, 0, 0, 0, 157, 158, 5, 47, 0, 0, 158, 36, 1, 0, 0, 0, 159, 160, 5, 37, 0, 0, 160, 38, 1, 0, 0, 0, 161, 162, 5, 43, 0, 0, 162, 40, 1, 0, 0, 0, 163, 164, 5, 45, 0, 0, 164, 42, 1, 0, 0, 0, 165, 166, 5, 61, 0, 0, 166, 44, 1, 0, 0, 0, 167, 168, 5, 33, 0, 0, 168, 169, 5, 61, 0, 0, 169, 46, 1, 0, 0, 0, 170, 171, 5, 62, 0, 0, 171, 48, 1, 0, 0, 0, 172, 173, 5, 62, 0, 0, 173, 174, 5, 61, 0, 0, 174, 50, 1, 0, 0, 0, 175, 176, 5, 60, 0, 0, 176, 52, 1, 0, 0, 0, 177, 178, 5, 60, 0, 0, 178, 179, 5, 62, 0, 0, 179, 54, 1, 0, 0, 0, 180, 181, 5, 60, 0, 0, 181, 182, 5, 61, 0, 0, 182, 56, 1, 0, 0, 0, 183, 184, 5, 76, 0, 0, 184, 185, 5, 73, 0, 0, 185, 186, 5, 75, 0, 0, 186, 187, 5, 69, 0, 0, 187, 58, 1, 0, 0, 0, 188, 189, 5, 69, 0, 0, 189, 190, 5, 88, 0, 0, 190, 191, 5, 73, 0, 0, 191, 192, 5, 83, 0, 0, 192, 193, 5, 84, 0, 0, 193, 194, 5, 83, 0, 0, 194, 60, 1, 0, 0, 0, 195, 196, 5, 73, 0, 0, 196, 197, 5, 78, 0, 0, 197, 62, 1, 0, 0, 0, 198, 199, 5, 84, 0, 0, 199, 200, 5, 82, 0, 0, 200, 201, 5, 85, 0, 0, 201, 202, 5, 69, 0, 0, 202, 64, 1, 0, 0, 0, 203, 204, 5, 70, 0, 0, 204, 205, 5, 65, 0, 0, 205, 206, 5, 76, 0, 0, 206, 207, 5, 83, 0, 0, 207, 208, 5, 69, 0, 0, 208, 66, 1, 0, 0, 0, 209, 210, 3, 5, 2, 0, 210, 68, 1, 0, 0, 0, 211, 212, 3, 7, 3, 0, 212, 70, 1, 0, 0, 0, 213, 215, 7, 7, 0, 0, 214, 213, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 217, 1, 0, 0, 0, 216, 218, 3, 9, 4, 0, 217, 216, 1, 0, 0, 0, 218, 219, 1, 0, 0, 0, 219, 217, 1, 0, 0, 0, 219, 220, 1, 0, 0, 0, 220, 72, 1, 0, 0, 0, 221, 223, 7, 8, 0, 0, 222, 221, 1, 0, 0, 0, 223, 224, 1, 0, 0, 0, 224, 222, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 74, 1, 0, 0, 0, 226, 228, 7, 1, 0, 0, 227, 226, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 230, 76, 1, 0, 0, 0, 231, 235, 7, 5, 0, 0, 232, 234, 7, 6, 0, 0, 233, 232, 1, 0, 0, 0, 234, 237, 1, 0, 0, 0, 235, 233, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 78, 1, 0, 0, 0, 237, 235, 1, 0, 0, 0, 14, 0, 82, 89, 97, 99, 110, 112, 123, 138, 214, 219, 224, 229, 235, 1, 6, 0, 0]
\ No newline at end of file
+[4, 0, 33, 235, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 1, 0, 4, 0, 81, 8, 0, 11, 0, 12, 0, 82, 1, 0, 1, 0, 1, 1, 4, 1, 88, 8, 1, 11, 1, 12, 1, 89, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 98, 8, 2, 10, 2, 12, 2, 101, 9, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 111, 8, 3, 10, 3, 12, 3, 114, 9, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 5, 5, 122, 8, 5, 10, 5, 12, 5, 125, 9, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 3, 11, 139, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 4, 35, 215, 8, 35, 11, 35, 12, 35, 216, 1, 36, 4, 36, 220, 8, 36, 11, 36, 12, 36, 221, 1, 37, 4, 37, 225, 8, 37, 11, 37, 12, 37, 226, 1, 38, 1, 38, 5, 38, 231, 8, 38, 10, 38, 12, 38, 234, 9, 38, 0, 0, 39, 1, 1, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 13, 2, 15, 3, 17, 4, 19, 5, 21, 6, 23, 0, 25, 7, 27, 8, 29, 9, 31, 10, 33, 11, 35, 12, 37, 13, 39, 14, 41, 15, 43, 16, 45, 17, 47, 18, 49, 19, 51, 20, 53, 21, 55, 22, 57, 23, 59, 24, 61, 25, 63, 26, 65, 27, 67, 28, 69, 29, 71, 30, 73, 31, 75, 32, 77, 33, 1, 0, 8, 3, 0, 9, 10, 13, 13, 32, 32, 3, 0, 48, 57, 65, 90, 97, 122, 2, 0, 34, 34, 92, 92, 2, 0, 39, 39, 92, 92, 1, 0, 48, 57, 1, 0, 65, 90, 2, 0, 65, 90, 95, 95, 2, 0, 65, 90, 97, 122, 242, 0, 1, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 1, 80, 1, 0, 0, 0, 3, 87, 1, 0, 0, 0, 5, 91, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 117, 1, 0, 0, 0, 11, 119, 1, 0, 0, 0, 13, 126, 1, 0, 0, 0, 15, 128, 1, 0, 0, 0, 17, 130, 1, 0, 0, 0, 19, 132, 1, 0, 0, 0, 21, 134, 1, 0, 0, 0, 23, 138, 1, 0, 0, 0, 25, 140, 1, 0, 0, 0, 27, 144, 1, 0, 0, 0, 29, 147, 1, 0, 0, 0, 31, 151, 1, 0, 0, 0, 33, 155, 1, 0, 0, 0, 35, 157, 1, 0, 0, 0, 37, 159, 1, 0, 0, 0, 39, 161, 1, 0, 0, 0, 41, 163, 1, 0, 0, 0, 43, 165, 1, 0, 0, 0, 45, 167, 1, 0, 0, 0, 47, 170, 1, 0, 0, 0, 49, 172, 1, 0, 0, 0, 51, 175, 1, 0, 0, 0, 53, 177, 1, 0, 0, 0, 55, 180, 1, 0, 0, 0, 57, 183, 1, 0, 0, 0, 59, 188, 1, 0, 0, 0, 61, 195, 1, 0, 0, 0, 63, 198, 1, 0, 0, 0, 65, 203, 1, 0, 0, 0, 67, 209, 1, 0, 0, 0, 69, 211, 1, 0, 0, 0, 71, 214, 1, 0, 0, 0, 73, 219, 1, 0, 0, 0, 75, 224, 1, 0, 0, 0, 77, 228, 1, 0, 0, 0, 79, 81, 7, 0, 0, 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 85, 6, 0, 0, 0, 85, 2, 1, 0, 0, 0, 86, 88, 7, 1, 0, 0, 87, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 87, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 4, 1, 0, 0, 0, 91, 99, 5, 34, 0, 0, 92, 93, 5, 92, 0, 0, 93, 98, 9, 0, 0, 0, 94, 95, 5, 34, 0, 0, 95, 98, 5, 34, 0, 0, 96, 98, 8, 2, 0, 0, 97, 92, 1, 0, 0, 0, 97, 94, 1, 0, 0, 0, 97, 96, 1, 0, 0, 0, 98, 101, 1, 0, 0, 0, 99, 97, 1, 0, 0, 0, 99, 100, 1, 0, 0, 0, 100, 102, 1, 0, 0, 0, 101, 99, 1, 0, 0, 0, 102, 103, 5, 34, 0, 0, 103, 6, 1, 0, 0, 0, 104, 112, 5, 39, 0, 0, 105, 106, 5, 92, 0, 0, 106, 111, 9, 0, 0, 0, 107, 108, 5, 39, 0, 0, 108, 111, 5, 39, 0, 0, 109, 111, 8, 3, 0, 0, 110, 105, 1, 0, 0, 0, 110, 107, 1, 0, 0, 0, 110, 109, 1, 0, 0, 0, 111, 114, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 112, 113, 1, 0, 0, 0, 113, 115, 1, 0, 0, 0, 114, 112, 1, 0, 0, 0, 115, 116, 5, 39, 0, 0, 116, 8, 1, 0, 0, 0, 117, 118, 7, 4, 0, 0, 118, 10, 1, 0, 0, 0, 119, 123, 7, 5, 0, 0, 120, 122, 7, 6, 0, 0, 121, 120, 1, 0, 0, 0, 122, 125, 1, 0, 0, 0, 123, 121, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 12, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 126, 127, 5, 40, 0, 0, 127, 14, 1, 0, 0, 0, 128, 129, 5, 41, 0, 0, 129, 16, 1, 0, 0, 0, 130, 131, 5, 44, 0, 0, 131, 18, 1, 0, 0, 0, 132, 133, 5, 39, 0, 0, 133, 20, 1, 0, 0, 0, 134, 135, 5, 34, 0, 0, 135, 22, 1, 0, 0, 0, 136, 139, 3, 19, 9, 0, 137, 139, 3, 21, 10, 0, 138, 136, 1, 0, 0, 0, 138, 137, 1, 0, 0, 0, 139, 24, 1, 0, 0, 0, 140, 141, 5, 65, 0, 0, 141, 142, 5, 78, 0, 0, 142, 143, 5, 68, 0, 0, 143, 26, 1, 0, 0, 0, 144, 145, 5, 79, 0, 0, 145, 146, 5, 82, 0, 0, 146, 28, 1, 0, 0, 0, 147, 148, 5, 88, 0, 0, 148, 149, 5, 79, 0, 0, 149, 150, 5, 82, 0, 0, 150, 30, 1, 0, 0, 0, 151, 152, 5, 78, 0, 0, 152, 153, 5, 79, 0, 0, 153, 154, 5, 84, 0, 0, 154, 32, 1, 0, 0, 0, 155, 156, 5, 42, 0, 0, 156, 34, 1, 0, 0, 0, 157, 158, 5, 47, 0, 0, 158, 36, 1, 0, 0, 0, 159, 160, 5, 37, 0, 0, 160, 38, 1, 0, 0, 0, 161, 162, 5, 43, 0, 0, 162, 40, 1, 0, 0, 0, 163, 164, 5, 45, 0, 0, 164, 42, 1, 0, 0, 0, 165, 166, 5, 61, 0, 0, 166, 44, 1, 0, 0, 0, 167, 168, 5, 33, 0, 0, 168, 169, 5, 61, 0, 0, 169, 46, 1, 0, 0, 0, 170, 171, 5, 62, 0, 0, 171, 48, 1, 0, 0, 0, 172, 173, 5, 62, 0, 0, 173, 174, 5, 61, 0, 0, 174, 50, 1, 0, 0, 0, 175, 176, 5, 60, 0, 0, 176, 52, 1, 0, 0, 0, 177, 178, 5, 60, 0, 0, 178, 179, 5, 62, 0, 0, 179, 54, 1, 0, 0, 0, 180, 181, 5, 60, 0, 0, 181, 182, 5, 61, 0, 0, 182, 56, 1, 0, 0, 0, 183, 184, 5, 76, 0, 0, 184, 185, 5, 73, 0, 0, 185, 186, 5, 75, 0, 0, 186, 187, 5, 69, 0, 0, 187, 58, 1, 0, 0, 0, 188, 189, 5, 69, 0, 0, 189, 190, 5, 88, 0, 0, 190, 191, 5, 73, 0, 0, 191, 192, 5, 83, 0, 0, 192, 193, 5, 84, 0, 0, 193, 194, 5, 83, 0, 0, 194, 60, 1, 0, 0, 0, 195, 196, 5, 73, 0, 0, 196, 197, 5, 78, 0, 0, 197, 62, 1, 0, 0, 0, 198, 199, 5, 84, 0, 0, 199, 200, 5, 82, 0, 0, 200, 201, 5, 85, 0, 0, 201, 202, 5, 69, 0, 0, 202, 64, 1, 0, 0, 0, 203, 204, 5, 70, 0, 0, 204, 205, 5, 65, 0, 0, 205, 206, 5, 76, 0, 0, 206, 207, 5, 83, 0, 0, 207, 208, 5, 69, 0, 0, 208, 66, 1, 0, 0, 0, 209, 210, 3, 5, 2, 0, 210, 68, 1, 0, 0, 0, 211, 212, 3, 7, 3, 0, 212, 70, 1, 0, 0, 0, 213, 215, 3, 9, 4, 0, 214, 213, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 214, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 72, 1, 0, 0, 0, 218, 220, 7, 7, 0, 0, 219, 218, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 219, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 74, 1, 0, 0, 0, 223, 225, 7, 1, 0, 0, 224, 223, 1, 0, 0, 0, 225, 226, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 76, 1, 0, 0, 0, 228, 232, 7, 5, 0, 0, 229, 231, 7, 6, 0, 0, 230, 229, 1, 0, 0, 0, 231, 234, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 232, 233, 1, 0, 0, 0, 233, 78, 1, 0, 0, 0, 234, 232, 1, 0, 0, 0, 13, 0, 82, 89, 97, 99, 110, 112, 123, 138, 216, 221, 226, 232, 1, 6, 0, 0]
\ No newline at end of file
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/cesqlparser_lexer.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/cesqlparser_lexer.go
index 22dc8dacc44..556d8b90986 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/cesqlparser_lexer.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/gen/cesqlparser_lexer.go
@@ -67,7 +67,7 @@ func cesqlparserlexerLexerInit() {
}
staticData.predictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{
- 4, 0, 33, 238, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2,
+ 4, 0, 33, 235, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2,
4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2,
10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15,
7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7,
@@ -87,90 +87,89 @@ func cesqlparserlexerLexerInit() {
1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1,
28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30,
1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1,
- 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 3, 35, 215, 8, 35, 1, 35, 4, 35,
- 218, 8, 35, 11, 35, 12, 35, 219, 1, 36, 4, 36, 223, 8, 36, 11, 36, 12,
- 36, 224, 1, 37, 4, 37, 228, 8, 37, 11, 37, 12, 37, 229, 1, 38, 1, 38, 5,
- 38, 234, 8, 38, 10, 38, 12, 38, 237, 9, 38, 0, 0, 39, 1, 1, 3, 0, 5, 0,
- 7, 0, 9, 0, 11, 0, 13, 2, 15, 3, 17, 4, 19, 5, 21, 6, 23, 0, 25, 7, 27,
- 8, 29, 9, 31, 10, 33, 11, 35, 12, 37, 13, 39, 14, 41, 15, 43, 16, 45, 17,
- 47, 18, 49, 19, 51, 20, 53, 21, 55, 22, 57, 23, 59, 24, 61, 25, 63, 26,
- 65, 27, 67, 28, 69, 29, 71, 30, 73, 31, 75, 32, 77, 33, 1, 0, 9, 3, 0,
- 9, 10, 13, 13, 32, 32, 3, 0, 48, 57, 65, 90, 97, 122, 2, 0, 34, 34, 92,
- 92, 2, 0, 39, 39, 92, 92, 1, 0, 48, 57, 1, 0, 65, 90, 2, 0, 65, 90, 95,
- 95, 2, 0, 43, 43, 45, 45, 2, 0, 65, 90, 97, 122, 246, 0, 1, 1, 0, 0, 0,
- 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0,
- 0, 0, 21, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0,
- 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1,
- 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45,
- 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0,
- 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0,
- 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0,
- 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0,
- 0, 0, 0, 77, 1, 0, 0, 0, 1, 80, 1, 0, 0, 0, 3, 87, 1, 0, 0, 0, 5, 91, 1,
- 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 117, 1, 0, 0, 0, 11, 119, 1, 0, 0, 0, 13,
- 126, 1, 0, 0, 0, 15, 128, 1, 0, 0, 0, 17, 130, 1, 0, 0, 0, 19, 132, 1,
- 0, 0, 0, 21, 134, 1, 0, 0, 0, 23, 138, 1, 0, 0, 0, 25, 140, 1, 0, 0, 0,
- 27, 144, 1, 0, 0, 0, 29, 147, 1, 0, 0, 0, 31, 151, 1, 0, 0, 0, 33, 155,
- 1, 0, 0, 0, 35, 157, 1, 0, 0, 0, 37, 159, 1, 0, 0, 0, 39, 161, 1, 0, 0,
- 0, 41, 163, 1, 0, 0, 0, 43, 165, 1, 0, 0, 0, 45, 167, 1, 0, 0, 0, 47, 170,
- 1, 0, 0, 0, 49, 172, 1, 0, 0, 0, 51, 175, 1, 0, 0, 0, 53, 177, 1, 0, 0,
- 0, 55, 180, 1, 0, 0, 0, 57, 183, 1, 0, 0, 0, 59, 188, 1, 0, 0, 0, 61, 195,
- 1, 0, 0, 0, 63, 198, 1, 0, 0, 0, 65, 203, 1, 0, 0, 0, 67, 209, 1, 0, 0,
- 0, 69, 211, 1, 0, 0, 0, 71, 214, 1, 0, 0, 0, 73, 222, 1, 0, 0, 0, 75, 227,
- 1, 0, 0, 0, 77, 231, 1, 0, 0, 0, 79, 81, 7, 0, 0, 0, 80, 79, 1, 0, 0, 0,
- 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 84, 1,
- 0, 0, 0, 84, 85, 6, 0, 0, 0, 85, 2, 1, 0, 0, 0, 86, 88, 7, 1, 0, 0, 87,
- 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 87, 1, 0, 0, 0, 89, 90, 1, 0, 0,
- 0, 90, 4, 1, 0, 0, 0, 91, 99, 5, 34, 0, 0, 92, 93, 5, 92, 0, 0, 93, 98,
- 9, 0, 0, 0, 94, 95, 5, 34, 0, 0, 95, 98, 5, 34, 0, 0, 96, 98, 8, 2, 0,
- 0, 97, 92, 1, 0, 0, 0, 97, 94, 1, 0, 0, 0, 97, 96, 1, 0, 0, 0, 98, 101,
- 1, 0, 0, 0, 99, 97, 1, 0, 0, 0, 99, 100, 1, 0, 0, 0, 100, 102, 1, 0, 0,
- 0, 101, 99, 1, 0, 0, 0, 102, 103, 5, 34, 0, 0, 103, 6, 1, 0, 0, 0, 104,
- 112, 5, 39, 0, 0, 105, 106, 5, 92, 0, 0, 106, 111, 9, 0, 0, 0, 107, 108,
- 5, 39, 0, 0, 108, 111, 5, 39, 0, 0, 109, 111, 8, 3, 0, 0, 110, 105, 1,
- 0, 0, 0, 110, 107, 1, 0, 0, 0, 110, 109, 1, 0, 0, 0, 111, 114, 1, 0, 0,
- 0, 112, 110, 1, 0, 0, 0, 112, 113, 1, 0, 0, 0, 113, 115, 1, 0, 0, 0, 114,
- 112, 1, 0, 0, 0, 115, 116, 5, 39, 0, 0, 116, 8, 1, 0, 0, 0, 117, 118, 7,
- 4, 0, 0, 118, 10, 1, 0, 0, 0, 119, 123, 7, 5, 0, 0, 120, 122, 7, 6, 0,
- 0, 121, 120, 1, 0, 0, 0, 122, 125, 1, 0, 0, 0, 123, 121, 1, 0, 0, 0, 123,
- 124, 1, 0, 0, 0, 124, 12, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 126, 127, 5,
- 40, 0, 0, 127, 14, 1, 0, 0, 0, 128, 129, 5, 41, 0, 0, 129, 16, 1, 0, 0,
- 0, 130, 131, 5, 44, 0, 0, 131, 18, 1, 0, 0, 0, 132, 133, 5, 39, 0, 0, 133,
- 20, 1, 0, 0, 0, 134, 135, 5, 34, 0, 0, 135, 22, 1, 0, 0, 0, 136, 139, 3,
- 19, 9, 0, 137, 139, 3, 21, 10, 0, 138, 136, 1, 0, 0, 0, 138, 137, 1, 0,
- 0, 0, 139, 24, 1, 0, 0, 0, 140, 141, 5, 65, 0, 0, 141, 142, 5, 78, 0, 0,
- 142, 143, 5, 68, 0, 0, 143, 26, 1, 0, 0, 0, 144, 145, 5, 79, 0, 0, 145,
- 146, 5, 82, 0, 0, 146, 28, 1, 0, 0, 0, 147, 148, 5, 88, 0, 0, 148, 149,
- 5, 79, 0, 0, 149, 150, 5, 82, 0, 0, 150, 30, 1, 0, 0, 0, 151, 152, 5, 78,
- 0, 0, 152, 153, 5, 79, 0, 0, 153, 154, 5, 84, 0, 0, 154, 32, 1, 0, 0, 0,
- 155, 156, 5, 42, 0, 0, 156, 34, 1, 0, 0, 0, 157, 158, 5, 47, 0, 0, 158,
- 36, 1, 0, 0, 0, 159, 160, 5, 37, 0, 0, 160, 38, 1, 0, 0, 0, 161, 162, 5,
- 43, 0, 0, 162, 40, 1, 0, 0, 0, 163, 164, 5, 45, 0, 0, 164, 42, 1, 0, 0,
- 0, 165, 166, 5, 61, 0, 0, 166, 44, 1, 0, 0, 0, 167, 168, 5, 33, 0, 0, 168,
- 169, 5, 61, 0, 0, 169, 46, 1, 0, 0, 0, 170, 171, 5, 62, 0, 0, 171, 48,
- 1, 0, 0, 0, 172, 173, 5, 62, 0, 0, 173, 174, 5, 61, 0, 0, 174, 50, 1, 0,
- 0, 0, 175, 176, 5, 60, 0, 0, 176, 52, 1, 0, 0, 0, 177, 178, 5, 60, 0, 0,
- 178, 179, 5, 62, 0, 0, 179, 54, 1, 0, 0, 0, 180, 181, 5, 60, 0, 0, 181,
- 182, 5, 61, 0, 0, 182, 56, 1, 0, 0, 0, 183, 184, 5, 76, 0, 0, 184, 185,
- 5, 73, 0, 0, 185, 186, 5, 75, 0, 0, 186, 187, 5, 69, 0, 0, 187, 58, 1,
- 0, 0, 0, 188, 189, 5, 69, 0, 0, 189, 190, 5, 88, 0, 0, 190, 191, 5, 73,
- 0, 0, 191, 192, 5, 83, 0, 0, 192, 193, 5, 84, 0, 0, 193, 194, 5, 83, 0,
- 0, 194, 60, 1, 0, 0, 0, 195, 196, 5, 73, 0, 0, 196, 197, 5, 78, 0, 0, 197,
- 62, 1, 0, 0, 0, 198, 199, 5, 84, 0, 0, 199, 200, 5, 82, 0, 0, 200, 201,
- 5, 85, 0, 0, 201, 202, 5, 69, 0, 0, 202, 64, 1, 0, 0, 0, 203, 204, 5, 70,
- 0, 0, 204, 205, 5, 65, 0, 0, 205, 206, 5, 76, 0, 0, 206, 207, 5, 83, 0,
- 0, 207, 208, 5, 69, 0, 0, 208, 66, 1, 0, 0, 0, 209, 210, 3, 5, 2, 0, 210,
- 68, 1, 0, 0, 0, 211, 212, 3, 7, 3, 0, 212, 70, 1, 0, 0, 0, 213, 215, 7,
- 7, 0, 0, 214, 213, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 217, 1, 0, 0,
- 0, 216, 218, 3, 9, 4, 0, 217, 216, 1, 0, 0, 0, 218, 219, 1, 0, 0, 0, 219,
- 217, 1, 0, 0, 0, 219, 220, 1, 0, 0, 0, 220, 72, 1, 0, 0, 0, 221, 223, 7,
- 8, 0, 0, 222, 221, 1, 0, 0, 0, 223, 224, 1, 0, 0, 0, 224, 222, 1, 0, 0,
- 0, 224, 225, 1, 0, 0, 0, 225, 74, 1, 0, 0, 0, 226, 228, 7, 1, 0, 0, 227,
- 226, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 230,
- 1, 0, 0, 0, 230, 76, 1, 0, 0, 0, 231, 235, 7, 5, 0, 0, 232, 234, 7, 6,
- 0, 0, 233, 232, 1, 0, 0, 0, 234, 237, 1, 0, 0, 0, 235, 233, 1, 0, 0, 0,
- 235, 236, 1, 0, 0, 0, 236, 78, 1, 0, 0, 0, 237, 235, 1, 0, 0, 0, 14, 0,
- 82, 89, 97, 99, 110, 112, 123, 138, 214, 219, 224, 229, 235, 1, 6, 0, 0,
+ 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 4, 35, 215, 8, 35, 11, 35, 12, 35,
+ 216, 1, 36, 4, 36, 220, 8, 36, 11, 36, 12, 36, 221, 1, 37, 4, 37, 225,
+ 8, 37, 11, 37, 12, 37, 226, 1, 38, 1, 38, 5, 38, 231, 8, 38, 10, 38, 12,
+ 38, 234, 9, 38, 0, 0, 39, 1, 1, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 13, 2, 15,
+ 3, 17, 4, 19, 5, 21, 6, 23, 0, 25, 7, 27, 8, 29, 9, 31, 10, 33, 11, 35,
+ 12, 37, 13, 39, 14, 41, 15, 43, 16, 45, 17, 47, 18, 49, 19, 51, 20, 53,
+ 21, 55, 22, 57, 23, 59, 24, 61, 25, 63, 26, 65, 27, 67, 28, 69, 29, 71,
+ 30, 73, 31, 75, 32, 77, 33, 1, 0, 8, 3, 0, 9, 10, 13, 13, 32, 32, 3, 0,
+ 48, 57, 65, 90, 97, 122, 2, 0, 34, 34, 92, 92, 2, 0, 39, 39, 92, 92, 1,
+ 0, 48, 57, 1, 0, 65, 90, 2, 0, 65, 90, 95, 95, 2, 0, 65, 90, 97, 122, 242,
+ 0, 1, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0,
+ 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0,
+ 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1,
+ 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43,
+ 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0,
+ 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0,
+ 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0,
+ 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0,
+ 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 1, 80, 1, 0, 0, 0, 3, 87, 1,
+ 0, 0, 0, 5, 91, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 117, 1, 0, 0, 0, 11,
+ 119, 1, 0, 0, 0, 13, 126, 1, 0, 0, 0, 15, 128, 1, 0, 0, 0, 17, 130, 1,
+ 0, 0, 0, 19, 132, 1, 0, 0, 0, 21, 134, 1, 0, 0, 0, 23, 138, 1, 0, 0, 0,
+ 25, 140, 1, 0, 0, 0, 27, 144, 1, 0, 0, 0, 29, 147, 1, 0, 0, 0, 31, 151,
+ 1, 0, 0, 0, 33, 155, 1, 0, 0, 0, 35, 157, 1, 0, 0, 0, 37, 159, 1, 0, 0,
+ 0, 39, 161, 1, 0, 0, 0, 41, 163, 1, 0, 0, 0, 43, 165, 1, 0, 0, 0, 45, 167,
+ 1, 0, 0, 0, 47, 170, 1, 0, 0, 0, 49, 172, 1, 0, 0, 0, 51, 175, 1, 0, 0,
+ 0, 53, 177, 1, 0, 0, 0, 55, 180, 1, 0, 0, 0, 57, 183, 1, 0, 0, 0, 59, 188,
+ 1, 0, 0, 0, 61, 195, 1, 0, 0, 0, 63, 198, 1, 0, 0, 0, 65, 203, 1, 0, 0,
+ 0, 67, 209, 1, 0, 0, 0, 69, 211, 1, 0, 0, 0, 71, 214, 1, 0, 0, 0, 73, 219,
+ 1, 0, 0, 0, 75, 224, 1, 0, 0, 0, 77, 228, 1, 0, 0, 0, 79, 81, 7, 0, 0,
+ 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83,
+ 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 85, 6, 0, 0, 0, 85, 2, 1, 0, 0, 0,
+ 86, 88, 7, 1, 0, 0, 87, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 87, 1,
+ 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 4, 1, 0, 0, 0, 91, 99, 5, 34, 0, 0, 92,
+ 93, 5, 92, 0, 0, 93, 98, 9, 0, 0, 0, 94, 95, 5, 34, 0, 0, 95, 98, 5, 34,
+ 0, 0, 96, 98, 8, 2, 0, 0, 97, 92, 1, 0, 0, 0, 97, 94, 1, 0, 0, 0, 97, 96,
+ 1, 0, 0, 0, 98, 101, 1, 0, 0, 0, 99, 97, 1, 0, 0, 0, 99, 100, 1, 0, 0,
+ 0, 100, 102, 1, 0, 0, 0, 101, 99, 1, 0, 0, 0, 102, 103, 5, 34, 0, 0, 103,
+ 6, 1, 0, 0, 0, 104, 112, 5, 39, 0, 0, 105, 106, 5, 92, 0, 0, 106, 111,
+ 9, 0, 0, 0, 107, 108, 5, 39, 0, 0, 108, 111, 5, 39, 0, 0, 109, 111, 8,
+ 3, 0, 0, 110, 105, 1, 0, 0, 0, 110, 107, 1, 0, 0, 0, 110, 109, 1, 0, 0,
+ 0, 111, 114, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 112, 113, 1, 0, 0, 0, 113,
+ 115, 1, 0, 0, 0, 114, 112, 1, 0, 0, 0, 115, 116, 5, 39, 0, 0, 116, 8, 1,
+ 0, 0, 0, 117, 118, 7, 4, 0, 0, 118, 10, 1, 0, 0, 0, 119, 123, 7, 5, 0,
+ 0, 120, 122, 7, 6, 0, 0, 121, 120, 1, 0, 0, 0, 122, 125, 1, 0, 0, 0, 123,
+ 121, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 12, 1, 0, 0, 0, 125, 123, 1,
+ 0, 0, 0, 126, 127, 5, 40, 0, 0, 127, 14, 1, 0, 0, 0, 128, 129, 5, 41, 0,
+ 0, 129, 16, 1, 0, 0, 0, 130, 131, 5, 44, 0, 0, 131, 18, 1, 0, 0, 0, 132,
+ 133, 5, 39, 0, 0, 133, 20, 1, 0, 0, 0, 134, 135, 5, 34, 0, 0, 135, 22,
+ 1, 0, 0, 0, 136, 139, 3, 19, 9, 0, 137, 139, 3, 21, 10, 0, 138, 136, 1,
+ 0, 0, 0, 138, 137, 1, 0, 0, 0, 139, 24, 1, 0, 0, 0, 140, 141, 5, 65, 0,
+ 0, 141, 142, 5, 78, 0, 0, 142, 143, 5, 68, 0, 0, 143, 26, 1, 0, 0, 0, 144,
+ 145, 5, 79, 0, 0, 145, 146, 5, 82, 0, 0, 146, 28, 1, 0, 0, 0, 147, 148,
+ 5, 88, 0, 0, 148, 149, 5, 79, 0, 0, 149, 150, 5, 82, 0, 0, 150, 30, 1,
+ 0, 0, 0, 151, 152, 5, 78, 0, 0, 152, 153, 5, 79, 0, 0, 153, 154, 5, 84,
+ 0, 0, 154, 32, 1, 0, 0, 0, 155, 156, 5, 42, 0, 0, 156, 34, 1, 0, 0, 0,
+ 157, 158, 5, 47, 0, 0, 158, 36, 1, 0, 0, 0, 159, 160, 5, 37, 0, 0, 160,
+ 38, 1, 0, 0, 0, 161, 162, 5, 43, 0, 0, 162, 40, 1, 0, 0, 0, 163, 164, 5,
+ 45, 0, 0, 164, 42, 1, 0, 0, 0, 165, 166, 5, 61, 0, 0, 166, 44, 1, 0, 0,
+ 0, 167, 168, 5, 33, 0, 0, 168, 169, 5, 61, 0, 0, 169, 46, 1, 0, 0, 0, 170,
+ 171, 5, 62, 0, 0, 171, 48, 1, 0, 0, 0, 172, 173, 5, 62, 0, 0, 173, 174,
+ 5, 61, 0, 0, 174, 50, 1, 0, 0, 0, 175, 176, 5, 60, 0, 0, 176, 52, 1, 0,
+ 0, 0, 177, 178, 5, 60, 0, 0, 178, 179, 5, 62, 0, 0, 179, 54, 1, 0, 0, 0,
+ 180, 181, 5, 60, 0, 0, 181, 182, 5, 61, 0, 0, 182, 56, 1, 0, 0, 0, 183,
+ 184, 5, 76, 0, 0, 184, 185, 5, 73, 0, 0, 185, 186, 5, 75, 0, 0, 186, 187,
+ 5, 69, 0, 0, 187, 58, 1, 0, 0, 0, 188, 189, 5, 69, 0, 0, 189, 190, 5, 88,
+ 0, 0, 190, 191, 5, 73, 0, 0, 191, 192, 5, 83, 0, 0, 192, 193, 5, 84, 0,
+ 0, 193, 194, 5, 83, 0, 0, 194, 60, 1, 0, 0, 0, 195, 196, 5, 73, 0, 0, 196,
+ 197, 5, 78, 0, 0, 197, 62, 1, 0, 0, 0, 198, 199, 5, 84, 0, 0, 199, 200,
+ 5, 82, 0, 0, 200, 201, 5, 85, 0, 0, 201, 202, 5, 69, 0, 0, 202, 64, 1,
+ 0, 0, 0, 203, 204, 5, 70, 0, 0, 204, 205, 5, 65, 0, 0, 205, 206, 5, 76,
+ 0, 0, 206, 207, 5, 83, 0, 0, 207, 208, 5, 69, 0, 0, 208, 66, 1, 0, 0, 0,
+ 209, 210, 3, 5, 2, 0, 210, 68, 1, 0, 0, 0, 211, 212, 3, 7, 3, 0, 212, 70,
+ 1, 0, 0, 0, 213, 215, 3, 9, 4, 0, 214, 213, 1, 0, 0, 0, 215, 216, 1, 0,
+ 0, 0, 216, 214, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 72, 1, 0, 0, 0,
+ 218, 220, 7, 7, 0, 0, 219, 218, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221,
+ 219, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 74, 1, 0, 0, 0, 223, 225, 7,
+ 1, 0, 0, 224, 223, 1, 0, 0, 0, 225, 226, 1, 0, 0, 0, 226, 224, 1, 0, 0,
+ 0, 226, 227, 1, 0, 0, 0, 227, 76, 1, 0, 0, 0, 228, 232, 7, 5, 0, 0, 229,
+ 231, 7, 6, 0, 0, 230, 229, 1, 0, 0, 0, 231, 234, 1, 0, 0, 0, 232, 230,
+ 1, 0, 0, 0, 232, 233, 1, 0, 0, 0, 233, 78, 1, 0, 0, 0, 234, 232, 1, 0,
+ 0, 0, 13, 0, 82, 89, 97, 99, 110, 112, 123, 138, 216, 221, 226, 232, 1,
+ 6, 0, 0,
}
deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN)
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/expression_visitor.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/expression_visitor.go
index 4fb863ac2a3..8ca5fd07ed4 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/expression_visitor.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/expression_visitor.go
@@ -6,7 +6,6 @@
package parser
import (
- "fmt"
"strconv"
"strings"
@@ -176,13 +175,9 @@ func (v *expressionVisitor) VisitLikeExpression(ctx *gen.LikeExpressionContext)
if patternContext.DQUOTED_STRING_LITERAL() != nil {
// Parse double quoted string
pattern = dQuotedStringToString(patternContext.DQUOTED_STRING_LITERAL().GetText())
- } else if patternContext.SQUOTED_STRING_LITERAL() != nil {
+ } else {
// Parse single quoted string
pattern = sQuotedStringToString(patternContext.SQUOTED_STRING_LITERAL().GetText())
- } else {
- // not a string, return an error
- v.parsingErrors = append(v.parsingErrors, fmt.Errorf("failed to parse LIKE expression: the pattern was not a string literal"))
- return noopExpression{}
}
likeExpression, err := expression.NewLikeExpression(v.Visit(ctx.Expression()).(cesql.Expression), pattern)
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/parser.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/parser.go
index e332da2cc3b..2dacf834be7 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/parser.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/parser/parser.go
@@ -6,12 +6,13 @@
package parser
import (
+ "errors"
"fmt"
+ "strings"
"github.com/antlr/antlr4/runtime/Go/antlr"
- v2 "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
+ "github.com/cloudevents/sdk-go/sql/v2"
"github.com/cloudevents/sdk-go/sql/v2/gen"
)
@@ -38,10 +39,10 @@ func (p *Parser) Parse(input string) (v2.Expression, error) {
result := antlrParser.Cesql().Accept(&visitor)
if result == nil {
- return nil, sqlerrors.NewParseError(append(collectingErrorListener.errs, visitor.parsingErrors...))
+ return nil, mergeErrs(append(collectingErrorListener.errs, visitor.parsingErrors...))
}
- return result.(v2.Expression), sqlerrors.NewParseError(append(collectingErrorListener.errs, visitor.parsingErrors...))
+ return result.(v2.Expression), mergeErrs(append(collectingErrorListener.errs, visitor.parsingErrors...))
}
type errorListener struct {
@@ -53,6 +54,19 @@ func (d *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol
d.errs = append(d.errs, fmt.Errorf("syntax error: %v", e.GetMessage()))
}
+func mergeErrs(errs []error) error {
+ if len(errs) == 0 {
+ return nil
+ }
+
+ var errStrings []string
+ for _, err := range errs {
+ errStrings = append(errStrings, err.Error())
+ }
+
+ return errors.New(strings.Join(errStrings, ","))
+}
+
var defaultParser = Parser{}
func Parse(input string) (v2.Expression, error) {
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/runtime/functions_resolver.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/runtime/functions_resolver.go
index 5ab964fb7ff..b801368426b 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/runtime/functions_resolver.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/runtime/functions_resolver.go
@@ -58,11 +58,6 @@ func (table functionTable) AddFunction(function cesql.Function) error {
}
}
-// Adds user defined function
-func AddFunction(fn cesql.Function) error {
- return globalFunctionTable.AddFunction(fn)
-}
-
func (table functionTable) ResolveFunction(name string, args int) cesql.Function {
item := table[strings.ToUpper(name)]
if item == nil {
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/types.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/types.go
index 629b7a18d55..0c1f20078e8 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/types.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/types.go
@@ -34,21 +34,6 @@ func (t Type) String() string {
return "Any"
}
-func (t Type) ZeroValue() interface{} {
- switch t {
- case StringType:
- return ""
- case IntegerType:
- return 0
- case BooleanType:
- return false
- case AnyType:
- // by default, return false
- return false
- }
- return false
-}
-
func TypeFromVal(val interface{}) Type {
switch val.(type) {
case string:
diff --git a/vendor/github.com/cloudevents/sdk-go/sql/v2/utils/casting.go b/vendor/github.com/cloudevents/sdk-go/sql/v2/utils/casting.go
index d8053adb328..25895374db2 100644
--- a/vendor/github.com/cloudevents/sdk-go/sql/v2/utils/casting.go
+++ b/vendor/github.com/cloudevents/sdk-go/sql/v2/utils/casting.go
@@ -11,7 +11,6 @@ import (
"strings"
cesql "github.com/cloudevents/sdk-go/sql/v2"
- sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors"
)
func Cast(val interface{}, target cesql.Type) (interface{}, error) {
@@ -37,16 +36,11 @@ func Cast(val interface{}, target cesql.Type) (interface{}, error) {
case string:
v, err := strconv.ParseInt(val.(string), 10, 32)
if err != nil {
- err = sqlerrors.NewCastError(fmt.Errorf("cannot cast from String to Integer: %w", err))
+ err = fmt.Errorf("cannot cast from String to Integer: %w", err)
}
return int32(v), err
- case bool:
- if val.(bool) {
- return int32(1), nil
- }
- return int32(0), nil
}
- return 0, sqlerrors.NewCastError(fmt.Errorf("undefined cast from %v to %v", cesql.TypeFromVal(val), target))
+ return 0, fmt.Errorf("undefined cast from %v to %v", cesql.TypeFromVal(val), target)
case cesql.BooleanType:
switch val.(type) {
case string:
@@ -56,14 +50,9 @@ func Cast(val interface{}, target cesql.Type) (interface{}, error) {
} else if lowerCase == "false" {
return false, nil
}
- return false, sqlerrors.NewCastError(fmt.Errorf("cannot cast String to Boolean, actual value: %v", val))
- case int32:
- if val.(int32) == 0 {
- return false, nil
- }
- return true, nil
+ return false, fmt.Errorf("cannot cast String to Boolean, actual value: %v", val)
}
- return false, sqlerrors.NewCastError(fmt.Errorf("undefined cast from %v to %v", cesql.TypeFromVal(val), target))
+ return false, fmt.Errorf("undefined cast from %v to %v", cesql.TypeFromVal(val), target)
}
// AnyType doesn't need casting
diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go b/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go
index b7bd09275df..f42d37d4812 100644
--- a/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go
+++ b/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go
@@ -1,5 +1,7 @@
package oidc
+import jose "github.com/go-jose/go-jose/v4"
+
// JOSE asymmetric signing algorithm values as defined by RFC 7518
//
// see: https://tools.ietf.org/html/rfc7518#section-3.1
@@ -15,3 +17,16 @@ const (
PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512
EdDSA = "EdDSA" // Ed25519 using SHA-512
)
+
+var allAlgs = []jose.SignatureAlgorithm{
+ jose.RS256,
+ jose.RS384,
+ jose.RS512,
+ jose.ES256,
+ jose.ES384,
+ jose.ES512,
+ jose.PS256,
+ jose.PS384,
+ jose.PS512,
+ jose.EdDSA,
+}
diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go
index b1e3f7e3ff5..6a846ece95b 100644
--- a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go
+++ b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go
@@ -13,7 +13,7 @@ import (
"sync"
"time"
- jose "github.com/go-jose/go-jose/v3"
+ jose "github.com/go-jose/go-jose/v4"
)
// StaticKeySet is a verifier that validates JWT against a static set of public keys.
@@ -25,7 +25,9 @@ type StaticKeySet struct {
// VerifySignature compares the signature against a static set of public keys.
func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
- jws, err := jose.ParseSigned(jwt)
+ // Algorithms are already checked by Verifier, so this parse method accepts
+ // any algorithm.
+ jws, err := jose.ParseSigned(jwt, allAlgs)
if err != nil {
return nil, fmt.Errorf("parsing jwt: %v", err)
}
@@ -62,16 +64,28 @@ func newRemoteKeySet(ctx context.Context, jwksURL string, now func() time.Time)
if now == nil {
now = time.Now
}
- return &RemoteKeySet{jwksURL: jwksURL, ctx: ctx, now: now}
+ return &RemoteKeySet{
+ jwksURL: jwksURL,
+ now: now,
+ // For historical reasons, this package uses contexts for configuration, not just
+ // cancellation. In hindsight, this was a bad idea.
+ //
+ // Attemps to reason about how cancels should work with background requests have
+ // largely lead to confusion. Use the context here as a config bag-of-values and
+ // ignore the cancel function.
+ ctx: context.WithoutCancel(ctx),
+ }
}
// RemoteKeySet is a KeySet implementation that validates JSON web tokens against
// a jwks_uri endpoint.
type RemoteKeySet struct {
jwksURL string
- ctx context.Context
now func() time.Time
+ // Used for configuration. Cancelation is ignored.
+ ctx context.Context
+
// guard all other fields
mu sync.RWMutex
@@ -127,8 +141,13 @@ var parsedJWTKey contextKey
func (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
jws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature)
if !ok {
+ // The algorithm values are already enforced by the Validator, which also sets
+ // the context value above to pre-parsed signature.
+ //
+ // Practically, this codepath isn't called in normal use of this package, but
+ // if it is, the algorithms have already been checked.
var err error
- jws, err = jose.ParseSigned(jwt)
+ jws, err = jose.ParseSigned(jwt, allAlgs)
if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
}
diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go b/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go
index b7db3c73429..f6a7ea8a580 100644
--- a/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go
+++ b/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go
@@ -79,7 +79,7 @@ func getClient(ctx context.Context) *http.Client {
// provider, err := oidc.NewProvider(ctx, discoveryBaseURL)
//
// This is insecure because validating the correct issuer is critical for multi-tenant
-// proivders. Any overrides here MUST be carefully reviewed.
+// providers. Any overrides here MUST be carefully reviewed.
func InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Context {
return context.WithValue(ctx, issuerURLKey, issuerURL)
}
@@ -154,40 +154,65 @@ var supportedAlgorithms = map[string]bool{
EdDSA: true,
}
-// ProviderConfig allows creating providers when discovery isn't supported. It's
-// generally easier to use NewProvider directly.
+// ProviderConfig allows direct creation of a [Provider] from metadata
+// configuration. This is intended for interop with providers that don't support
+// discovery, or host the JSON discovery document at an off-spec path.
+//
+// The ProviderConfig struct specifies JSON struct tags to support document
+// parsing.
+//
+// // Directly fetch the metadata document.
+// resp, err := http.Get("https://login.example.com/custom-metadata-path")
+// if err != nil {
+// // ...
+// }
+// defer resp.Body.Close()
+//
+// // Parse config from JSON metadata.
+// config := &oidc.ProviderConfig{}
+// if err := json.NewDecoder(resp.Body).Decode(config); err != nil {
+// // ...
+// }
+// p := config.NewProvider(context.Background())
+//
+// For providers that implement discovery, use [NewProvider] instead.
+//
+// See: https://openid.net/specs/openid-connect-discovery-1_0.html
type ProviderConfig struct {
// IssuerURL is the identity of the provider, and the string it uses to sign
// ID tokens with. For example "https://accounts.google.com". This value MUST
// match ID tokens exactly.
- IssuerURL string
+ IssuerURL string `json:"issuer"`
// AuthURL is the endpoint used by the provider to support the OAuth 2.0
// authorization endpoint.
- AuthURL string
+ AuthURL string `json:"authorization_endpoint"`
// TokenURL is the endpoint used by the provider to support the OAuth 2.0
// token endpoint.
- TokenURL string
+ TokenURL string `json:"token_endpoint"`
// DeviceAuthURL is the endpoint used by the provider to support the OAuth 2.0
// device authorization endpoint.
- DeviceAuthURL string
+ DeviceAuthURL string `json:"device_authorization_endpoint"`
// UserInfoURL is the endpoint used by the provider to support the OpenID
// Connect UserInfo flow.
//
// https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
- UserInfoURL string
+ UserInfoURL string `json:"userinfo_endpoint"`
// JWKSURL is the endpoint used by the provider to advertise public keys to
// verify issued ID tokens. This endpoint is polled as new keys are made
// available.
- JWKSURL string
+ JWKSURL string `json:"jwks_uri"`
// Algorithms, if provided, indicate a list of JWT algorithms allowed to sign
// ID tokens. If not provided, this defaults to the algorithms advertised by
// the JWK endpoint, then the set of algorithms supported by this package.
- Algorithms []string
+ Algorithms []string `json:"id_token_signing_alg_values_supported"`
}
// NewProvider initializes a provider from a set of endpoints, rather than
// through discovery.
+//
+// The provided context is only used for [http.Client] configuration through
+// [ClientContext], not cancelation.
func (p *ProviderConfig) NewProvider(ctx context.Context) *Provider {
return &Provider{
issuer: p.IssuerURL,
@@ -202,9 +227,14 @@ func (p *ProviderConfig) NewProvider(ctx context.Context) *Provider {
}
// NewProvider uses the OpenID Connect discovery mechanism to construct a Provider.
-//
// The issuer is the URL identifier for the service. For example: "https://accounts.google.com"
// or "https://login.salesforce.com".
+//
+// OpenID Connect providers that don't implement discovery or host the discovery
+// document at a non-spec complaint path (such as requiring a URL parameter),
+// should use [ProviderConfig] instead.
+//
+// See: https://openid.net/specs/openid-connect-discovery-1_0.html
func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
wellKnown := strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration"
req, err := http.NewRequest("GET", wellKnown, nil)
diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go b/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go
index 0bca49a8992..52b27b746a2 100644
--- a/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go
+++ b/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go
@@ -12,7 +12,7 @@ import (
"strings"
"time"
- jose "github.com/go-jose/go-jose/v3"
+ jose "github.com/go-jose/go-jose/v4"
"golang.org/x/oauth2"
)
@@ -120,8 +120,8 @@ type Config struct {
}
// VerifierContext returns an IDTokenVerifier that uses the provider's key set to
-// verify JWTs. As opposed to Verifier, the context is used for all requests to
-// the upstream JWKs endpoint.
+// verify JWTs. As opposed to Verifier, the context is used to configure requests
+// to the upstream JWKs endpoint. The provided context's cancellation is ignored.
func (p *Provider) VerifierContext(ctx context.Context, config *Config) *IDTokenVerifier {
return p.newVerifier(NewRemoteKeySet(ctx, p.jwksURL), config)
}
@@ -310,7 +310,16 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
return t, nil
}
- jws, err := jose.ParseSigned(rawIDToken)
+ var supportedSigAlgs []jose.SignatureAlgorithm
+ for _, alg := range v.config.SupportedSigningAlgs {
+ supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg))
+ }
+ if len(supportedSigAlgs) == 0 {
+ // If no algorithms were specified by both the config and discovery, default
+ // to the one mandatory algorithm "RS256".
+ supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256}
+ }
+ jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs)
if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
}
@@ -322,17 +331,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
default:
return nil, fmt.Errorf("oidc: multiple signatures on id token not supported")
}
-
sig := jws.Signatures[0]
- supportedSigAlgs := v.config.SupportedSigningAlgs
- if len(supportedSigAlgs) == 0 {
- supportedSigAlgs = []string{RS256}
- }
-
- if !contains(supportedSigAlgs, sig.Header.Algorithm) {
- return nil, fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", supportedSigAlgs, sig.Header.Algorithm)
- }
-
t.sigAlgorithm = sig.Header.Algorithm
ctx = context.WithValue(ctx, parsedJWTKey, jws)
diff --git a/vendor/github.com/eclipse/paho.golang/LICENSE b/vendor/github.com/eclipse/paho.golang/LICENSE
index d3087e4c540..f55c3953911 100644
--- a/vendor/github.com/eclipse/paho.golang/LICENSE
+++ b/vendor/github.com/eclipse/paho.golang/LICENSE
@@ -1,3 +1,20 @@
+Eclipse Public License - v 2.0 (EPL-2.0)
+
+This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v2.0
+and Eclipse Distribution License v1.0 which accompany this distribution.
+
+The Eclipse Public License is available at
+ https://www.eclipse.org/legal/epl-2.0/
+and the Eclipse Distribution License is available at
+ http://www.eclipse.org/org/documents/edl-v10.php.
+
+For an explanation of what dual-licensing means to you, see:
+https://www.eclipse.org/legal/eplfaq.php#DUALLIC
+
+****
+The epl-2.0 is copied below in order to pass the pkg.go.dev license check (https://pkg.go.dev/license-policy).
+****
Eclipse Public License - v 2.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
@@ -261,8 +278,8 @@ No third-party beneficiary rights are created under this Agreement.
Exhibit A - Form of Secondary Licenses Notice
-"This Source Code may also be made available under the following
-Secondary Licenses when the conditions for such availability set forth
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
version(s), and exceptions or additional permissions here}."
diff --git a/vendor/github.com/eclipse/paho.golang/packets/auth.go b/vendor/github.com/eclipse/paho.golang/packets/auth.go
index 56237e00c43..c97446f6ad7 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/auth.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/auth.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/connack.go b/vendor/github.com/eclipse/paho.golang/packets/connack.go
index aa171eaba83..493aa29e021 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/connack.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/connack.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -43,7 +58,7 @@ func (c *Connack) String() string {
return fmt.Sprintf("CONNACK: ReasonCode:%d SessionPresent:%t\nProperties:\n%s", c.ReasonCode, c.SessionPresent, c.Properties)
}
-//Unpack is the implementation of the interface required function for a packet
+// Unpack is the implementation of the interface required function for a packet
func (c *Connack) Unpack(r *bytes.Buffer) error {
connackFlags, err := r.ReadByte()
if err != nil {
diff --git a/vendor/github.com/eclipse/paho.golang/packets/connect.go b/vendor/github.com/eclipse/paho.golang/packets/connect.go
index 31340f6bdb9..2394e7d0118 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/connect.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/connect.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -85,7 +100,7 @@ func (c *Connect) UnpackFlags(b byte) {
c.UsernameFlag = 1&(b>>7) > 0
}
-//Unpack is the implementation of the interface required function for a packet
+// Unpack is the implementation of the interface required function for a packet
func (c *Connect) Unpack(r *bytes.Buffer) error {
var err error
diff --git a/vendor/github.com/eclipse/paho.golang/packets/disconnect.go b/vendor/github.com/eclipse/paho.golang/packets/disconnect.go
index 9180207a610..693abfd3eea 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/disconnect.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/disconnect.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/packets.go b/vendor/github.com/eclipse/paho.golang/packets/packets.go
index 4f023e015e7..48dc5462e22 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/packets.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/packets.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/pingreq.go b/vendor/github.com/eclipse/paho.golang/packets/pingreq.go
index 27d39ee324e..b6a4c7fa06f 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/pingreq.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/pingreq.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/pingresp.go b/vendor/github.com/eclipse/paho.golang/packets/pingresp.go
index fcf421a763f..f5210f187ad 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/pingresp.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/pingresp.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/properties.go b/vendor/github.com/eclipse/paho.golang/packets/properties.go
index 5a74e0561a1..9ddc9bdc73b 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/properties.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/properties.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -285,11 +300,6 @@ func (i *Properties) Pack(p byte) []byte {
writeUint16(*i.TopicAliasMaximum, &b)
}
- if i.MaximumQOS != nil {
- b.WriteByte(PropMaximumQOS)
- b.WriteByte(*i.MaximumQOS)
- }
-
if i.MaximumPacketSize != nil {
b.WriteByte(PropMaximumPacketSize)
writeUint32(*i.MaximumPacketSize, &b)
@@ -297,6 +307,11 @@ func (i *Properties) Pack(p byte) []byte {
}
if p == CONNACK {
+ if i.MaximumQOS != nil {
+ b.WriteByte(PropMaximumQOS)
+ b.WriteByte(*i.MaximumQOS)
+ }
+
if i.AssignedClientID != "" {
b.WriteByte(PropAssignedClientID)
writeString(i.AssignedClientID, &b)
@@ -453,11 +468,6 @@ func (i *Properties) PackBuf(p byte) *bytes.Buffer {
writeUint16(*i.TopicAliasMaximum, &b)
}
- if i.MaximumQOS != nil {
- b.WriteByte(PropMaximumQOS)
- b.WriteByte(*i.MaximumQOS)
- }
-
if i.MaximumPacketSize != nil {
b.WriteByte(PropMaximumPacketSize)
writeUint32(*i.MaximumPacketSize, &b)
@@ -465,6 +475,11 @@ func (i *Properties) PackBuf(p byte) *bytes.Buffer {
}
if p == CONNACK {
+ if i.MaximumQOS != nil {
+ b.WriteByte(PropMaximumQOS)
+ b.WriteByte(*i.MaximumQOS)
+ }
+
if i.AssignedClientID != "" {
b.WriteByte(PropAssignedClientID)
writeString(i.AssignedClientID, &b)
@@ -792,7 +807,7 @@ var ValidProperties = map[byte]map[byte]struct{}{
PropReasonString: {CONNACK: {}, PUBACK: {}, PUBREC: {}, PUBREL: {}, PUBCOMP: {}, SUBACK: {}, UNSUBACK: {}, DISCONNECT: {}, AUTH: {}},
PropReceiveMaximum: {CONNECT: {}, CONNACK: {}},
PropTopicAliasMaximum: {CONNECT: {}, CONNACK: {}},
- PropMaximumQOS: {CONNECT: {}, CONNACK: {}},
+ PropMaximumQOS: {CONNACK: {}},
PropMaximumPacketSize: {CONNECT: {}, CONNACK: {}},
PropUser: {CONNECT: {}, CONNACK: {}, PUBLISH: {}, PUBACK: {}, PUBREC: {}, PUBREL: {}, PUBCOMP: {}, SUBSCRIBE: {}, UNSUBSCRIBE: {}, SUBACK: {}, UNSUBACK: {}, DISCONNECT: {}, AUTH: {}},
}
diff --git a/vendor/github.com/eclipse/paho.golang/packets/puback.go b/vendor/github.com/eclipse/paho.golang/packets/puback.go
index 67f404ce6a6..57e6f34f7da 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/puback.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/puback.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -41,7 +56,7 @@ func (p *Puback) String() string {
return b.String()
}
-//Unpack is the implementation of the interface required function for a packet
+// Unpack is the implementation of the interface required function for a packet
func (p *Puback) Unpack(r *bytes.Buffer) error {
var err error
success := r.Len() == 2
diff --git a/vendor/github.com/eclipse/paho.golang/packets/pubcomp.go b/vendor/github.com/eclipse/paho.golang/packets/pubcomp.go
index 1cdfe61e98b..b193be03752 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/pubcomp.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/pubcomp.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -34,7 +49,7 @@ func (p *Pubcomp) String() string {
return b.String()
}
-//Unpack is the implementation of the interface required function for a packet
+// Unpack is the implementation of the interface required function for a packet
func (p *Pubcomp) Unpack(r *bytes.Buffer) error {
var err error
success := r.Len() == 2
diff --git a/vendor/github.com/eclipse/paho.golang/packets/publish.go b/vendor/github.com/eclipse/paho.golang/packets/publish.go
index 24edb588b23..150ea3417b0 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/publish.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/publish.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/pubrec.go b/vendor/github.com/eclipse/paho.golang/packets/pubrec.go
index 7bd30451099..f1627968b5d 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/pubrec.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/pubrec.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/pubrel.go b/vendor/github.com/eclipse/paho.golang/packets/pubrel.go
index 27c48c24042..1f8ea9447de 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/pubrel.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/pubrel.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -28,7 +43,7 @@ func (p *Pubrel) String() string {
return b.String()
}
-//Unpack is the implementation of the interface required function for a packet
+// Unpack is the implementation of the interface required function for a packet
func (p *Pubrel) Unpack(r *bytes.Buffer) error {
var err error
success := r.Len() == 2
diff --git a/vendor/github.com/eclipse/paho.golang/packets/suback.go b/vendor/github.com/eclipse/paho.golang/packets/suback.go
index 2503aaf1aec..be5eaaa2b06 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/suback.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/suback.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
@@ -34,7 +49,7 @@ const (
SubackWildcardsubscriptionsnotsupported = 0xA2
)
-//Unpack is the implementation of the interface required function for a packet
+// Unpack is the implementation of the interface required function for a packet
func (s *Suback) Unpack(r *bytes.Buffer) error {
var err error
s.PacketID, err = readUint16(r)
diff --git a/vendor/github.com/eclipse/paho.golang/packets/subscribe.go b/vendor/github.com/eclipse/paho.golang/packets/subscribe.go
index 2abccbbd674..c179e4eb902 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/subscribe.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/subscribe.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/unsuback.go b/vendor/github.com/eclipse/paho.golang/packets/unsuback.go
index ba5164b9f19..264ebce1d38 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/unsuback.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/unsuback.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/packets/unsubscribe.go b/vendor/github.com/eclipse/paho.golang/packets/unsubscribe.go
index 090d7ca7209..4af1bc5fd71 100644
--- a/vendor/github.com/eclipse/paho.golang/packets/unsubscribe.go
+++ b/vendor/github.com/eclipse/paho.golang/packets/unsubscribe.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package packets
import (
diff --git a/vendor/github.com/eclipse/paho.golang/paho/acks_tracker.go b/vendor/github.com/eclipse/paho.golang/paho/acks_tracker.go
index 47f11cb67f4..d4077b0eef4 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/acks_tracker.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/acks_tracker.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
diff --git a/vendor/github.com/eclipse/paho.golang/paho/auth.go b/vendor/github.com/eclipse/paho.golang/paho/auth.go
index 7d3a3c97233..3ab6496566c 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/auth.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/auth.go
@@ -1,8 +1,23 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
// Auther is the interface for something that implements the extended authentication
// flows in MQTT v5
type Auther interface {
- Authenticate(*Auth) *Auth
- Authenticated()
+ Authenticate(*Auth) *Auth // Authenticate will be called when an AUTH packet is received.
+ Authenticated() // Authenticated will be called when CONNACK is received
}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/client.go b/vendor/github.com/eclipse/paho.golang/paho/client.go
index 76a98722933..d4bea750d0d 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/client.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/client.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
@@ -11,7 +26,9 @@ import (
"time"
"github.com/eclipse/paho.golang/packets"
- "golang.org/x/sync/semaphore"
+ "github.com/eclipse/paho.golang/paho/log"
+ "github.com/eclipse/paho.golang/paho/session"
+ "github.com/eclipse/paho.golang/paho/session/state"
)
type MQTTVersion byte
@@ -25,10 +42,22 @@ const defaultSendAckInterval = 50 * time.Millisecond
var (
ErrManualAcknowledgmentDisabled = errors.New("manual acknowledgments disabled")
+ ErrNetworkErrorAfterStored = errors.New("error after packet added to state") // Could not send packet but its stored (and response will be sent on chan at some point in the future)
+ ErrConnectionLost = errors.New("connection lost after request transmitted") // We don't know whether the server received the request or not
+
+ ErrInvalidArguments = errors.New("invalid argument") // If included (errors.Join) in an error, there is a problem with the arguments passed. Retrying on the same connection with the same arguments will not succeed.
)
type (
- // ClientConfig are the user configurable options for the client, an
+ PublishReceived struct {
+ Packet *Publish
+ Client *Client // The Client that received the message (note that the connection may have been lost post-receipt)
+
+ AlreadyHandled bool // Set to true if a previous callback has returned true (indicating some action has already been taken re the message)
+ Errs []error // Errors returned by previous handlers (if any).
+ }
+
+ // ClientConfig are the user-configurable options for the client, an
// instance of this struct is passed into NewClient(), not all options
// are required to be set, defaults are provided for Persistence, MIDs,
// PingHandler, PacketTimeout and Router.
@@ -38,12 +67,27 @@ type (
// BEWARE that most wrapped net.Conn implementations like tls.Conn are
// not thread safe for writing. To fix, use packets.NewThreadSafeConn
// wrapper or extend the custom net.Conn struct with sync.Locker.
- Conn net.Conn
- MIDs MIDService
+ Conn net.Conn
+
+ Session session.SessionManager
+ autoCloseSession bool
+
AuthHandler Auther
PingHandler Pinger
- Router Router
- Persistence Persistence
+ defaultPinger bool
+
+ // Router - new inbound messages will be passed to the `Route(*packets.Publish)` function.
+ //
+ // Depreciated: If a router is provided, it will now be added to the end of the OnPublishReceived
+ // slice (which provides a more flexible approach to handling incoming messages).
+ Router Router
+
+ // OnPublishReceived provides a slice of callbacks; additional handlers may be added after the client has been
+ // created via the AddOnPublishReceived function (Client holds a copy of the slice; OnPublishReceived will not change).
+ // When a `PUBLISH` is received, the callbacks will be called in order. If a callback processes the message,
+ // then it should return true. This boolean, and any errors, will be passed to subsequent handlers.
+ OnPublishReceived []func(PublishReceived) (bool, error)
+
PacketTimeout time.Duration
// OnServerDisconnect is called only when a packets.DISCONNECT is received from server
OnServerDisconnect func(*Disconnect)
@@ -68,20 +112,30 @@ type (
}
// Client is the struct representing an MQTT client
Client struct {
- mu sync.Mutex
- ClientConfig
- // raCtx is used for handling the MQTTv5 authentication exchange.
- raCtx *CPContext
- stop chan struct{}
+ config ClientConfig
+
+ // OnPublishReceived copy of OnPublishReceived from ClientConfig (perhaps with added callback form Router)
+ onPublishReceived []func(PublishReceived) (bool, error)
+ onPublishReceivedTracker []int // Used to track positions in above
+ onPublishReceivedMu sync.Mutex
+
+ // authResponse is used for handling the MQTTv5 authentication exchange (MUST be buffered)
+ authResponse chan<- packets.ControlPacket
+ authResponseMu sync.Mutex // protects the above
+
+ cancelFunc func()
+
+ connectCalled bool // if true `Connect` has been called and a connection is being managed
+ connectCalledMu sync.Mutex // protects the above
+
+ done <-chan struct{} // closed when shutdown complete (only valid after Connect returns nil error)
publishPackets chan *packets.Publish
acksTracker acksTracker
workers sync.WaitGroup
serverProps CommsProperties
clientProps CommsProperties
- serverInflight *semaphore.Weighted
- clientInflight *semaphore.Weighted
- debug Logger
- errors Logger
+ debug log.Logger
+ errors log.Logger
}
// CommsProperties is a struct of the communication properties that may
@@ -97,11 +151,6 @@ type (
SubIDAvailable bool
SharedSubAvailable bool
}
-
- caContext struct {
- Context context.Context
- Return chan *packets.Connack
- }
)
// NewClient is used to create a new default instance of an MQTT client.
@@ -129,30 +178,40 @@ func NewClient(conf ClientConfig) *Client {
MaximumPacketSize: 0,
TopicAliasMaximum: 0,
},
- ClientConfig: conf,
- errors: NOOPLogger{},
- debug: NOOPLogger{},
+ config: conf,
+ onPublishReceived: conf.OnPublishReceived,
+ done: make(chan struct{}),
+ errors: log.NOOPLogger{},
+ debug: log.NOOPLogger{},
}
- if c.Persistence == nil {
- c.Persistence = &noopPersistence{}
+ if c.config.Session == nil {
+ c.config.Session = state.NewInMemory()
+ c.config.autoCloseSession = true // We created `Session`, so need to close it when done (so handlers all return)
}
- if c.MIDs == nil {
- c.MIDs = &MIDs{index: make([]*CPContext, int(midMax))}
+ if c.config.PacketTimeout == 0 {
+ c.config.PacketTimeout = 10 * time.Second
}
- if c.PacketTimeout == 0 {
- c.PacketTimeout = 10 * time.Second
+
+ if c.config.Router == nil && len(c.onPublishReceived) == 0 {
+ c.config.Router = NewStandardRouter() // Maintain backwards compatibility (for now!)
}
- if c.Router == nil {
- c.Router = NewStandardRouter()
+ if c.config.Router != nil {
+ r := c.config.Router
+ c.onPublishReceived = append(c.onPublishReceived,
+ func(p PublishReceived) (bool, error) {
+ r.Route(p.Packet.Packet())
+ return false, nil
+ })
}
- if c.PingHandler == nil {
- c.PingHandler = DefaultPingerWithCustomFailHandler(func(e error) {
- go c.error(e)
- })
+ c.onPublishReceivedTracker = make([]int, len(c.onPublishReceived)) // Must have the same number of elements as onPublishReceived
+
+ if c.config.PingHandler == nil {
+ c.config.PingHandler = NewDefaultPinger()
+ c.config.defaultPinger = true
}
- if c.OnClientError == nil {
- c.OnClientError = func(e error) {}
+ if c.config.OnClientError == nil {
+ c.config.OnClientError = func(e error) {}
}
return c
@@ -162,23 +221,38 @@ func NewClient(conf ClientConfig) *Client {
// the Client instance already has a working network connection.
// The function takes a pre-prepared Connect packet, and uses that to
// establish an MQTT connection. Assuming the connection completes
-// successfully the rest of the client is initiated and the Connack
-// returned. Otherwise the failure Connack (if there is one) is returned
+// successfully, the rest of the client is initiated and the Connack
+// returned. Otherwise, the failure Connack (if there is one) is returned
// along with an error indicating the reason for the failure to connect.
func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
- if c.Conn == nil {
+ if c.config.Conn == nil {
return nil, fmt.Errorf("client connection is nil")
}
+ // The connection is in c.config.Conn which is inaccessible to the user.
+ // The end result of `Connect` (possibly some time after it returns) will be to close the connection so calling
+ // Connect twice is invalid.
+ c.connectCalledMu.Lock()
+ if c.connectCalled {
+ c.connectCalledMu.Unlock()
+ return nil, fmt.Errorf("connect must only be called once")
+ }
+ c.connectCalled = true
+ c.connectCalledMu.Unlock()
+
+ // The passed in ctx applies to the connection process only. clientCtx applies to Client (signals that the
+ // client should shut down).
+ clientCtx, cancelFunc := context.WithCancel(context.Background())
+ done := make(chan struct{})
cleanup := func() {
- close(c.stop)
+ cancelFunc()
close(c.publishPackets)
- _ = c.Conn.Close()
- c.mu.Unlock()
+ _ = c.config.Conn.Close()
+ close(done)
}
- c.mu.Lock()
- c.stop = make(chan struct{})
+ c.cancelFunc = cancelFunc
+ c.done = done
var publishPacketsSize uint16 = math.MaxUint16
if cp.Properties != nil && cp.Properties.ReceiveMaximum != nil {
@@ -187,14 +261,11 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
c.publishPackets = make(chan *packets.Publish, publishPacketsSize)
keepalive := cp.KeepAlive
- c.ClientID = cp.ClientID
+ c.config.ClientID = cp.ClientID
if cp.Properties != nil {
if cp.Properties.MaximumPacketSize != nil {
c.clientProps.MaximumPacketSize = *cp.Properties.MaximumPacketSize
}
- if cp.Properties.MaximumQOS != nil {
- c.clientProps.MaximumQoS = *cp.Properties.MaximumQOS
- }
if cp.Properties.ReceiveMaximum != nil {
c.clientProps.ReceiveMaximum = *cp.Properties.ReceiveMaximum
}
@@ -204,7 +275,7 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
}
c.debug.Println("connecting")
- connCtx, cf := context.WithTimeout(ctx, c.PacketTimeout)
+ connCtx, cf := context.WithTimeout(ctx, c.config.PacketTimeout)
defer cf()
ccp := cp.Packet()
@@ -212,14 +283,14 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
ccp.ProtocolVersion = 5
c.debug.Println("sending CONNECT")
- if _, err := ccp.WriteTo(c.Conn); err != nil {
+ if _, err := ccp.WriteTo(c.config.Conn); err != nil {
cleanup()
return nil, err
}
c.debug.Println("waiting for CONNACK/AUTH")
var (
- caPacket *packets.Connack
+ caPacket *packets.Connack
// We use buffered channels to prevent goroutine leak. The Details are below.
// - c.expectConnack waits to send data to caPacketCh or caPacketErr.
// - If connCtx is cancelled (done) before c.expectConnack finishes to send data to either "unbuffered" channel,
@@ -230,11 +301,10 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
go c.expectConnack(caPacketCh, caPacketErr)
select {
case <-connCtx.Done():
- if ctxErr := connCtx.Err(); ctxErr != nil {
- c.debug.Println(fmt.Sprintf("terminated due to context: %v", ctxErr))
- }
+ ctxErr := connCtx.Err()
+ c.debug.Println(fmt.Sprintf("terminated due to context waiting for CONNACK: %v", ctxErr))
cleanup()
- return nil, connCtx.Err()
+ return nil, ctxErr
case err := <-caPacketErr:
c.debug.Println(err)
cleanup()
@@ -254,15 +324,21 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
return ca, fmt.Errorf("failed to connect to server: %s", reason)
}
- // no more possible calls to cleanup(), defer an unlock
- defer c.mu.Unlock()
+ if err := c.config.Session.ConAckReceived(c.config.Conn, ccp, caPacket); err != nil {
+ cleanup()
+ return ca, fmt.Errorf("session error: %w", err)
+ }
+
+ // the connection is now fully up and a nil error will be returned.
+ // cleanup() must not be called past this point and will be handled by `shutdown`
+ context.AfterFunc(clientCtx, func() { c.shutdown(done) })
if ca.Properties != nil {
if ca.Properties.ServerKeepAlive != nil {
keepalive = *ca.Properties.ServerKeepAlive
}
if ca.Properties.AssignedClientID != "" {
- c.ClientID = ca.Properties.AssignedClientID
+ c.config.ClientID = ca.Properties.AssignedClientID
}
if ca.Properties.ReceiveMaximum != nil {
c.serverProps.ReceiveMaximum = *ca.Properties.ReceiveMaximum
@@ -282,15 +358,14 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
c.serverProps.SharedSubAvailable = ca.Properties.SharedSubAvailable
}
- c.serverInflight = semaphore.NewWeighted(int64(c.serverProps.ReceiveMaximum))
- c.clientInflight = semaphore.NewWeighted(int64(c.clientProps.ReceiveMaximum))
-
c.debug.Println("received CONNACK, starting PingHandler")
c.workers.Add(1)
go func() {
defer c.workers.Done()
defer c.debug.Println("returning from ping handler worker")
- c.PingHandler.Start(c.Conn, time.Duration(keepalive)*time.Second)
+ if err := c.config.PingHandler.Run(clientCtx, c.config.Conn, keepalive); err != nil {
+ go c.error(fmt.Errorf("ping handler error: %w", err))
+ }
}()
c.debug.Println("starting publish packets loop")
@@ -298,6 +373,8 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
go func() {
defer c.workers.Done()
defer c.debug.Println("returning from publish packets loop worker")
+ // exits when `c.publishPackets` is closed (`c.incoming()` closes this). This is important because
+ // messages may be passed for processing after `c.stop` has been closed.
c.routePublishPackets()
}()
@@ -306,16 +383,16 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
go func() {
defer c.workers.Done()
defer c.debug.Println("returning from incoming worker")
- c.incoming()
+ c.incoming(clientCtx)
}()
- if c.EnableManualAcknowledgment {
+ if c.config.EnableManualAcknowledgment {
c.debug.Println("starting acking routine")
c.acksTracker.reset()
sendAcksInterval := defaultSendAckInterval
- if c.SendAcksInterval > 0 {
- sendAcksInterval = c.SendAcksInterval
+ if c.config.SendAcksInterval > 0 {
+ sendAcksInterval = c.config.SendAcksInterval
}
c.workers.Add(1)
@@ -325,7 +402,7 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
t := time.NewTicker(sendAcksInterval)
for {
select {
- case <-c.stop:
+ case <-clientCtx.Done():
return
case <-t.C:
c.acksTracker.flush(func(pbs []*packets.Publish) {
@@ -341,8 +418,17 @@ func (c *Client) Connect(ctx context.Context, cp *Connect) (*Connack, error) {
return ca, nil
}
+// Done returns a channel that will be closed when Client has shutdown. Only valid after Connect has returned a
+// nil error.
+func (c *Client) Done() <-chan struct{} {
+ return c.done
+}
+
+// Ack transmits an acknowledgement of the `Publish` packet.
+// WARNING: Calling Ack after the connection is closed may have unpredictable results (particularly if the sessionState
+// is being accessed by a new connection). See issue #160.
func (c *Client) Ack(pb *Publish) error {
- if !c.EnableManualAcknowledgment {
+ if !c.config.EnableManualAcknowledgment {
return ErrManualAcknowledgmentDisabled
}
if pb.QoS == 0 {
@@ -351,52 +437,45 @@ func (c *Client) Ack(pb *Publish) error {
return c.acksTracker.markAsAcked(pb.Packet())
}
+// ack acknowledges a message (note: called by acksTracker to ensure these are sent in order)
func (c *Client) ack(pb *packets.Publish) {
- switch pb.QoS {
- case 1:
- pa := packets.Puback{
- Properties: &packets.Properties{},
- PacketID: pb.PacketID,
- }
- c.debug.Println("sending PUBACK")
- _, err := pa.WriteTo(c.Conn)
- if err != nil {
- c.errors.Printf("failed to send PUBACK for %d: %s", pb.PacketID, err)
- }
- case 2:
- pr := packets.Pubrec{
- Properties: &packets.Properties{},
- PacketID: pb.PacketID,
- }
- c.debug.Printf("sending PUBREC")
- _, err := pr.WriteTo(c.Conn)
- if err != nil {
- c.errors.Printf("failed to send PUBREC for %d: %s", pb.PacketID, err)
- }
- }
+ c.config.Session.Ack(pb)
}
+// routePublishPackets listens on c.publishPackets and passes received messages to the handlers
+// terminates when publishPackets closed
func (c *Client) routePublishPackets() {
- for {
- select {
- case <-c.stop:
- return
- case pb, open := <-c.publishPackets:
- if !open {
- return
- }
+ for pb := range c.publishPackets {
+ // Copy onPublishReceived so lock is only held briefly
+ c.onPublishReceivedMu.Lock()
+ handlers := make([]func(PublishReceived) (bool, error), len(c.onPublishReceived))
+ for i := range c.onPublishReceived {
+ handlers[i] = c.onPublishReceived[i]
+ }
+ c.onPublishReceivedMu.Unlock()
- if !c.ClientConfig.EnableManualAcknowledgment {
- c.Router.Route(pb)
- c.ack(pb)
- continue
- }
+ if c.config.EnableManualAcknowledgment && pb.QoS != 0 {
+ c.acksTracker.add(pb)
+ }
- if pb.QoS != 0 {
- c.acksTracker.add(pb)
+ var handled bool
+ var errs []error
+ pkt := PublishFromPacketPublish(pb)
+ for _, h := range handlers {
+ ha, err := h(PublishReceived{
+ Packet: pkt,
+ Client: c,
+ AlreadyHandled: handled,
+ Errs: errs,
+ })
+ if ha {
+ handled = true
}
+ errs = append(errs, err)
+ }
- c.Router.Route(pb)
+ if !c.config.EnableManualAcknowledgment {
+ c.ack(pb)
}
}
}
@@ -406,21 +485,24 @@ func (c *Client) routePublishPackets() {
// from Connect(), it exits when it receives a server initiated
// Disconnect, the Stop channel is closed or there is an error reading
// a packet from the network connection
-func (c *Client) incoming() {
+// Closes `c.publishPackets` when done (should be the only thing sending on this channel)
+func (c *Client) incoming(ctx context.Context) {
defer c.debug.Println("client stopping, incoming stopping")
+ defer close(c.publishPackets)
+
for {
select {
- case <-c.stop:
+ case <-ctx.Done():
return
default:
- recv, err := packets.ReadPacket(c.Conn)
+ recv, err := packets.ReadPacket(c.config.Conn)
if err != nil {
go c.error(err)
return
}
switch recv.Type {
case packets.CONNACK:
- c.debug.Println("received CONNACK")
+ c.debug.Println("received CONNACK (unexpected)")
go c.error(fmt.Errorf("received unexpected CONNACK"))
return
case packets.AUTH:
@@ -428,93 +510,55 @@ func (c *Client) incoming() {
ap := recv.Content.(*packets.Auth)
switch ap.ReasonCode {
case packets.AuthSuccess:
- if c.AuthHandler != nil {
- go c.AuthHandler.Authenticated()
+ if c.config.AuthHandler != nil {
+ go c.config.AuthHandler.Authenticated()
}
- if c.raCtx != nil {
- c.raCtx.Return <- *recv
+ c.authResponseMu.Lock()
+ if c.authResponse != nil {
+ select { // authResponse must be buffered, and we should only receive 1 AUTH packet a time
+ case c.authResponse <- *recv:
+ default:
+ }
}
+ c.authResponseMu.Unlock()
case packets.AuthContinueAuthentication:
- if c.AuthHandler != nil {
- if _, err := c.AuthHandler.Authenticate(AuthFromPacketAuth(ap)).Packet().WriteTo(c.Conn); err != nil {
+ if c.config.AuthHandler != nil {
+ if _, err := c.config.AuthHandler.Authenticate(AuthFromPacketAuth(ap)).Packet().WriteTo(c.config.Conn); err != nil {
go c.error(err)
return
}
+ c.config.PingHandler.PacketSent()
}
}
case packets.PUBLISH:
pb := recv.Content.(*packets.Publish)
- c.debug.Printf("received QoS%d PUBLISH", pb.QoS)
- c.mu.Lock()
- select {
- case <-c.stop:
- c.mu.Unlock()
- return
- default:
- c.publishPackets <- pb
- c.mu.Unlock()
- }
- case packets.PUBACK, packets.PUBCOMP, packets.SUBACK, packets.UNSUBACK:
- c.debug.Printf("received %s packet with id %d", recv.PacketType(), recv.PacketID())
- if cpCtx := c.MIDs.Get(recv.PacketID()); cpCtx != nil {
- cpCtx.Return <- *recv
- } else {
- c.debug.Println("received a response for a message ID we don't know:", recv.PacketID())
- }
- case packets.PUBREC:
- c.debug.Println("received PUBREC for", recv.PacketID())
- if cpCtx := c.MIDs.Get(recv.PacketID()); cpCtx == nil {
- c.debug.Println("received a PUBREC for a message ID we don't know:", recv.PacketID())
- pl := packets.Pubrel{
- PacketID: recv.Content.(*packets.Pubrec).PacketID,
- ReasonCode: 0x92,
- }
- c.debug.Println("sending PUBREL for", pl.PacketID)
- _, err := pl.WriteTo(c.Conn)
- if err != nil {
- c.errors.Printf("failed to send PUBREL for %d: %s", pl.PacketID, err)
- }
- } else {
- pr := recv.Content.(*packets.Pubrec)
- if pr.ReasonCode >= 0x80 {
- //Received a failure code, shortcut and return
- cpCtx.Return <- *recv
- } else {
- pl := packets.Pubrel{
- PacketID: pr.PacketID,
- }
- c.debug.Println("sending PUBREL for", pl.PacketID)
- _, err := pl.WriteTo(c.Conn)
- if err != nil {
- c.errors.Printf("failed to send PUBREL for %d: %s", pl.PacketID, err)
- }
- }
- }
- case packets.PUBREL:
- c.debug.Println("received PUBREL for", recv.PacketID())
- //Auto respond to pubrels unless failure code
- pr := recv.Content.(*packets.Pubrel)
- if pr.ReasonCode >= 0x80 {
- //Received a failure code, continue
- continue
+ if pb.QoS > 0 { // QOS1 or 2 need to be recorded in session state
+ c.config.Session.PacketReceived(recv, c.publishPackets)
} else {
- pc := packets.Pubcomp{
- PacketID: pr.PacketID,
- }
- c.debug.Println("sending PUBCOMP for", pr.PacketID)
- _, err := pc.WriteTo(c.Conn)
- if err != nil {
- c.errors.Printf("failed to send PUBCOMP for %d: %s", pc.PacketID, err)
+ c.debug.Printf("received QoS%d PUBLISH", pb.QoS)
+ select {
+ case <-ctx.Done():
+ return
+ case c.publishPackets <- pb:
}
}
+ case packets.PUBACK, packets.PUBCOMP, packets.SUBACK, packets.UNSUBACK, packets.PUBREC, packets.PUBREL:
+ c.config.Session.PacketReceived(recv, c.publishPackets)
case packets.DISCONNECT:
+ pd := recv.Content.(*packets.Disconnect)
c.debug.Println("received DISCONNECT")
- if c.raCtx != nil {
- c.raCtx.Return <- *recv
+ c.authResponseMu.Lock()
+ if c.authResponse != nil {
+ select { // authResponse must be buffered, and we should only receive 1 AUTH packet a time
+ case c.authResponse <- *recv:
+ default:
+ }
}
+ c.authResponseMu.Unlock()
+ c.config.Session.ConnectionLost(pd) // this may impact the session state
go func() {
- if c.OnServerDisconnect != nil {
- go c.serverDisconnect(DisconnectFromPacketDisconnect(recv.Content.(*packets.Disconnect)))
+ if c.config.OnServerDisconnect != nil {
+ go c.serverDisconnect(DisconnectFromPacketDisconnect(pd))
} else {
go c.error(fmt.Errorf("server initiated disconnect"))
}
@@ -522,33 +566,37 @@ func (c *Client) incoming() {
return
case packets.PINGRESP:
c.debug.Println("received PINGRESP")
- c.PingHandler.PingResp()
+ c.config.PingHandler.PingResp()
}
}
}
}
+// close terminates the connection and waits for a clean shutdown
+// may be called multiple times (subsequent calls will wait on previously requested shutdown)
func (c *Client) close() {
- c.mu.Lock()
- defer c.mu.Unlock()
-
- select {
- case <-c.stop:
- //already shutting down, do nothing
- return
- default:
- }
-
- close(c.stop)
- close(c.publishPackets)
+ c.cancelFunc() // cleanup handled by AfterFunc defined in Connect
+ <-c.done
+}
- c.debug.Println("client stopped")
- c.PingHandler.Stop()
- c.debug.Println("ping stopped")
- _ = c.Conn.Close()
+// shutdown cleanly shutdown the client
+// This should only be called via the AfterFunc in `Connect` (shutdown must not be called more than once)
+func (c *Client) shutdown(done chan<- struct{}) {
+ c.debug.Println("client stop requested")
+ _ = c.config.Conn.Close()
c.debug.Println("conn closed")
c.acksTracker.reset()
c.debug.Println("acks tracker reset")
+ c.config.Session.ConnectionLost(nil)
+ if c.config.autoCloseSession {
+ if err := c.config.Session.Close(); err != nil {
+ c.errors.Println("error closing session", err)
+ }
+ }
+ c.debug.Println("session updated, waiting on workers")
+ c.workers.Wait()
+ c.debug.Println("workers done")
+ close(done)
}
// error is called to signify that an error situation has occurred, this
@@ -558,15 +606,13 @@ func (c *Client) close() {
func (c *Client) error(e error) {
c.debug.Println("error called:", e)
c.close()
- c.workers.Wait()
- go c.OnClientError(e)
+ go c.config.OnClientError(e)
}
func (c *Client) serverDisconnect(d *Disconnect) {
c.close()
- c.workers.Wait()
c.debug.Println("calling OnServerDisconnect")
- go c.OnServerDisconnect(d)
+ go c.config.OnServerDisconnect(d)
}
// Authenticate is used to initiate a reauthentication of credentials with the
@@ -576,39 +622,39 @@ func (c *Client) serverDisconnect(d *Disconnect) {
// is received.
func (c *Client) Authenticate(ctx context.Context, a *Auth) (*AuthResponse, error) {
c.debug.Println("client initiated reauthentication")
-
- c.mu.Lock()
- if c.raCtx != nil {
- c.mu.Unlock()
+ authResp := make(chan packets.ControlPacket, 1)
+ c.authResponseMu.Lock()
+ if c.authResponse != nil {
+ c.authResponseMu.Unlock()
return nil, fmt.Errorf("previous authentication is still in progress")
}
- c.raCtx = &CPContext{ctx, make(chan packets.ControlPacket, 1)}
- c.mu.Unlock()
+ c.authResponse = authResp
+ c.authResponseMu.Unlock()
defer func() {
- c.mu.Lock()
- c.raCtx = nil
- c.mu.Unlock()
+ c.authResponseMu.Lock()
+ c.authResponse = nil
+ c.authResponseMu.Unlock()
}()
c.debug.Println("sending AUTH")
- if _, err := a.Packet().WriteTo(c.Conn); err != nil {
+ if _, err := a.Packet().WriteTo(c.config.Conn); err != nil {
return nil, err
}
+ c.config.PingHandler.PacketSent()
var rp packets.ControlPacket
select {
case <-ctx.Done():
- if ctxErr := ctx.Err(); ctxErr != nil {
- c.debug.Println(fmt.Sprintf("terminated due to context: %v", ctxErr))
- return nil, ctxErr
- }
- case rp = <-c.raCtx.Return:
+ ctxErr := ctx.Err()
+ c.debug.Println(fmt.Sprintf("terminated due to context waiting for AUTH: %v", ctxErr))
+ return nil, ctxErr
+ case rp = <-authResp:
}
switch rp.Type {
case packets.AUTH:
- //If we've received one here it must be successful, the only way
- //to abort a reauth is a server initiated disconnect
+ // If we've received one here it must be successful, the only way
+ // to abort a reauth is a server initiated disconnect
return AuthResponseFromPacketAuth(rp.Content.(*packets.Auth)), nil
case packets.DISCONNECT:
return AuthResponseFromPacketDisconnect(rp.Content.(*packets.Disconnect)), nil
@@ -626,50 +672,52 @@ func (c *Client) Subscribe(ctx context.Context, s *Subscribe) (*Suback, error) {
for _, sub := range s.Subscriptions {
if strings.ContainsAny(sub.Topic, "#+") {
// Using a wildcard in a subscription when not supported
- return nil, fmt.Errorf("cannot subscribe to %s, server does not support wildcards", sub.Topic)
+ return nil, fmt.Errorf("%w: cannot subscribe to %s, server does not support wildcards", ErrInvalidArguments, sub.Topic)
}
}
}
if !c.serverProps.SubIDAvailable && s.Properties != nil && s.Properties.SubscriptionIdentifier != nil {
- return nil, fmt.Errorf("cannot send subscribe with subID set, server does not support subID")
+ return nil, fmt.Errorf("%w: cannot send subscribe with subID set, server does not support subID", ErrInvalidArguments)
}
if !c.serverProps.SharedSubAvailable {
for _, sub := range s.Subscriptions {
if strings.HasPrefix(sub.Topic, "$share") {
- return nil, fmt.Errorf("cannont subscribe to %s, server does not support shared subscriptions", sub.Topic)
+ return nil, fmt.Errorf("%w: cannont subscribe to %s, server does not support shared subscriptions", ErrInvalidArguments, sub.Topic)
}
}
}
c.debug.Printf("subscribing to %+v", s.Subscriptions)
- subCtx, cf := context.WithTimeout(ctx, c.PacketTimeout)
- defer cf()
- cpCtx := &CPContext{subCtx, make(chan packets.ControlPacket, 1)}
-
+ ret := make(chan packets.ControlPacket, 1)
sp := s.Packet()
-
- mid, err := c.MIDs.Request(cpCtx)
- if err != nil {
+ if err := c.config.Session.AddToSession(ctx, sp, ret); err != nil {
return nil, err
}
- defer c.MIDs.Free(mid)
- sp.PacketID = mid
- c.debug.Println("sending SUBSCRIBE")
- if _, err := sp.WriteTo(c.Conn); err != nil {
+ // From this point on the message is in store, and ret will receive something regardless of whether we succeed in
+ // writing the packet to the connection or not.
+ if _, err := sp.WriteTo(c.config.Conn); err != nil {
+ // The packet will remain in the session state until `Session` is notified of the disconnection.
return nil, err
}
+ c.config.PingHandler.PacketSent()
+
c.debug.Println("waiting for SUBACK")
+ subCtx, cf := context.WithTimeout(ctx, c.config.PacketTimeout)
+ defer cf()
var sap packets.ControlPacket
select {
case <-subCtx.Done():
- if ctxErr := subCtx.Err(); ctxErr != nil {
- c.debug.Println(fmt.Sprintf("terminated due to context: %v", ctxErr))
- return nil, ctxErr
- }
- case sap = <-cpCtx.Return:
+ ctxErr := subCtx.Err()
+ c.debug.Println(fmt.Sprintf("terminated due to context waiting for SUBACK: %v", ctxErr))
+ return nil, ctxErr
+ case sap = <-ret:
+ }
+
+ if sap.Type == 0 { // default ControlPacket indicates we are shutting down
+ return nil, ErrConnectionLost
}
if sap.Type != packets.SUBACK {
@@ -706,33 +754,35 @@ func (c *Client) Subscribe(ctx context.Context, s *Subscribe) (*Suback, error) {
// is returned from the function, along with any errors.
func (c *Client) Unsubscribe(ctx context.Context, u *Unsubscribe) (*Unsuback, error) {
c.debug.Printf("unsubscribing from %+v", u.Topics)
- unsubCtx, cf := context.WithTimeout(ctx, c.PacketTimeout)
- defer cf()
- cpCtx := &CPContext{unsubCtx, make(chan packets.ControlPacket, 1)}
-
+ ret := make(chan packets.ControlPacket, 1)
up := u.Packet()
-
- mid, err := c.MIDs.Request(cpCtx)
- if err != nil {
+ if err := c.config.Session.AddToSession(ctx, up, ret); err != nil {
return nil, err
}
- defer c.MIDs.Free(mid)
- up.PacketID = mid
- c.debug.Println("sending UNSUBSCRIBE")
- if _, err := up.WriteTo(c.Conn); err != nil {
+ // From this point on the message is in store, and ret will receive something regardless of whether we succeed in
+ // writing the packet to the connection or not
+ if _, err := up.WriteTo(c.config.Conn); err != nil {
+ // The packet will remain in the session state until `Session` is notified of the disconnection.
return nil, err
}
- c.debug.Println("waiting for UNSUBACK")
+ c.config.PingHandler.PacketSent()
+
+ unsubCtx, cf := context.WithTimeout(ctx, c.config.PacketTimeout)
+ defer cf()
var uap packets.ControlPacket
+ c.debug.Println("waiting for UNSUBACK")
select {
case <-unsubCtx.Done():
- if ctxErr := unsubCtx.Err(); ctxErr != nil {
- c.debug.Println(fmt.Sprintf("terminated due to context: %v", ctxErr))
- return nil, ctxErr
- }
- case uap = <-cpCtx.Return:
+ ctxErr := unsubCtx.Err()
+ c.debug.Println(fmt.Sprintf("terminated due to context waiting for UNSUBACK: %v", ctxErr))
+ return nil, ctxErr
+ case uap = <-ret:
+ }
+
+ if uap.Type == 0 { // default ControlPacket indicates we are shutting down
+ return nil, ErrConnectionLost
}
if uap.Type != packets.UNSUBACK {
@@ -764,27 +814,52 @@ func (c *Client) Unsubscribe(ctx context.Context, u *Unsubscribe) (*Unsuback, er
}
// Publish is used to send a publication to the MQTT server.
-// It is passed a pre-prepared Publish packet and blocks waiting for
-// the appropriate response, or for the timeout to fire.
-// Any response message is returned from the function, along with any errors.
+// It is passed a pre-prepared Publish packet and blocks waiting for the appropriate response, or for the timeout to fire.
+// A PublishResponse is returned, which is relevant for QOS1+. For QOS0, a default success response is returned.
+// Note that a message may still be delivered even if Publish times out (once the message is part of the session state,
+// it may even be delivered following an application restart).
+// Warning: Publish may outlive the connection when QOS1+ (managed in `session_state`)
func (c *Client) Publish(ctx context.Context, p *Publish) (*PublishResponse, error) {
+ return c.PublishWithOptions(ctx, p, PublishOptions{})
+}
+
+type PublishMethod int
+
+const (
+ PublishMethod_Blocking PublishMethod = iota // by default PublishWithOptions will block until the publish transaction is complete
+ PublishMethod_AsyncSend // PublishWithOptions will add the message to the session and then return (no method to check status is provided)
+)
+
+// PublishOptions enables the behaviour of Publish to be modified
+type PublishOptions struct {
+ // Method enables a degree of control over how PublishWithOptions operates
+ Method PublishMethod
+}
+
+// PublishWithOptions is used to send a publication to the MQTT server (with options to customise its behaviour)
+// It is passed a pre-prepared Publish packet and, by default, blocks waiting for the appropriate response, or for the
+// timeout to fire. A PublishResponse is returned, which is relevant for QOS1+. For QOS0, a default success response is returned.
+// Note that a message may still be delivered even if Publish times out (once the message is part of the session state,
+// it may even be delivered following an application restart).
+// Warning: Publish may outlive the connection when QOS1+ (managed in `session_state`)
+func (c *Client) PublishWithOptions(ctx context.Context, p *Publish, o PublishOptions) (*PublishResponse, error) {
if p.QoS > c.serverProps.MaximumQoS {
- return nil, fmt.Errorf("cannot send Publish with QoS %d, server maximum QoS is %d", p.QoS, c.serverProps.MaximumQoS)
+ return nil, fmt.Errorf("%w: cannot send Publish with QoS %d, server maximum QoS is %d", ErrInvalidArguments, p.QoS, c.serverProps.MaximumQoS)
}
if p.Properties != nil && p.Properties.TopicAlias != nil {
if c.serverProps.TopicAliasMaximum > 0 && *p.Properties.TopicAlias > c.serverProps.TopicAliasMaximum {
- return nil, fmt.Errorf("cannot send publish with TopicAlias %d, server topic alias maximum is %d", *p.Properties.TopicAlias, c.serverProps.TopicAliasMaximum)
+ return nil, fmt.Errorf("%w: cannot send publish with TopicAlias %d, server topic alias maximum is %d", ErrInvalidArguments, *p.Properties.TopicAlias, c.serverProps.TopicAliasMaximum)
}
}
if !c.serverProps.RetainAvailable && p.Retain {
- return nil, fmt.Errorf("cannot send Publish with retain flag set, server does not support retained messages")
+ return nil, fmt.Errorf("%w: cannot send Publish with retain flag set, server does not support retained messages", ErrInvalidArguments)
}
if (p.Properties == nil || p.Properties.TopicAlias == nil) && p.Topic == "" {
- return nil, fmt.Errorf("cannot send a publish with no TopicAlias and no Topic set")
+ return nil, fmt.Errorf("%w: cannot send a publish with no TopicAlias and no Topic set", ErrInvalidArguments)
}
- if c.ClientConfig.PublishHook != nil {
- c.ClientConfig.PublishHook(p)
+ if c.config.PublishHook != nil {
+ c.config.PublishHook(p)
}
c.debug.Printf("sending message to %s", p.Topic)
@@ -794,46 +869,54 @@ func (c *Client) Publish(ctx context.Context, p *Publish) (*PublishResponse, err
switch p.QoS {
case 0:
c.debug.Println("sending QoS0 message")
- if _, err := pb.WriteTo(c.Conn); err != nil {
+ if _, err := pb.WriteTo(c.config.Conn); err != nil {
+ go c.error(err)
return nil, err
}
- return nil, nil
+ c.config.PingHandler.PacketSent()
+ return &PublishResponse{}, nil
case 1, 2:
- return c.publishQoS12(ctx, pb)
+ return c.publishQoS12(ctx, pb, o)
}
- return nil, fmt.Errorf("QoS isn't 0, 1 or 2")
+ return nil, fmt.Errorf("%w: QoS isn't 0, 1 or 2", ErrInvalidArguments)
}
-func (c *Client) publishQoS12(ctx context.Context, pb *packets.Publish) (*PublishResponse, error) {
+func (c *Client) publishQoS12(ctx context.Context, pb *packets.Publish, o PublishOptions) (*PublishResponse, error) {
c.debug.Println("sending QoS12 message")
- pubCtx, cf := context.WithTimeout(ctx, c.PacketTimeout)
+ pubCtx, cf := context.WithTimeout(ctx, c.config.PacketTimeout)
defer cf()
- if err := c.serverInflight.Acquire(pubCtx, 1); err != nil {
+
+ ret := make(chan packets.ControlPacket, 1)
+ if err := c.config.Session.AddToSession(pubCtx, pb, ret); err != nil {
return nil, err
}
- defer c.serverInflight.Release(1)
- cpCtx := &CPContext{pubCtx, make(chan packets.ControlPacket, 1)}
- mid, err := c.MIDs.Request(cpCtx)
- if err != nil {
- return nil, err
+ // From this point on the message is in store, and ret will receive something regardless of whether we succeed in
+ // writing the packet to the connection
+ if _, err := pb.WriteTo(c.config.Conn); err != nil {
+ c.debug.Printf("failed to write packet %d to connection: %s", pb.PacketID, err)
+ if o.Method == PublishMethod_AsyncSend {
+ return nil, ErrNetworkErrorAfterStored // Async send, so we don't wait for the response (may add callbacks in the future to enable user to obtain status)
+ }
}
- defer c.MIDs.Free(mid)
- pb.PacketID = mid
+ c.config.PingHandler.PacketSent()
- if _, err := pb.WriteTo(c.Conn); err != nil {
- return nil, err
+ if o.Method == PublishMethod_AsyncSend {
+ return nil, nil // Async send, so we don't wait for the response (may add callbacks in the future to enable user to obtain status)
}
- var resp packets.ControlPacket
+ var resp packets.ControlPacket
select {
case <-pubCtx.Done():
- if ctxErr := pubCtx.Err(); ctxErr != nil {
- c.debug.Println(fmt.Sprintf("terminated due to context: %v", ctxErr))
- return nil, ctxErr
- }
- case resp = <-cpCtx.Return:
+ ctxErr := pubCtx.Err()
+ c.debug.Println(fmt.Sprintf("terminated due to context waiting for Publish ack: %v", ctxErr))
+ return nil, ctxErr
+ case resp = <-ret:
+ }
+
+ if resp.Type == 0 { // default ControlPacket indicates we are shutting down
+ return nil, errors.New("PUBLISH transmitted but not fully acknowledged at time of shutdown")
}
switch pb.QoS {
@@ -867,7 +950,7 @@ func (c *Client) publishQoS12(ctx context.Context, pb *packets.Publish) (*Publis
}
func (c *Client) expectConnack(packet chan<- *packets.Connack, errs chan<- error) {
- recv, err := packets.ReadPacket(c.Conn)
+ recv, err := packets.ReadPacket(c.config.Conn)
if err != nil {
errs <- err
return
@@ -877,17 +960,17 @@ func (c *Client) expectConnack(packet chan<- *packets.Connack, errs chan<- error
c.debug.Println("received CONNACK")
if r.ReasonCode == packets.ConnackSuccess && r.Properties != nil && r.Properties.AuthMethod != "" {
// Successful connack and AuthMethod is defined, must have successfully authed during connect
- go c.AuthHandler.Authenticated()
+ go c.config.AuthHandler.Authenticated()
}
packet <- r
case *packets.Auth:
c.debug.Println("received AUTH")
- if c.AuthHandler == nil {
+ if c.config.AuthHandler == nil {
errs <- fmt.Errorf("enhanced authentication flow started but no AuthHandler configured")
return
}
c.debug.Println("sending AUTH")
- _, err := c.AuthHandler.Authenticate(AuthFromPacketAuth(r)).Packet().WriteTo(c.Conn)
+ _, err := c.config.AuthHandler.Authenticate(AuthFromPacketAuth(r)).Packet().WriteTo(c.config.Conn)
if err != nil {
errs <- fmt.Errorf("error sending authentication packet: %w", err)
return
@@ -905,23 +988,77 @@ func (c *Client) expectConnack(packet chan<- *packets.Connack, errs chan<- error
// (and if it does this function returns any error) the network connection
// is closed.
func (c *Client) Disconnect(d *Disconnect) error {
- c.debug.Println("disconnecting")
- _, err := d.Packet().WriteTo(c.Conn)
+ c.debug.Println("disconnecting", d)
+ _, err := d.Packet().WriteTo(c.config.Conn)
c.close()
- c.workers.Wait()
return err
}
+// AddOnPublishReceived adds a function that will be called when a PUBLISH is received
+// The new function will be called after any functions already in the list
+// Returns a function that can be called to remove the callback
+func (c *Client) AddOnPublishReceived(f func(PublishReceived) (bool, error)) func() {
+ c.onPublishReceivedMu.Lock()
+ defer c.onPublishReceivedMu.Unlock()
+
+ c.onPublishReceived = append(c.onPublishReceived, f)
+
+ // We insert a unique ID into the same position in onPublishReceivedTracker; this enables us to
+ // remove the handler later (without complicating onPublishReceived which will be called frequently)
+ var id int
+idLoop:
+ for id = 0; ; id++ {
+ for _, used := range c.onPublishReceivedTracker {
+ if used == id {
+ continue idLoop
+ }
+ }
+ break
+ }
+ c.onPublishReceivedTracker = append(c.onPublishReceivedTracker, id)
+
+ return func() {
+ c.onPublishReceivedMu.Lock()
+ defer c.onPublishReceivedMu.Unlock()
+ for pos, storedID := range c.onPublishReceivedTracker {
+ if id == storedID {
+ c.onPublishReceivedTracker = append(c.onPublishReceivedTracker[:pos], c.onPublishReceivedTracker[pos+1:]...)
+ c.onPublishReceived = append(c.onPublishReceived[:pos], c.onPublishReceived[pos+1:]...)
+ }
+ }
+ }
+}
+
+// ClientID retrieves the client ID from the config (sometimes used in handlers that require the ID)
+func (c *Client) ClientID() string {
+ return c.config.ClientID
+}
+
// SetDebugLogger takes an instance of the paho Logger interface
// and sets it to be used by the debug log endpoint
-func (c *Client) SetDebugLogger(l Logger) {
+func (c *Client) SetDebugLogger(l log.Logger) {
c.debug = l
+ if c.config.autoCloseSession { // If we created the session store then it should use the same logger
+ c.config.Session.SetDebugLogger(l)
+ }
+ if c.config.defaultPinger { // Debug logger is set after the client is created so need to copy it to pinger
+ c.config.PingHandler.SetDebug(c.debug)
+ }
}
// SetErrorLogger takes an instance of the paho Logger interface
// and sets it to be used by the error log endpoint
-func (c *Client) SetErrorLogger(l Logger) {
+func (c *Client) SetErrorLogger(l log.Logger) {
c.errors = l
+ if c.config.autoCloseSession { // If we created the session store then it should use the same logger
+ c.config.Session.SetErrorLogger(l)
+ }
+}
+
+// TerminateConnectionForTest closes the active connection (if any). This function is intended for testing only, it
+// simulates connection loss which supports testing QOS1 and 2 message delivery.
+func (c *Client) TerminateConnectionForTest() {
+ _ = c.config.Conn.Close()
}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_auth.go b/vendor/github.com/eclipse/paho.golang/paho/cp_auth.go
index 6ccef9b47de..46b64f8e2af 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_auth.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_auth.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_connack.go b/vendor/github.com/eclipse/paho.golang/paho/cp_connack.go
index 2a525eb48b0..ef8a58605f6 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_connack.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_connack.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_connect.go b/vendor/github.com/eclipse/paho.golang/paho/cp_connect.go
index 8d731764d14..76adb183a0d 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_connect.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_connect.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
@@ -26,7 +41,6 @@ type (
WillDelayInterval *uint32
ReceiveMaximum *uint16
TopicAliasMaximum *uint16
- MaximumQOS *byte
MaximumPacketSize *uint32
User UserProperties
RequestProblemInfo bool
@@ -47,7 +61,6 @@ func (c *Connect) InitProperties(p *packets.Properties) {
RequestProblemInfo: true,
ReceiveMaximum: p.ReceiveMaximum,
TopicAliasMaximum: p.TopicAliasMaximum,
- MaximumQOS: p.MaximumQOS,
MaximumPacketSize: p.MaximumPacketSize,
User: UserPropertiesFromPacketUser(p.User),
}
@@ -122,7 +135,6 @@ func (c *Connect) Packet() *packets.Connect {
WillDelayInterval: c.Properties.WillDelayInterval,
ReceiveMaximum: c.Properties.ReceiveMaximum,
TopicAliasMaximum: c.Properties.TopicAliasMaximum,
- MaximumQOS: c.Properties.MaximumQOS,
MaximumPacketSize: c.Properties.MaximumPacketSize,
User: c.Properties.User.ToPacketProperties(),
}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_disconnect.go b/vendor/github.com/eclipse/paho.golang/paho/cp_disconnect.go
index 5caa85b147c..ac5931c40a1 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_disconnect.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_disconnect.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_publish.go b/vendor/github.com/eclipse/paho.golang/paho/cp_publish.go
index 1bb9654b341..7f845e3d844 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_publish.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_publish.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
@@ -12,6 +27,7 @@ type (
Publish struct {
PacketID uint16
QoS byte
+ duplicate bool // private because this should only ever be set in paho/session
Retain bool
Topic string
Properties *PublishProperties
@@ -52,26 +68,34 @@ func (p *Publish) InitProperties(prop *packets.Properties) {
// returns a paho library Publish
func PublishFromPacketPublish(p *packets.Publish) *Publish {
v := &Publish{
- PacketID: p.PacketID,
- QoS: p.QoS,
- Retain: p.Retain,
- Topic: p.Topic,
- Payload: p.Payload,
+ PacketID: p.PacketID,
+ QoS: p.QoS,
+ duplicate: p.Duplicate,
+ Retain: p.Retain,
+ Topic: p.Topic,
+ Payload: p.Payload,
}
v.InitProperties(p.Properties)
return v
}
+// Duplicate returns true if the duplicate flag is set (the server sets this if the message has
+// been sent previously; this does not necessarily mean the client has previously processed the message).
+func (p *Publish) Duplicate() bool {
+ return p.duplicate
+}
+
// Packet returns a packets library Publish from the paho Publish
// on which it is called
func (p *Publish) Packet() *packets.Publish {
v := &packets.Publish{
- PacketID: p.PacketID,
- QoS: p.QoS,
- Retain: p.Retain,
- Topic: p.Topic,
- Payload: p.Payload,
+ PacketID: p.PacketID,
+ QoS: p.QoS,
+ Duplicate: p.duplicate,
+ Retain: p.Retain,
+ Topic: p.Topic,
+ Payload: p.Payload,
}
if p.Properties != nil {
v.Properties = &packets.Properties{
@@ -90,6 +114,9 @@ func (p *Publish) Packet() *packets.Publish {
}
func (p *Publish) String() string {
+ if p == nil {
+ return "Publish==nil"
+ }
var b bytes.Buffer
fmt.Fprintf(&b, "topic: %s qos: %d retain: %t\n", p.Topic, p.QoS, p.Retain)
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_pubresp.go b/vendor/github.com/eclipse/paho.golang/paho/cp_pubresp.go
index 0c4e174aa00..bf47fca569e 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_pubresp.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_pubresp.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_suback.go b/vendor/github.com/eclipse/paho.golang/paho/cp_suback.go
index c1034c26c30..f9bce038933 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_suback.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_suback.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_subscribe.go b/vendor/github.com/eclipse/paho.golang/paho/cp_subscribe.go
index 52dc54017f2..04298accf0e 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_subscribe.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_subscribe.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_unsuback.go b/vendor/github.com/eclipse/paho.golang/paho/cp_unsuback.go
index 15ca83885a0..d9f1ad2c127 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_unsuback.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_unsuback.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_unsubscribe.go b/vendor/github.com/eclipse/paho.golang/paho/cp_unsubscribe.go
index 375b917c8f6..ff20acf9978 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_unsubscribe.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_unsubscribe.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import "github.com/eclipse/paho.golang/packets"
diff --git a/vendor/github.com/eclipse/paho.golang/paho/cp_utils.go b/vendor/github.com/eclipse/paho.golang/paho/cp_utils.go
index 2d7995f5ca7..a1ca35ebef0 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/cp_utils.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/cp_utils.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
diff --git a/vendor/github.com/eclipse/paho.golang/paho/log/test.go b/vendor/github.com/eclipse/paho.golang/paho/log/test.go
new file mode 100644
index 00000000000..4e8ff4d7e3b
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/log/test.go
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package log
+
+import (
+ "sync"
+ "time"
+)
+
+// test implements a logger than can be passed a testing.T (which will only output logs for failed tests)
+
+// testLogger contains the logging functions provided by testing.T
+type testLogger interface {
+ Log(args ...interface{})
+ Logf(format string, args ...interface{})
+}
+
+// The TestLog type is an adapter to allow the use of testing.T as a paho.Logger.
+// With this implementation, log messages will only be output when a test fails (and will be associated with the test).
+type TestLog struct {
+ sync.Mutex
+ l testLogger
+ prefix string
+}
+
+// NewTestLogger accepts a testLogger (e.g. Testing.T) and a prefix (added to messages logged) and returns a Logger
+func NewTestLogger(l testLogger, prefix string) *TestLog {
+ return &TestLog{
+ l: l,
+ prefix: prefix,
+ }
+}
+
+// Println prints a line to the log
+// Println its arguments in the test log (only printed if the test files or appropriate arguments passed to go test).
+func (t *TestLog) Println(v ...interface{}) {
+ t.Lock()
+ defer t.Unlock()
+ if t.l != nil {
+ t.l.Log(append([]interface{}{time.Now().Format(time.RFC3339Nano), t.prefix}, v...)...)
+ }
+}
+
+// Printf formats its arguments according to the format, analogous to fmt.Printf, and
+// records the text in the test log (only printed if the test files or appropriate arguments passed to go test).
+func (t *TestLog) Printf(format string, v ...interface{}) {
+ t.Lock()
+ defer t.Unlock()
+ if t.l != nil {
+ t.l.Logf(time.Now().Format(time.RFC3339Nano)+" "+t.prefix+format, v...)
+ }
+}
+
+// Stop prevents future logging
+// func (t *TestLog) Stop() {
+// t.Lock()
+// defer t.Unlock()
+// t.l = nil
+// }
diff --git a/vendor/github.com/eclipse/paho.golang/paho/trace.go b/vendor/github.com/eclipse/paho.golang/paho/log/trace.go
similarity index 55%
rename from vendor/github.com/eclipse/paho.golang/paho/trace.go
rename to vendor/github.com/eclipse/paho.golang/paho/log/trace.go
index 586c9239891..8363f7254e4 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/trace.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/log/trace.go
@@ -1,4 +1,19 @@
-package paho
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package log
type (
// Logger interface allows implementations to provide to this package any
diff --git a/vendor/github.com/eclipse/paho.golang/paho/message_ids.go b/vendor/github.com/eclipse/paho.golang/paho/message_ids.go
deleted file mode 100644
index ad287b5c755..00000000000
--- a/vendor/github.com/eclipse/paho.golang/paho/message_ids.go
+++ /dev/null
@@ -1,110 +0,0 @@
-package paho
-
-import (
- "context"
- "errors"
- "sync"
-
- "github.com/eclipse/paho.golang/packets"
-)
-
-const (
- midMin uint16 = 1
- midMax uint16 = 65535
-)
-
-// ErrorMidsExhausted is returned from Request() when there are no
-// free message ids to be used.
-var ErrorMidsExhausted = errors.New("all message ids in use")
-
-// MIDService defines the interface for a struct that handles the
-// relationship between message ids and CPContexts
-// Request() takes a *CPContext and returns a uint16 that is the
-// messageid that should be used by the code that called Request()
-// Get() takes a uint16 that is a messageid and returns the matching
-// *CPContext that the MIDService has associated with that messageid
-// Free() takes a uint16 that is a messageid and instructs the MIDService
-// to mark that messageid as available for reuse
-// Clear() resets the internal state of the MIDService
-type MIDService interface {
- Request(*CPContext) (uint16, error)
- Get(uint16) *CPContext
- Free(uint16)
- Clear()
-}
-
-// CPContext is the struct that is used to return responses to
-// ControlPackets that have them, eg: the suback to a subscribe.
-// The response packet is send down the Return channel and the
-// Context is used to track timeouts.
-type CPContext struct {
- Context context.Context
- Return chan packets.ControlPacket
-}
-
-// MIDs is the default MIDService provided by this library.
-// It uses a slice of *CPContext to track responses
-// to messages with a messageid tracking the last used message id
-type MIDs struct {
- sync.Mutex
- lastMid uint16
- index []*CPContext // index of slice is (messageid - 1)
-}
-
-// Request is the library provided MIDService's implementation of
-// the required interface function()
-func (m *MIDs) Request(c *CPContext) (uint16, error) {
- m.Lock()
- defer m.Unlock()
-
- // Scan from lastMid to end of range.
- for i := m.lastMid; i < midMax; i++ {
- if m.index[i] != nil {
- continue
- }
- m.index[i] = c
- m.lastMid = i + 1
- return i + 1, nil
- }
- // Scan from start of range to lastMid
- for i := uint16(0); i < m.lastMid; i++ {
- if m.index[i] != nil {
- continue
- }
- m.index[i] = c
- m.lastMid = i + 1
- return i + 1, nil
- }
-
- return 0, ErrorMidsExhausted
-}
-
-// Get is the library provided MIDService's implementation of
-// the required interface function()
-func (m *MIDs) Get(i uint16) *CPContext {
- // 0 Packet Identifier is invalid but just in case handled with returning nil to avoid panic.
- if i == 0 {
- return nil
- }
- m.Lock()
- defer m.Unlock()
- return m.index[i-1]
-}
-
-// Free is the library provided MIDService's implementation of
-// the required interface function()
-func (m *MIDs) Free(i uint16) {
- // 0 Packet Identifier is invalid but just in case handled to avoid panic.
- if i == 0 {
- return
- }
- m.Lock()
- m.index[i-1] = nil
- m.Unlock()
-}
-
-// Clear is the library provided MIDService's implementation of
-// the required interface function()
-func (m *MIDs) Clear() {
- m.index = make([]*CPContext, int(midMax))
-}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/noop_persistence.go b/vendor/github.com/eclipse/paho.golang/paho/noop_persistence.go
deleted file mode 100644
index d2d15704f1e..00000000000
--- a/vendor/github.com/eclipse/paho.golang/paho/noop_persistence.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package paho
-
-import "github.com/eclipse/paho.golang/packets"
-
-type noopPersistence struct{}
-
-func (n *noopPersistence) Open() {}
-
-func (n *noopPersistence) Put(id uint16, cp packets.ControlPacket) {}
-
-func (n *noopPersistence) Get(id uint16) packets.ControlPacket {
- return packets.ControlPacket{}
-}
-
-func (n *noopPersistence) All() []packets.ControlPacket {
- return nil
-}
-
-func (n *noopPersistence) Delete(id uint16) {}
-
-func (n *noopPersistence) Close() {}
-
-func (n *noopPersistence) Reset() {}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/persistence.go b/vendor/github.com/eclipse/paho.golang/paho/persistence.go
deleted file mode 100644
index f02b846cc2d..00000000000
--- a/vendor/github.com/eclipse/paho.golang/paho/persistence.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package paho
-
-import (
- "sync"
-
- "github.com/eclipse/paho.golang/packets"
-)
-
-// Persistence is an interface of the functions for a struct
-// that is used to persist ControlPackets.
-// Open() is an initialiser to prepare the Persistence for use
-// Put() takes a uint16 which is a messageid and a ControlPacket
-// to persist against that messageid
-// Get() takes a uint16 which is a messageid and returns the
-// persisted ControlPacket from the Persistence for that messageid
-// All() returns a slice of all ControlPackets persisted
-// Delete() takes a uint16 which is a messageid and deletes the
-// associated stored ControlPacket from the Persistence
-// Close() closes the Persistence
-// Reset() clears the Persistence and prepares it to be reused
-type Persistence interface {
- Open()
- Put(uint16, packets.ControlPacket)
- Get(uint16) packets.ControlPacket
- All() []packets.ControlPacket
- Delete(uint16)
- Close()
- Reset()
-}
-
-// MemoryPersistence is an implementation of a Persistence
-// that stores the ControlPackets in memory using a map
-type MemoryPersistence struct {
- sync.RWMutex
- packets map[uint16]packets.ControlPacket
-}
-
-// Open is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) Open() {
- m.Lock()
- m.packets = make(map[uint16]packets.ControlPacket)
- m.Unlock()
-}
-
-// Put is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) Put(id uint16, cp packets.ControlPacket) {
- m.Lock()
- m.packets[id] = cp
- m.Unlock()
-}
-
-// Get is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) Get(id uint16) packets.ControlPacket {
- m.RLock()
- defer m.RUnlock()
- return m.packets[id]
-}
-
-// All is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) All() []packets.ControlPacket {
- m.Lock()
- defer m.RUnlock()
- ret := make([]packets.ControlPacket, len(m.packets))
-
- for _, cp := range m.packets {
- ret = append(ret, cp)
- }
-
- return ret
-}
-
-// Delete is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) Delete(id uint16) {
- m.Lock()
- delete(m.packets, id)
- m.Unlock()
-}
-
-// Close is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) Close() {
- m.Lock()
- m.packets = nil
- m.Unlock()
-}
-
-// Reset is the library provided MemoryPersistence's implementation of
-// the required interface function()
-func (m *MemoryPersistence) Reset() {
- m.Lock()
- m.packets = make(map[uint16]packets.ControlPacket)
- m.Unlock()
-}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/pinger.go b/vendor/github.com/eclipse/paho.golang/paho/pinger.go
index e135d25acfe..0eb28ccb22c 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/pinger.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/pinger.go
@@ -1,122 +1,149 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
+ "context"
"fmt"
"net"
"sync"
- "sync/atomic"
"time"
"github.com/eclipse/paho.golang/packets"
+ "github.com/eclipse/paho.golang/paho/log"
)
-// PingFailHandler is a type for the function that is invoked
-// when we have sent a Pingreq to the server and not received
-// a Pingresp within 1.5x our pingtimeout
-type PingFailHandler func(error)
-
-// Pinger is an interface of the functions for a struct that is
-// used to manage sending PingRequests and responding to
-// PingResponses
-// Start() takes a net.Conn which is a connection over which an
-// MQTT session has already been established, and a time.Duration
-// of the keepalive setting passed to the server when the MQTT
-// session was established.
-// Stop() is used to stop the Pinger
-// PingResp() is the function that is called by the Client when
-// a PingResponse is received
-// SetDebug() is used to pass in a Logger to be used to log debug
-// information, for example sharing a logger with the main client
type Pinger interface {
- Start(net.Conn, time.Duration)
- Stop()
+ // Run starts the pinger. It blocks until the pinger is stopped.
+ // If the pinger stops due to an error, it returns the error.
+ // If the keepAlive is 0, it returns nil immediately.
+ // Run() may be called multiple times, but only after prior instances have terminated.
+ Run(ctx context.Context, conn net.Conn, keepAlive uint16) error
+
+ // PacketSent is called when a packet is sent to the server.
+ PacketSent()
+
+ // PingResp is called when a PINGRESP is received from the server.
PingResp()
- SetDebug(Logger)
+
+ // SetDebug sets the logger for debugging.
+ // It is not thread-safe and must be called before Run() to avoid race conditions.
+ SetDebug(log.Logger)
}
-// PingHandler is the library provided default Pinger
-type PingHandler struct {
- mu sync.Mutex
- lastPing time.Time
- conn net.Conn
- stop chan struct{}
- pingFailHandler PingFailHandler
- pingOutstanding int32
- debug Logger
+// DefaultPinger is the default implementation of Pinger.
+type DefaultPinger struct {
+ lastPacketSent time.Time
+ lastPingResponse time.Time
+
+ debug log.Logger
+
+ running bool // Used to prevent concurrent calls to Run
+
+ mu sync.Mutex // Protects all of the above
}
-// DefaultPingerWithCustomFailHandler returns an instance of the
-// default Pinger but with a custom PingFailHandler that is called
-// when the client has not received a response to a PingRequest
-// within the appropriate amount of time
-func DefaultPingerWithCustomFailHandler(pfh PingFailHandler) *PingHandler {
- return &PingHandler{
- pingFailHandler: pfh,
- debug: NOOPLogger{},
+// NewDefaultPinger creates a DefaultPinger
+func NewDefaultPinger() *DefaultPinger {
+ return &DefaultPinger{
+ debug: log.NOOPLogger{},
}
}
-// Start is the library provided Pinger's implementation of
-// the required interface function()
-func (p *PingHandler) Start(c net.Conn, pt time.Duration) {
+// Run starts the pinger; blocks until done (either context cancelled or error encountered)
+func (p *DefaultPinger) Run(ctx context.Context, conn net.Conn, keepAlive uint16) error {
+ if keepAlive == 0 {
+ p.debug.Println("Run() returning immediately due to keepAlive == 0")
+ return nil
+ }
+ if conn == nil {
+ return fmt.Errorf("conn is nil")
+ }
p.mu.Lock()
- p.conn = c
- p.stop = make(chan struct{})
+ if p.running {
+ p.mu.Unlock()
+ return fmt.Errorf("Run() already in progress")
+ }
+ p.running = true
p.mu.Unlock()
- checkTicker := time.NewTicker(pt / 4)
- defer checkTicker.Stop()
+ defer func() {
+ p.mu.Lock()
+ p.running = false
+ p.mu.Unlock()
+ }()
+
+ interval := time.Duration(keepAlive) * time.Second
+ timer := time.NewTimer(0) // Immediately send first pingreq
+ // If timer is not stopped, it cannot be garbage collected until it fires.
+ defer timer.Stop()
+ var lastPingSent time.Time
+ // errCh should be buffered, so that the goroutine sending the error does not block if the context is cancelled
+ errCh := make(chan error, 1)
for {
select {
- case <-p.stop:
- return
- case <-checkTicker.C:
- if atomic.LoadInt32(&p.pingOutstanding) > 0 && time.Since(p.lastPing) > (pt+pt>>1) {
- p.pingFailHandler(fmt.Errorf("ping resp timed out"))
- //ping outstanding and not reset in 1.5 times ping timer
- return
+ case <-ctx.Done():
+ return nil
+ case t := <-timer.C:
+ p.mu.Lock()
+ lastPingResponse := p.lastPingResponse
+ pingDue := p.lastPacketSent.Add(interval)
+ p.mu.Unlock()
+
+ if !lastPingSent.IsZero() && lastPingSent.After(lastPingResponse) {
+ p.debug.Printf("DefaultPinger PINGRESP timeout")
+ return fmt.Errorf("PINGRESP timed out")
}
- if time.Since(p.lastPing) >= pt {
- //time to send a ping
- if _, err := packets.NewControlPacket(packets.PINGREQ).WriteTo(p.conn); err != nil {
- if p.pingFailHandler != nil {
- p.pingFailHandler(err)
- }
- return
- }
- atomic.AddInt32(&p.pingOutstanding, 1)
- p.lastPing = time.Now()
- p.debug.Println("pingHandler sending ping request")
+
+ if t.Before(pingDue) {
+ // A Control Packet has been sent since we last checked, meaning the ping can be delayed
+ timer.Reset(pingDue.Sub(t))
+ continue
}
+ lastPingSent = time.Now()
+ go func() {
+ // WriteTo may not complete within KeepAlive period due to slow/unstable network.
+ // For instance, if a huge message is sent over a very slow link at the same time as PINGREQ packet,
+ // the Write operation may block for longer than KeepAlive interval.
+ // Note: connection closure unblocks the Write operation. So, the goroutine is not leaked.
+ if _, err := packets.NewControlPacket(packets.PINGREQ).WriteTo(conn); err != nil {
+ p.debug.Printf("DefaultPinger packet write error: %v", err)
+ errCh <- fmt.Errorf("failed to send PINGREQ: %w", err)
+ }
+ }()
+ timer.Reset(interval)
+ case err := <-errCh:
+ return err
}
}
}
-// Stop is the library provided Pinger's implementation of
-// the required interface function()
-func (p *PingHandler) Stop() {
+func (p *DefaultPinger) PacketSent() {
p.mu.Lock()
defer p.mu.Unlock()
- if p.stop == nil {
- return
- }
- p.debug.Println("pingHandler stopping")
- select {
- case <-p.stop:
- //Already stopped, do nothing
- default:
- close(p.stop)
- }
+ p.lastPacketSent = time.Now()
}
-// PingResp is the library provided Pinger's implementation of
-// the required interface function()
-func (p *PingHandler) PingResp() {
- p.debug.Println("pingHandler resetting pingOutstanding")
- atomic.StoreInt32(&p.pingOutstanding, 0)
+func (p *DefaultPinger) PingResp() {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ p.lastPingResponse = time.Now()
}
-// SetDebug sets the logger l to be used for printing debug
-// information for the pinger
-func (p *PingHandler) SetDebug(l Logger) {
- p.debug = l
+func (p *DefaultPinger) SetDebug(debug log.Logger) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ p.debug = debug
}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/router.go b/vendor/github.com/eclipse/paho.golang/paho/router.go
index 05031596f29..dc6fa7062f5 100644
--- a/vendor/github.com/eclipse/paho.golang/paho/router.go
+++ b/vendor/github.com/eclipse/paho.golang/paho/router.go
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
package paho
import (
@@ -5,10 +20,14 @@ import (
"sync"
"github.com/eclipse/paho.golang/packets"
+ "github.com/eclipse/paho.golang/paho/log"
)
// MessageHandler is a type for a function that is invoked
// by a Router when it has received a Publish.
+// MessageHandlers should complete quickly (start a go routine for
+// long-running processes) and should not call functions within the
+// paho instance that triggered them (due to potential deadlocks).
type MessageHandler func(*Publish)
// Router is an interface of the functions for a struct that is
@@ -24,16 +43,17 @@ type Router interface {
RegisterHandler(string, MessageHandler)
UnregisterHandler(string)
Route(*packets.Publish)
- SetDebugLogger(Logger)
+ SetDebugLogger(log.Logger)
}
// StandardRouter is a library provided implementation of a Router that
// allows for unique and multiple MessageHandlers per topic
type StandardRouter struct {
sync.RWMutex
- subscriptions map[string][]MessageHandler
- aliases map[uint16]string
- debug Logger
+ defaultHandler MessageHandler
+ subscriptions map[string][]MessageHandler
+ aliases map[uint16]string
+ debug log.Logger
}
// NewStandardRouter instantiates and returns an instance of a StandardRouter
@@ -41,10 +61,19 @@ func NewStandardRouter() *StandardRouter {
return &StandardRouter{
subscriptions: make(map[string][]MessageHandler),
aliases: make(map[uint16]string),
- debug: NOOPLogger{},
+ debug: log.NOOPLogger{},
}
}
+// NewStandardRouterWithDefault instantiates and returns an instance of a StandardRouter
+// with the default handler set to the value passed in (for convenience when creating
+// handler inline).
+func NewStandardRouterWithDefault(h MessageHandler) *StandardRouter {
+ r := NewStandardRouter()
+ r.DefaultHandler(h)
+ return r
+}
+
// RegisterHandler is the library provided StandardRouter's
// implementation of the required interface function()
func (r *StandardRouter) RegisterHandler(topic string, h MessageHandler) {
@@ -78,7 +107,7 @@ func (r *StandardRouter) Route(pb *packets.Publish) {
if pb.Properties.TopicAlias != nil {
r.debug.Println("message is using topic aliasing")
if pb.Topic != "" {
- //Register new alias
+ // Register new alias
r.debug.Printf("registering new topic alias '%d' for topic '%s'", *pb.Properties.TopicAlias, m.Topic)
r.aliases[*pb.Properties.TopicAlias] = pb.Topic
}
@@ -90,22 +119,37 @@ func (r *StandardRouter) Route(pb *packets.Publish) {
topic = m.Topic
}
+ handlerCalled := false
for route, handlers := range r.subscriptions {
if match(route, topic) {
r.debug.Println("found handler for:", route)
for _, handler := range handlers {
handler(m)
+ handlerCalled = true
}
}
}
+
+ if !handlerCalled && r.defaultHandler != nil {
+ r.defaultHandler(m)
+ }
}
// SetDebugLogger sets the logger l to be used for printing debug
// information for the router
-func (r *StandardRouter) SetDebugLogger(l Logger) {
+func (r *StandardRouter) SetDebugLogger(l log.Logger) {
r.debug = l
}
+// DefaultHandler sets handler to be called for messages that don't trigger another handler
+// Pass nil to unset.
+func (r *StandardRouter) DefaultHandler(h MessageHandler) {
+ r.debug.Println("registering default handler")
+ r.Lock()
+ defer r.Unlock()
+ r.defaultHandler = h
+}
+
func match(route, topic string) bool {
return route == topic || routeIncludesTopic(route, topic)
}
@@ -153,60 +197,12 @@ func topicSplit(topic string) []string {
return strings.Split(topic, "/")
}
-// SingleHandlerRouter is a library provided implementation of a Router
-// that stores only a single MessageHandler and invokes this MessageHandler
-// for all received Publishes
-type SingleHandlerRouter struct {
- sync.Mutex
- aliases map[uint16]string
- handler MessageHandler
- debug Logger
-}
-
-// NewSingleHandlerRouter instantiates and returns an instance of a SingleHandlerRouter
-func NewSingleHandlerRouter(h MessageHandler) *SingleHandlerRouter {
- return &SingleHandlerRouter{
- aliases: make(map[uint16]string),
- handler: h,
- debug: NOOPLogger{},
- }
-}
-
-// RegisterHandler is the library provided SingleHandlerRouter's
-// implementation of the required interface function()
-func (s *SingleHandlerRouter) RegisterHandler(topic string, h MessageHandler) {
- s.debug.Println("registering handler for:", topic)
- s.handler = h
-}
-
-// UnregisterHandler is the library provided SingleHandlerRouter's
-// implementation of the required interface function()
-func (s *SingleHandlerRouter) UnregisterHandler(topic string) {}
-
-// Route is the library provided SingleHandlerRouter's
-// implementation of the required interface function()
-func (s *SingleHandlerRouter) Route(pb *packets.Publish) {
- m := PublishFromPacketPublish(pb)
-
- s.debug.Println("routing message for:", m.Topic)
-
- if pb.Properties.TopicAlias != nil {
- s.debug.Println("message is using topic aliasing")
- if pb.Topic != "" {
- //Register new alias
- s.debug.Printf("registering new topic alias '%d' for topic '%s'", *pb.Properties.TopicAlias, m.Topic)
- s.aliases[*pb.Properties.TopicAlias] = pb.Topic
- }
- if t, ok := s.aliases[*pb.Properties.TopicAlias]; ok {
- s.debug.Printf("aliased topic '%d' translates to '%s'", *pb.Properties.TopicAlias, m.Topic)
- m.Topic = t
- }
- }
- s.handler(m)
-}
-
-// SetDebugLogger sets the logger l to be used for printing debug
-// information for the router
-func (s *SingleHandlerRouter) SetDebugLogger(l Logger) {
- s.debug = l
+// NewSingleHandlerRouter instantiates a router that will call the passed in message handler for all
+// inbound messages (assuming `RegisterHandler` is never called).
+//
+// Deprecated: SingleHandlerRouter has been removed because it did not meet the requirements set out
+// in the `Router` interface documentation. This function is only included to maintain compatibility,
+// but there are limits (this version does not ignore calls to `RegisterHandler`).
+func NewSingleHandlerRouter(h MessageHandler) *StandardRouter {
+ return NewStandardRouterWithDefault(h)
}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/session/session.go b/vendor/github.com/eclipse/paho.golang/paho/session/session.go
new file mode 100644
index 00000000000..a8d4a534945
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/session/session.go
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package session
+
+import (
+ "context"
+ "errors"
+ "io"
+
+ "github.com/eclipse/paho.golang/packets"
+ paholog "github.com/eclipse/paho.golang/paho/log"
+)
+
+// The session state includes:
+// * Inflight QOS1/2 Publish transactions (both sent and received)
+// * All requests
+
+var (
+ ErrNoConnection = errors.New("no connection available") // We are not in-between a call to ConAckReceived and ConnectionLost
+ ErrPacketIdentifiersExhausted = errors.New("all packet identifiers in use") // There are no available Packet IDs
+)
+
+// Packet provides sufficient functionality to enable a packet to be transmitted with a packet identifier
+type Packet interface {
+ SetIdentifier(uint16) // Sets the packet identifier
+ Type() byte // Gets the packet type
+ WriteTo(io.Writer) (int64, error)
+}
+
+// SessionManager will manage the mqtt session state; note that the state may outlast a single `Client` instance
+type SessionManager interface {
+ // ConAckReceived must be called when a CONNACK has been received (with no error). If an error is returned
+ // then the connection will be dropped.
+ ConAckReceived(io.Writer, *packets.Connect, *packets.Connack) error
+
+ // ConnectionLost must be called whenever the connection is lost or a DISCONNECT packet is received. It can be
+ // called multiple times for the same event as long as ConAckReceived is not called in the interim.
+ ConnectionLost(dp *packets.Disconnect) error
+
+ // AddToSession adds a packet to the session state (including allocation of a message identifier).
+ // This should only be used for packets that impact the session state (which does not include QOS0 publish).
+ // If this function returns a nil then:
+ // - A message Identifier has been added to the passed in packet
+ // - If a `PUBLISH` then a slot has been allocated (function will block if RECEIVE MAXIMUM messages are inflight)
+ // - Publish messages will have been written to the store (and will be automatically transmitted if a new connection
+ // is established before the message is fully acknowledged - subject to state rules in the MQTTv5 spec)
+ // - Something will be sent to `resp` when either the message is fully acknowledged or the packet is removed from
+ // the session (in which case nil will be sent).
+ //
+ // If the function returns an error, then any actions taken will be rewound prior to return.
+ AddToSession(ctx context.Context, packet Packet, resp chan<- packets.ControlPacket) error
+
+ // PacketReceived must be called when any packet with a packet identifier is received. It will make any required
+ // response and pass any `PUBLISH` messages that need to be passed to the user via the channel.
+ PacketReceived(*packets.ControlPacket, chan<- *packets.Publish) error
+
+ // Ack must be called when the client message handlers have completed (or, if manual acknowledgements are enabled,
+ // when`client.ACK()` has been called - note the potential issues discussed in issue #160.
+ Ack(pb *packets.Publish) error
+
+ // Close shuts down the session store, this will release any blocked calls
+ // Note: `paho` will only call this if it created the session (i.e. it was not passed in the config)
+ Close() error
+
+ // SetErrorLogger enables error logging via the passed logger (not thread safe)
+ SetErrorLogger(l paholog.Logger)
+
+ // SetDebugLogger enables debug logging via the passed logger (not thread safe)
+ SetDebugLogger(l paholog.Logger)
+}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/session/state/readme.md b/vendor/github.com/eclipse/paho.golang/paho/session/state/readme.md
new file mode 100644
index 00000000000..cbeec0f88ea
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/session/state/readme.md
@@ -0,0 +1,5 @@
+paho.golang/paho/session/state
+==============================
+
+This is an implementation of the `paho.golang/paho/session.SessionManager` interface and is the implementation used
+by default (should be suitable for mose use cases but can be replaced if it does not meet your needs).
\ No newline at end of file
diff --git a/vendor/github.com/eclipse/paho.golang/paho/session/state/sendquota.go b/vendor/github.com/eclipse/paho.golang/paho/session/state/sendquota.go
new file mode 100644
index 00000000000..d48f053037d
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/session/state/sendquota.go
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package state
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "sync"
+)
+
+// Implements send quota as described in section 4.9 of the spec. This is used to honour the receive-maximum
+// received from the broker; each time a qos1/2 PUBLISH is to be sent `Acquire` must be called, and this will
+// block until a slot is available (`Release` is called when the message is fully acknowledged).
+
+// This function was previously performed by `golang.org/x/sync/semaphore` but, as per the MQTT spec:
+//
+// > The send quota is not incremented if it is already equal to the initial send quota. The attempt to increment above
+// > the initial send quota might be caused by the re-transmission of a PUBREL packet after a new Network Connection is
+// > established.
+//
+// The result of this happening with `semaphore` is a `panic` which is not ideal.
+// It is also possible (as per issue #179) that bugs, or unexpected circumstances, may result in the same situation. For
+// example: if the local session state is lost but there is a session state on the server (meaning it sends an unexpected
+// PUBACK).
+//
+// Note: If the broker does not correctly acknowledge messages, then the quota will be consumed over time. There
+// should probably be a process to drop the connection if there are no slots available and no acknowledgements have been
+// received recently.
+
+// ErrUnexpectedRelease is for logging only (to help identify if there are issues with state management)
+var ErrUnexpectedRelease = errors.New("release called when quota at initial value")
+
+// newSendQuota creates a new tracker limited to quota concurrent messages
+func newSendQuota(quota uint16) *sendQuota {
+ w := &sendQuota{initialQuota: quota, quota: quota}
+ return w
+}
+
+// sendQuota provides a way to bound concurrent access to a resource.
+// The callers can request access with a given weight.
+type sendQuota struct {
+ mu sync.Mutex
+ initialQuota uint16
+ quota uint16
+ waiters []chan<- struct{} // using a slice because would generally expect this to be small
+}
+
+// Retransmit takes a slot for a message that is being redelivered and will never block.
+// This is not in compliance with the MQTT v5 spec and should be removed in the future.
+func (s *sendQuota) Retransmit() error {
+ return s.acquire(context.Background(), true)
+}
+
+// Acquire waits for a slot to become available so a message can be published
+// If ctx is already done, Acquire may still succeed without blocking.
+func (s *sendQuota) Acquire(ctx context.Context) error {
+ return s.acquire(ctx, false)
+}
+
+// acquire attempts to allocate a slot for a message to be published
+// If noWait is true quota will be ignored and the call will return immediately, otherwise acquire will block
+// until a slot is available.
+func (s *sendQuota) acquire(ctx context.Context, noWait bool) error {
+ s.mu.Lock()
+ if noWait || (s.quota > 0 && len(s.waiters) == 0) {
+ s.quota-- // Note: can go < 0 if noWait used
+ s.mu.Unlock()
+ return nil
+ }
+
+ // We need to join the queue
+ ready := make(chan struct{})
+ s.waiters = append(s.waiters, ready)
+ s.mu.Unlock()
+
+ var err error
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ s.mu.Lock()
+ select {
+ case <-ready: // If ready then already removed from s.waiters
+ // Acquired the semaphore after we were cancelled. Rather than trying to
+ // fix up the queue, just pretend we didn't notice the cancellation.
+ err = nil
+ fmt.Println("quota released entry but ready so nil error ", s.quota)
+ default:
+ // Remove ourselves from the list of waiters
+ for i, r := range s.waiters {
+ if ready == r {
+ s.waiters = append(s.waiters[:i], s.waiters[i+1:]...)
+ }
+ }
+ }
+ s.mu.Unlock()
+ case <-ready: // Note that quota already accounts for this item
+ }
+ return err
+}
+
+// Release releases slot
+func (s *sendQuota) Release() error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if s.quota >= 0 && len(s.waiters) > 0 { // Possible quota could go negative when using noWait
+ close(s.waiters[0])
+ s.waiters = append(s.waiters[:0], s.waiters[1:]...)
+ return nil
+ }
+ if s.quota < s.initialQuota {
+ s.quota++
+ return nil
+ }
+ return ErrUnexpectedRelease
+}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/session/state/state.go b/vendor/github.com/eclipse/paho.golang/paho/session/state/state.go
new file mode 100644
index 00000000000..bd197046e99
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/session/state/state.go
@@ -0,0 +1,739 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package state
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "sync"
+ "time"
+
+ "github.com/eclipse/paho.golang/packets"
+ paholog "github.com/eclipse/paho.golang/paho/log"
+ "github.com/eclipse/paho.golang/paho/session"
+ "github.com/eclipse/paho.golang/paho/store/memory"
+)
+
+// The Session State, as per the MQTT spec, contains:
+//
+// > QoS 1 and QoS 2 messages which have been sent to the Server, but have not been completely acknowledged.
+// > QoS 2 messages which have been received from the Server, but have not been completely acknowledged.
+//
+// and, importantly, is used when resending as follows:
+//
+// > When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend
+// > any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This
+// > is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT
+// > resend messages at any other time
+//
+// There are a few other areas where the State is important:
+// * When allocating a new packet identifier we need to know what Id's are already in the session state.
+// * If a QOS2 Publish with `DUP=TRUE` is received then we should not pass it to the client if we have previously
+// sent a `PUBREC` (indicating that the message has already been processed).
+// * Some subscribers may need a transaction (i.e. commit transaction when `PUBREL` received), this is not implemented
+// here, but the option is left open.
+//
+// This means that the following information may need to be retained after the connection is lost:
+// * The IDs of any transactions initiated by the client (so that we don't reuse IDs and can notify the requester (if
+// known) when a response is received or the request is removed from the state).
+// * For client initiated publish:
+// * Outgoing `PUBLISH` packets to allow resend.
+// * Outgoing `PUBREL` packets to allow resend.
+// * For server initiated publish:
+// * Outgoing `PUBREL` packets. The fact that this has been sent indicates that the user app has acknowledged the
+// message, and it should not be re-presented (doing so would breach the "exactly once" requirement).
+// * In memory only - the fact that a QOS2 PUBLISH has been received and sent to the handler, but not acknowledged.
+// This allows us to avoid presenting the message a second time (if the application is restarted, we have no option
+// but to re-present it because we have no way of knowing if the application completed handling it).
+//
+// It is important to note that there are packets with identifiers that do not form part of the session state
+// (SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK). Whilst these will never be stored to disk, it is important to track
+// the packet IDs to ensure we don't reuse them.
+// For packets relating to client-initiated transactions sent during a `session.State` lifetime we also want to link
+// a channel to the message ID so that we can notify our user when the transaction is complete (allowing a call to, for
+// instance `Publish()` to block until the message is fully acknowledged even if we disconnect/reconnect in the interim.
+
+const (
+ midMin uint16 = 1
+ midMax uint16 = 65535
+)
+
+type (
+ // clientGenerated holds information on client-generated packets (e.g. an outgoing SUBSCRIBE request)
+ clientGenerated struct {
+ packetType byte // The type of the last packet sent (i.e. PUBLISH, SUBSCRIBE or UNSUBSCRIBE) - 0 means unknown until loaded from the store
+
+ // When a message is fully acknowledged, we need to let the requester know by sending the final response to this
+ // channel. One and only one message will be sent (the channel will then be closed to ensure this!).
+ // We also guarantee to always send to the channel (assuming there is a clean shutdown) so that the end user knows
+ // the status of the request.
+ responseChan chan<- packets.ControlPacket
+ }
+)
+
+// State manages the session state. The client will send messages that may impact the state via
+// us, and we will maintain the session state
+type State struct {
+ mu sync.Mutex // protects whole struct (operations should be quick, so the impact of multiple mutexes is likely to be low)
+ connectionLostAt time.Time // Time that the connection was lost
+ sessionExpiryInterval uint32 // The session expiry interval sent with the most recent CONNECT packet
+
+ conn io.Writer // current connection or nil if we are not connected
+ connCtx context.Context // Context will be closed if the connection is lost (only valid when conn != nil)
+ connCtxCancel func() // Cancels the above context
+
+ // client store - holds packets where the message ID was generated on the client (i.e. by paho.golang)
+ clientPackets map[uint16]clientGenerated // Store relating to messages sent TO the server
+ clientStore storer // Used to store session state that survives connection loss
+ lastMid uint16 // The message ID most recently issued
+
+ // server store - holds packets where the message ID was generated on the server
+ serverPackets map[uint16]byte // The last packet received from the server with this ID (cleared when the transaction is complete)
+ serverStore storer // Used to store session state that survives connection loss
+
+ // The number of messages in flight needs to be limited, as per receive maximum received from the server.
+ inflight *sendQuota
+
+ debug paholog.Logger
+ errors paholog.Logger
+}
+
+// New creates a new state which will persist information using the passed in storer's.
+func New(client storer, server storer) *State {
+ return &State{
+ clientStore: client,
+ serverStore: server,
+ debug: paholog.NOOPLogger{},
+ errors: paholog.NOOPLogger{},
+ }
+}
+
+// NewInMemory returns a default State that stores all information in memory
+func NewInMemory() *State {
+ return &State{
+ clientStore: memory.New(),
+ serverStore: memory.New(),
+ debug: paholog.NOOPLogger{},
+ errors: paholog.NOOPLogger{},
+ }
+}
+
+// Close closes the session state
+func (s *State) Close() error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.connectionLost(nil) // Connection may be up in which case we need to cleanup.
+ for packetID, cg := range s.clientPackets {
+ cg.responseChan <- packets.ControlPacket{} // Default control packet indicates that we are shutting down (TODO: better solution?)
+ delete(s.clientPackets, packetID)
+ }
+ return nil
+}
+
+// ConAckReceived will be called when the client receives a CONACK that indicates the connection has been successfully
+// established. This indicates that a new connection is live and the passed in connection should be used going forward.
+// It is also the trigger to resend any queued messages. Note that this function should not be called concurrently with
+// others (we should not begin sending/receiving packets until after the CONACK has been processed).
+// TODO: Add errors() function so we can notify the client of errors whilst transmitting the session stuff?
+func (s *State) ConAckReceived(conn io.Writer, cp *packets.Connect, ca *packets.Connack) error {
+ // We could use cp.Properties.SessionExpiryInterval / ca.Properties.SessionExpiryInterval to clear the session
+ // after the specified time period (if the Session Expiry Interval is absent the value in the CONNECT Packet used)
+ // however, this is not something the generic client can really accomplish (forks may wish to do this!).
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.conn != nil {
+ s.errors.Println("ConAckReceived called whilst connection active (you MUST call ConnectionLost before starting a new connection")
+ _ = s.connectionLost(nil) // assume the connection dropped
+ }
+ s.conn = conn
+ s.connCtx, s.connCtxCancel = context.WithCancel(context.Background())
+
+ // If the Server accepts a connection with Clean Start set to 1, the Server MUST set Session Present to 0 in the
+ // CONNACK packet in addition to setting a 0x00 (Success) Reason Code in the CONNACK packet [MQTT-3.2.2-2].
+ // If the Server accepts a connection with Clean Start set to 0 and the Server has Session State for the ClientID,
+ // it MUST set Session Present to 1 in the CONNACK packet, otherwise it MUST set Session Present to 0 in the CONNACK
+ // packet. In both cases, it MUST set a 0x00 (Success) Reason Code in the CONNACK packet [MQTT-3.2.2-3].
+ if !ca.SessionPresent {
+ s.debug.Println("no session present - cleaning session state")
+ s.clean()
+ }
+ inFlight := uint16(len(s.clientPackets))
+ s.debug.Printf("%d inflight transactions upon connection", inFlight)
+
+ // "If the Session Expiry Interval is absent, the Session Expiry Interval in the CONNECT packet is used."
+ // If the Session Expiry Interval is absent the value 0 is used. If it is set to 0, or is absent, the Session ends
+ // when the Network Connection is closed (3.1.2.11.2).
+ if ca.Properties != nil && ca.Properties.SessionExpiryInterval != nil {
+ s.sessionExpiryInterval = *ca.Properties.SessionExpiryInterval
+ } else if cp.Properties != nil && cp.Properties.SessionExpiryInterval != nil {
+ s.sessionExpiryInterval = *cp.Properties.SessionExpiryInterval
+ } else {
+ s.sessionExpiryInterval = 0
+ }
+
+ // If clientPackets already exists, we re-use it so that the responseChan survives the reconnection
+ // the map will be populated/repopulated when we retransmit the messages.
+ if s.clientPackets == nil {
+ s.clientPackets = make(map[uint16]clientGenerated) // This will be populated whilst packets are resent
+ }
+
+ if s.serverPackets == nil {
+ if err := s.loadServerSession(ca); err != nil {
+ return fmt.Errorf("failed to server session: %w", err)
+ }
+ }
+
+ // As per section 4.9 "The send quota and Receive Maximum value are not preserved across Network Connections"
+ recvMax := uint16(65535) // Default as per MQTT spec
+ if ca.Properties != nil && ca.Properties.ReceiveMaximum != nil {
+ recvMax = *ca.Properties.ReceiveMaximum
+ }
+ s.inflight = newSendQuota(recvMax)
+
+ // Now we need to resend any packets in the store; this must happen in order, the simplest approach is to complete
+ // the sending them before returning.
+ toResend, err := s.clientStore.List()
+ if err != nil {
+ return fmt.Errorf("failed to load stored message ids: %w", err)
+ }
+ s.debug.Printf("retransmitting %d messages", len(toResend))
+ for _, id := range toResend {
+ s.debug.Printf("resending message ID %d", id)
+ r, err := s.clientStore.Get(id)
+ if err != nil {
+ s.errors.Printf("failed to load packet %d from client store: %s", id, err)
+ continue
+ }
+
+ // DUP needs to be set when resending PUBLISH
+ // Read/parse the full packet, so we can detect corruption (e.g. 0 byte file)
+ p, err := packets.ReadPacket(r)
+ if cErr := r.Close(); cErr != nil {
+ s.errors.Printf("failed to close stored client packet %d: %s", id, cErr)
+ }
+ if err != nil { // If the packet cannot be read, we quarantine it; otherwise we may retry infinitely.
+ if err := s.clientStore.Quarantine(id); err != nil {
+ s.errors.Printf("failed to quarantine packet %d from client store: %s", id, err)
+ }
+ s.errors.Printf("failed to retrieve/parse packet %d from client store: %s", id, err)
+ continue
+ }
+
+ switch p.Type {
+ case packets.PUBLISH:
+ pub := p.Content.(*packets.Publish)
+ pub.Duplicate = true
+ case packets.PUBREL:
+ default:
+ if err := s.clientStore.Quarantine(id); err != nil {
+ s.errors.Printf("failed to quarantine packet %d from client store: %s", id, err)
+ }
+ s.errors.Printf("unexpected packet type %d (for packet identifier %d) in client store", p.Type, id)
+ continue
+ }
+
+ // The messages being retransmitted form part of the "send quota"; however, as per the V5 spec,
+ // the limit does not apply to messages being resent (the quota can go under 0)
+ s.inflight.Retransmit() // This will never block (but is needed to block new messages)
+
+ // Any failure from this point should result in loss of connection (so fatal)
+ if _, err := p.WriteTo(conn); err != nil {
+ s.debug.Printf("retransmitting of identifier %d failed: %s", id, err)
+ return fmt.Errorf("failed to retransmit message (%d): %w", id, err)
+ }
+ s.debug.Printf("retransmitted message with identifier %d", id)
+ // On initial connection, the packet needs to be added to our record of client-generated packets.
+ if _, ok := s.clientPackets[id]; !ok {
+ s.clientPackets[id] = clientGenerated{
+ packetType: p.Type,
+ responseChan: make(chan packets.ControlPacket, 1), // Nothing will wait on this
+ }
+ }
+ }
+ return nil
+}
+
+// loadServerSession should be called once, when the first connection is established.
+// It loads the server session state from the store.
+// The caller must hold a lock on s.mu
+func (s *State) loadServerSession(ca *packets.Connack) error {
+ s.serverPackets = make(map[uint16]byte)
+ ids, err := s.serverStore.List()
+ if err != nil {
+ return fmt.Errorf("failed to load stored server message ids: %w", err)
+ }
+ for _, id := range ids {
+ r, err := s.serverStore.Get(id)
+ if err != nil {
+ s.errors.Printf("failed to load packet %d from server store: %s", id, err)
+ continue
+ }
+ // We only need to know the packet type so there is no need to process the entire packet
+ byte1 := make([]byte, 1)
+ _, err = r.Read(byte1)
+ _ = r.Close()
+ if err != nil {
+ if err := s.serverStore.Quarantine(id); err != nil {
+ s.errors.Printf("failed to quarantine packet %d from server store (failed to read): %s", id, err)
+ }
+ s.errors.Printf("packet %d from server store could not be read: %s", id, err)
+ continue // don't want to fail so quarantine and continue is the best we can do
+ }
+ packetType := byte1[0] >> 4
+ switch packetType {
+ case packets.PUBLISH:
+ s.serverPackets[id] = packets.PUBLISH
+ case packets.PUBREC:
+ s.serverPackets[id] = packets.PUBREC
+ default:
+ if err := s.serverStore.Quarantine(id); err != nil {
+ s.errors.Printf("failed to quarantine packet %d from server store: %s", id, err)
+ }
+ s.errors.Printf("packet %d from server store had unexpected type %d", id, packetType)
+ continue // don't want to fail so quarantine and continue is the best we can do
+ }
+ }
+ return nil
+}
+
+// ConnectionLost will be called when the connection is lost; either because we received a DISCONNECT packet or due
+// to a network error (`nil` will be passed in)
+func (s *State) ConnectionLost(dp *packets.Disconnect) error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ return s.connectionLost(dp)
+}
+
+// connectionLost process loss of connection
+// Caller MUST have locked c.Mu
+func (s *State) connectionLost(dp *packets.Disconnect) error {
+ if s.conn == nil {
+ return nil // ConnectionLost may be called multiple times (but call ref Disconnect packet should be first)
+ }
+ s.connCtxCancel()
+ s.conn, s.connCtx, s.connCtxCancel = nil, nil, nil
+ s.connectionLostAt = time.Now()
+
+ if dp != nil && dp.Properties != nil && dp.Properties.SessionExpiryInterval != nil {
+ s.sessionExpiryInterval = *dp.Properties.SessionExpiryInterval
+ }
+ // The Client and Server MUST store the Session State after the Network Connection is closed if the Session Expiry
+ // Interval is greater than 0 [MQTT-3.1.2-23]
+ if s.sessionExpiryInterval == 0 {
+ s.debug.Println("sessionExpiryInterval is 0 and connection lost - cleaning session state")
+ s.clean()
+ }
+ return nil
+}
+
+// AddToSession adds a packet to the session state (including allocation of a Message Identifier).
+// If this function returns a nil then:
+// - A slot has been allocated if the packet is a PUBLISH (function will block if RECEIVE MAXIMUM messages are inflight)
+// - A message Identifier has been added to the passed in packet
+// - Publish messages will have been written to the store (and will be automatically transmitted if a new connection
+// is established before the message is fully acknowledged - subject to state rules in the MQTTv5 spec)
+// - Something will be sent to `resp` when either the message is fully acknowledged or the packet is removed from
+// the session (in which case nil will be sent).
+//
+// If the function returns an error, then any actions taken will be rewound prior to return.
+func (s *State) AddToSession(ctx context.Context, packet session.Packet, resp chan<- packets.ControlPacket) error {
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+ s.mu.Lock() // There may be a delay waiting for semaphore so check for connection before and after
+ if s.conn == nil {
+ s.mu.Unlock()
+ return session.ErrNoConnection
+ }
+ // If the connection is lost whilst we are waiting, then in Acquire should terminate.
+ connCtx := s.connCtx
+ s.mu.Unlock()
+
+ // If the connection drops while waiting we should abort
+ go func() {
+ select {
+ case <-connCtx.Done():
+ cancel()
+ case <-ctx.Done():
+ }
+ }()
+
+ pt := packet.Type()
+
+ // Ensure only "RECEIVE MAXIMUM" PUBLISH transactions are in flight at any time
+ if pt == packets.PUBLISH {
+ if err := s.inflight.Acquire(ctx); err != nil {
+ if connCtx.Err() != nil {
+ return session.ErrNoConnection
+ }
+ return err // Allow user to confirm if it was their context that led to termination
+ }
+ }
+
+ // We have a slot, so acquire a Message ID
+ // Need to look at what to do if this fails. Should be infrequent as:
+ // its a lot of messages
+ // receive max often defaults to a fairly low value
+ // Maximum recieve max is 65535 which matches the number of slots (so would also need a SUB/UNSUB in flight).
+ packetID, err := s.allocateNextPacketId(pt, resp)
+ if err != nil {
+ if pt == packets.PUBLISH {
+ if qErr := s.inflight.Release(); qErr != nil {
+ s.errors.Printf("quota release due to packet id issue: %s", qErr)
+ }
+ }
+ return err
+ }
+ packet.SetIdentifier(packetID)
+ if pt == packets.PUBLISH {
+ if err = s.clientStore.Put(packetID, pt, packet); err != nil {
+ s.mu.Lock()
+ delete(s.clientPackets, packetID)
+ s.mu.Unlock()
+ if qErr := s.inflight.Release(); qErr != nil {
+ s.errors.Printf("quota release due to store issue: %s", qErr)
+ }
+ packet.SetIdentifier(0) // ensure the Message identifier is not used
+ return err
+ }
+ }
+ return nil
+}
+
+// endClientGenerated should be called when a client-generated transaction has been fully acknowledged
+// (or if, due to connection loss, it will never be acknowledged).
+func (s *State) endClientGenerated(packetID uint16, recv *packets.ControlPacket) error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if cg, ok := s.clientPackets[packetID]; ok {
+ cg.responseChan <- *recv
+ delete(s.clientPackets, packetID)
+ // Outgoing publish messages will be in the store (replaced with PUBREL that is sent)
+ if cg.packetType == packets.PUBLISH || cg.packetType == packets.PUBREL {
+ if qErr := s.inflight.Release(); qErr != nil {
+ s.errors.Printf("quota release due to %s: %s", recv.PacketType(), qErr)
+ }
+ if err := s.clientStore.Delete(packetID); err != nil {
+ s.errors.Printf("failed to remove message %d from store: %s", packetID, err)
+ }
+ }
+ } else {
+ s.debug.Println("received a response for a message ID we don't know:", recv.PacketID())
+ }
+ return nil // TODO: Should we return errors here (not much that could be done with them)
+}
+
+// Ack is called when the client message handlers have completed (or, if manual acknowledgements are enabled, when
+// `client.ACK()` has been called - this may happen some time after the message was received and it is conceivable that
+// the connection may have been dropped and reestablished in the interim).
+// See issue 160 re issues when the State is called after the connection is dropped. We assume that the
+// user will ensure that all ACK's are completed before the State is applied to a new connection (not doing
+// this may have unpredictable results).
+func (s *State) Ack(pb *packets.Publish) error {
+ return s.ack(pb)
+}
+
+// ack sends an acknowledgment of the `PUBLISH` (which will have been received from the server)
+// `s.mu` must NOT be locked when this is called.
+// Note: Adding properties to the response is not currently supported. If this functionality is added, then it is
+// important to note that QOS2 PUBREC's may be resent if a duplicate `PUBLISH` is received.
+// This function will only return comms related errors (so caller can assume connection has been lost).
+func (s *State) ack(pb *packets.Publish) error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ var err error
+ switch pb.QoS {
+ case 1:
+ pa := packets.Puback{
+ Properties: &packets.Properties{},
+ PacketID: pb.PacketID,
+ }
+ if s.conn != nil {
+ s.debug.Println("sending PUBACK")
+ _, err = pa.WriteTo(s.conn)
+ if err != nil {
+ s.errors.Printf("failed to send PUBACK for %d: %s", pb.PacketID, err)
+ }
+ } else {
+ s.debug.Println("PUBACK not send because connection down")
+ }
+ // We don't store outbound PUBACK. The server will retransmit the PUBLISH if the connection is reestablished
+ // before it receives the ACK. Unfortunately, there is no definitive way to determine if
+ // such messages are duplicates or not (so we are forced to treat them all as if they are new).
+ case 2:
+ pr := packets.Pubrec{
+ Properties: &packets.Properties{},
+ PacketID: pb.PacketID,
+ }
+ if s.conn != nil {
+ s.debug.Printf("sending PUBREC")
+ _, err = pr.WriteTo(s.conn)
+ if err != nil {
+ s.errors.Printf("failed to send PUBREC for %d: %s", pb.PacketID, err)
+ }
+ } else {
+ s.debug.Println("PUBREC not send because connection down")
+ }
+
+ // We need to record the fact that a PUBREC has been sent so we can detect receipt of a duplicate `PUBLISH`
+ // (which should not be passed to the client app)
+ cp := pr.ToControlPacket()
+ s.serverStore.Put(pb.PacketID, packets.PUBREC, cp)
+ s.serverPackets[pb.PacketID] = cp.Type
+ default:
+ err = errors.New("ack called but publish not QOS 1 or 2")
+ }
+ return err
+}
+
+// PacketReceived should be called whenever one of the following is received:
+// `PUBLISH` (QOS1+ only), `PUBACK`, `PUBREC`, `PUBREL`, `PUBCOMP`, `SUBACK`, `UNSUBACK`
+// It will handle sending any neccessary response or passing the message to the client.
+// pubChan will be sent a `PUBLISH` if applicable (and a receiver must be active whilst this function runs)
+func (s *State) PacketReceived(recv *packets.ControlPacket, pubChan chan<- *packets.Publish) error {
+ // Note: we do a type switch rather than using the packet type because it's safer and easier to understand
+ switch rp := recv.Content.(type) {
+ //
+ // Packets in response to client-generated transactions
+ //
+ case *packets.Suback: // Not in store, just need to advise client and free Message Identifier
+ s.debug.Println("received SUBACK packet with id ", rp.PacketID)
+ s.endClientGenerated(rp.PacketID, recv)
+ return nil
+ case *packets.Unsuback: // Not in store, just need to advise client and free Message Identifier
+ s.debug.Println("received UNSUBACK packet with id ", rp.PacketID)
+ s.endClientGenerated(rp.PacketID, recv)
+ return nil
+ case *packets.Puback: // QOS 1 initial (and final) response
+ s.debug.Println("received PUBACK packet with id ", rp.PacketID)
+ s.endClientGenerated(rp.PacketID, recv)
+ return nil
+ case *packets.Pubrec: // Initial response to a QOS2 Publish
+ s.debug.Println("received PUBREC packet with id ", rp.PacketID)
+ s.mu.Lock()
+ _, ok := s.clientPackets[rp.PacketID]
+ s.mu.Unlock()
+ if !ok {
+ pl := packets.Pubrel{ // Respond with "Packet Identifier not found"
+ PacketID: recv.Content.(*packets.Pubrec).PacketID,
+ ReasonCode: 0x92,
+ }
+ s.debug.Println("sending PUBREL (unknown ID) for ", pl.PacketID)
+ _, err := pl.WriteTo(s.conn)
+ if err != nil {
+ s.errors.Printf("failed to send PUBREL for %d: %s", pl.PacketID, err)
+ }
+ } else {
+ if rp.ReasonCode >= 0x80 {
+ s.endClientGenerated(rp.PacketID, recv)
+ } else {
+ pl := packets.Pubrel{
+ PacketID: rp.PacketID,
+ }
+ s.debug.Println("sending PUBREL for", rp.PacketID)
+ // Update the store (we should never resend the PUBLISH after receiving a PUBREL)
+ if err := s.clientStore.Put(rp.PacketID, packets.PUBREL, &pl); err != nil {
+ s.errors.Printf("failed to write PUBREL to store for %d: %s", rp.PacketID, err)
+ }
+ if _, err := pl.WriteTo(s.conn); err != nil {
+ s.errors.Printf("failed to send PUBREL for %d: %s", rp.PacketID, err)
+ }
+ }
+ }
+ return nil
+ case *packets.Pubcomp: // QOS 2 final response
+ s.debug.Printf("received PUBCOMP packet with id %d", rp.PacketID)
+ s.endClientGenerated(rp.PacketID, recv)
+ return nil
+ //
+ // Packets relating to server generated PUBLISH
+ //
+ case *packets.Publish:
+ s.debug.Printf("received QoS%d PUBLISH", rp.QoS)
+ // There is no need to store the packet because it will be resent if not acknowledged before the connection is
+ // reestablished.
+ if rp.QoS > 0 {
+ if rp.PacketID == 0 { // Invalid
+ return fmt.Errorf("received QOS %d PUBLISH with 0 PacketID", rp.QoS)
+ }
+ if rp.QoS == 2 {
+ s.mu.Lock()
+ if lastSent, ok := s.serverPackets[rp.PacketID]; ok {
+ // If we have sent a PUBREC, that means that the client has already seen this message, so we can
+ // simply resend the acknowledgment.
+ if lastSent == packets.PUBREC {
+ // If the message is not flagged as a duplicate, then something is wrong; to avoid message loss,
+ // we will treat this as a new message (because it appears there is a session mismatch, and we
+ // have not actually seen this message).
+ if rp.Duplicate {
+ // The client has already seen this message meaning we do not want to resend it and, instead
+ // immediately acknowledge it.
+ s.mu.Unlock() // mu must be unlocked to call ack
+ return s.ack(rp)
+ }
+ s.errors.Printf("received duplicate PUBLISH (%d) but dup flag not set (will assume this overwrites old publish)", rp.PacketID)
+ } else {
+ s.errors.Printf("received PUBLISH (%d) but lastSent type is %d (unexpected!)", lastSent)
+ }
+ }
+ s.mu.Unlock()
+ }
+ }
+ pubChan <- rp // the message will be passed to router (and thus the end user app)
+ return nil
+ case *packets.Pubrel:
+ s.debug.Println("received PUBREL for", recv.PacketID())
+ // Auto respond to pubrels unless failure code
+ pr := recv.Content.(*packets.Pubrel)
+ if pr.ReasonCode >= 0x80 {
+ // Received a failure code meaning the server does not know about the message (so all we can do is to remove
+ // it from our store).
+ s.errors.Printf("received PUBREL with reason code %d ", pr.ReasonCode)
+ return nil
+ } else {
+ pc := packets.Pubcomp{
+ PacketID: pr.PacketID,
+ }
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.debug.Println("sending PUBCOMP for", pr.PacketID)
+ var err error
+ if s.conn != nil {
+ _, err = pc.WriteTo(s.conn)
+ if err != nil {
+ s.errors.Printf("failed to send PUBCOMP for %d: %s", pc.PacketID, err)
+ }
+ // Note: If connection is down we do not clear store (because the server will resend PUBREL upon reconnect)
+ delete(s.serverPackets, pr.PacketID)
+ if sErr := s.serverStore.Delete(pr.PacketID); sErr != nil {
+ s.errors.Printf("failed to remove message %d from server store: %s", pr.PacketID, sErr)
+ }
+ }
+ return err
+ }
+ default:
+ s.errors.Printf("State.PacketReceived received unexpected packet: %#v ", rp)
+ return nil
+ }
+}
+
+// allocateNextPacketId assigns the next available packet ID
+// Callers must NOT hold lock on s.mu
+func (s *State) allocateNextPacketId(forPacketType byte, resp chan<- packets.ControlPacket) (uint16, error) {
+ s.mu.Lock() // There may be a delay waiting for semaphore so check for connection before and after
+ defer s.mu.Unlock()
+
+ cg := clientGenerated{
+ packetType: forPacketType,
+ responseChan: resp,
+ }
+
+ // Scan from lastMid to end of range.
+ for i := s.lastMid + 1; i != 0; i++ {
+ if _, ok := s.clientPackets[i]; ok {
+ continue
+ }
+ s.clientPackets[i] = cg
+ s.lastMid = i
+ return i, nil
+ }
+
+ // Default struct will set s.lastMid=0 meaning we have already scanned all mids
+ if s.lastMid == 0 {
+ s.lastMid = 1
+ return 0, session.ErrPacketIdentifiersExhausted
+ }
+
+ // Scan from start of range to lastMid (use +1 to avoid rolling over when s.lastMid = 65535)
+ for i := uint16(0); i < s.lastMid; i++ {
+ if _, ok := s.clientPackets[i+1]; ok {
+ continue
+ }
+ s.clientPackets[i+1] = cg
+ s.lastMid = i + 1
+ return i + 1, nil
+ }
+ return 0, session.ErrPacketIdentifiersExhausted
+}
+
+// clean deletes any existing stored session information
+// does not touch inflight because this is not part of the session state (so is reset separately)
+// caller is responsible for locking s.mu
+func (s *State) clean() {
+ s.debug.Println("State.clean() called")
+ s.serverPackets = make(map[uint16]byte)
+ s.clientPackets = make(map[uint16]clientGenerated)
+
+ s.serverStore.Reset()
+ s.clientStore.Reset()
+}
+
+// clean deletes any existing stored session information
+// as per section 4.1 in the spec; The Session State in the Client consists of:
+// > · QoS 1 and QoS 2 messages which have been sent to the Server, but have not been completely acknowledged.
+// > · QoS 2 messages which have been received from the Server, but have not been completely acknowledged.
+// This means that we keep PUBLISH, PUBREC and PUBREL packets. PUBACK and PUBCOMP will not be stored (the MID
+// will be free once they have been sent). PUBREC is retained so we can check newly received PUBLISH messages (and
+// confirm if they have already been processed).
+// We only resend PUBLISH (where QoS > 0) and PUBREL packets (as per spec section 4.4)
+// caller is responsible for locking s.mu
+func (s *State) tidy(trigger *packets.ControlPacket) {
+ s.debug.Println("State.tidy() called")
+ for id, p := range s.serverPackets {
+ switch p {
+ case packets.PUBREC:
+ // For inbound messages, we only retain `PUBREC` messages so that we can determine if a PUBLISH received has
+ // already been processed (the `PUBREL` will be sent when the message has been processed by our user).
+ // The broker will resend any `PUBLISH` and `PUBREL` messages, so there is no need to retain those.
+ default:
+ delete(s.serverPackets, id)
+ s.serverStore.Delete(id)
+ }
+ }
+
+ for id, p := range s.clientPackets {
+ // We only need to remember `PUBLISH` and `PUBREL` messages (both originating from a PUBLISH)
+ if p.packetType != packets.PUBLISH {
+ delete(s.clientPackets, id)
+ s.clientStore.Delete(id)
+ p.responseChan <- packets.ControlPacket{}
+ }
+ }
+}
+
+// SetDebugLogger takes an instance of the paho Logger interface
+// and sets it to be used by the debug log endpoint
+func (s *State) SetDebugLogger(l paholog.Logger) {
+ s.debug = l
+}
+
+// SetErrorLogger takes an instance of the paho Logger interface
+// and sets it to be used by the error log endpoint
+func (s *State) SetErrorLogger(l paholog.Logger) {
+ s.errors = l
+}
+
+// AllocateClientPacketIDForTest is intended for use in tests only. It allocates a packet ID in the client session state
+// This feels like a hack but makes it easier to test packet identifier exhaustion
+func (s *State) AllocateClientPacketIDForTest(packetID uint16, forPacketType byte, resp chan<- packets.ControlPacket) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.clientPackets[packetID] = clientGenerated{
+ packetType: forPacketType,
+ responseChan: resp,
+ }
+}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/session/state/store.go b/vendor/github.com/eclipse/paho.golang/paho/session/state/store.go
new file mode 100644
index 00000000000..b31a8e50ed3
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/session/state/store.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package state
+
+import (
+ "io"
+)
+
+// storer must be implemented by session state stores
+type storer interface {
+ Put(packetID uint16, packetType byte, w io.WriterTo) error // Store the packet
+ Get(packetID uint16) (io.ReadCloser, error) // Retrieve the packet with the specified in ID
+ Delete(id uint16) error // Removes the message with the specified store ID
+
+ // Quarantine sets the message with the specified store ID into an error state; this may mean deleting it or storing
+ // it somewhere separate. This is intended for use when a corrupt packet is detected (as this may result in data
+ // loss, it's beneficial to have access to corrupt packets for analysis).
+ Quarantine(id uint16) error
+
+ List() ([]uint16, error) // Returns packet IDs in the order they were Put
+ Reset() error // Clears the store (deleting all messages)
+}
diff --git a/vendor/github.com/eclipse/paho.golang/paho/store/memory/store.go b/vendor/github.com/eclipse/paho.golang/paho/store/memory/store.go
new file mode 100644
index 00000000000..03c52febb46
--- /dev/null
+++ b/vendor/github.com/eclipse/paho.golang/paho/store/memory/store.go
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package memory
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "sync"
+
+ "github.com/eclipse/paho.golang/packets"
+)
+
+var (
+ ErrNotInStore = errors.New("the requested ID was not found in the store") // Returned when requested ID not found
+)
+
+// memoryPacket is an element in the memory store
+type memoryPacket struct {
+ c int // message count (used for ordering; as this is 32 bit min chance of rolling over seems remote)
+ p []byte // the packet we are storing
+}
+
+// New creates a Store
+func New() *Store {
+ return &Store{
+ data: make(map[uint16]memoryPacket),
+ }
+
+}
+
+// Store is an implementation of a Store that stores the data in memory
+type Store struct {
+ // server store - holds packets where the message ID was generated on the server
+ sync.Mutex
+ data map[uint16]memoryPacket // Holds messages initiated by the server (i.e. we will receive the PUBLISH)
+ c int // sequence counter used to maintain message order
+}
+
+// Put stores the packet
+func (m *Store) Put(packetID uint16, packetType byte, w io.WriterTo) error {
+ m.Lock()
+ defer m.Unlock()
+ var buff bytes.Buffer
+
+ _, err := w.WriteTo(&buff)
+ if err != nil {
+ panic(err)
+ }
+
+ m.data[packetID] = memoryPacket{
+ c: m.c,
+ p: buff.Bytes(),
+ }
+ m.c++
+ return nil
+}
+
+func (m *Store) Get(packetID uint16) (io.ReadCloser, error) {
+ m.Lock()
+ defer m.Unlock()
+ d, ok := m.data[packetID]
+ if !ok {
+ return nil, ErrNotInStore
+ }
+ return io.NopCloser(bytes.NewReader(d.p)), nil
+}
+
+// Delete removes the message with the specified store ID
+func (m *Store) Delete(id uint16) error {
+ m.Lock()
+ defer m.Unlock()
+ if _, ok := m.data[id]; !ok {
+ // This could be ignored, but reporting it may help reveal other issues
+ return fmt.Errorf("request to delete packet %d; packet not found", id)
+ }
+ delete(m.data, id)
+ return nil
+}
+
+// Quarantine is called if a corrupt packet is detected.
+// There is little we can do other than deleting the packet.
+func (m *Store) Quarantine(id uint16) error {
+ return m.Delete(id)
+}
+
+// List returns packet IDs in the order they were Put
+func (m *Store) List() ([]uint16, error) {
+ m.Lock()
+ defer m.Unlock()
+
+ ids := make([]uint16, 0, len(m.data))
+ seq := make([]int, 0, len(m.data))
+
+ // Basic insert sort from map ordered by time
+ // As the map is relatively small, this should be quick enough (data is retrieved infrequently)
+ itemNo := 0
+ var pos int
+ for i, v := range m.data {
+ for pos = 0; pos < itemNo; pos++ {
+ if seq[pos] > v.c {
+ break
+ }
+ }
+ ids = append(ids[:pos], append([]uint16{i}, ids[pos:]...)...)
+ seq = append(seq[:pos], append([]int{v.c}, seq[pos:]...)...)
+ itemNo++
+ }
+ return ids, nil
+}
+
+// Reset clears the store (deleting all messages)
+func (m *Store) Reset() error {
+ m.Lock()
+ defer m.Unlock()
+ m.data = make(map[uint16]memoryPacket)
+ return nil
+}
+
+// String is for debugging purposes; it dumps the content of the store in a readable format
+func (m *Store) String() string {
+ var b bytes.Buffer
+ for i, c := range m.data {
+ p, err := packets.ReadPacket(bytes.NewReader(c.p))
+ if err != nil {
+ b.WriteString(fmt.Sprintf("packet %d could not be read: %s\n", i, err))
+ continue
+ }
+
+ b.WriteString(fmt.Sprintf("packet %d is %s\n", i, p))
+ }
+ return b.String()
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/.gitignore b/vendor/github.com/go-jose/go-jose/v4/.gitignore
new file mode 100644
index 00000000000..eb29ebaefd8
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/.gitignore
@@ -0,0 +1,2 @@
+jose-util/jose-util
+jose-util.t.err
\ No newline at end of file
diff --git a/vendor/github.com/go-jose/go-jose/v4/.golangci.yml b/vendor/github.com/go-jose/go-jose/v4/.golangci.yml
new file mode 100644
index 00000000000..2a577a8f95b
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/.golangci.yml
@@ -0,0 +1,53 @@
+# https://github.com/golangci/golangci-lint
+
+run:
+ skip-files:
+ - doc_test.go
+ modules-download-mode: readonly
+
+linters:
+ enable-all: true
+ disable:
+ - gochecknoglobals
+ - goconst
+ - lll
+ - maligned
+ - nakedret
+ - scopelint
+ - unparam
+ - funlen # added in 1.18 (requires go-jose changes before it can be enabled)
+
+linters-settings:
+ gocyclo:
+ min-complexity: 35
+
+issues:
+ exclude-rules:
+ - text: "don't use ALL_CAPS in Go names"
+ linters:
+ - golint
+ - text: "hardcoded credentials"
+ linters:
+ - gosec
+ - text: "weak cryptographic primitive"
+ linters:
+ - gosec
+ - path: json/
+ linters:
+ - dupl
+ - errcheck
+ - gocritic
+ - gocyclo
+ - golint
+ - govet
+ - ineffassign
+ - staticcheck
+ - structcheck
+ - stylecheck
+ - unused
+ - path: _test\.go
+ linters:
+ - scopelint
+ - path: jwk.go
+ linters:
+ - gocyclo
diff --git a/vendor/github.com/go-jose/go-jose/v4/.travis.yml b/vendor/github.com/go-jose/go-jose/v4/.travis.yml
new file mode 100644
index 00000000000..48de631b003
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/.travis.yml
@@ -0,0 +1,33 @@
+language: go
+
+matrix:
+ fast_finish: true
+ allow_failures:
+ - go: tip
+
+go:
+ - "1.13.x"
+ - "1.14.x"
+ - tip
+
+before_script:
+ - export PATH=$HOME/.local/bin:$PATH
+
+before_install:
+ - go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge
+ - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0
+ - pip install cram --user
+
+script:
+ - go test -v -covermode=count -coverprofile=profile.cov .
+ - go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner
+ - go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher
+ - go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt
+ - go test -v ./json # no coverage for forked encoding/json package
+ - golangci-lint run
+ - cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util
+ - cd ..
+
+after_success:
+ - gocovmerge *.cov */*.cov > merged.coverprofile
+ - goveralls -coverprofile merged.coverprofile -service=travis-ci
diff --git a/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
new file mode 100644
index 00000000000..28bdd2fc08f
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
@@ -0,0 +1,72 @@
+# v4.0.1
+
+## Fixed
+
+ - An attacker could send a JWE containing compressed data that used large
+ amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
+ Those functions now return an error if the decompressed data would exceed
+ 250kB or 10x the compressed size (whichever is larger). Thanks to
+ Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
+ for reporting.
+
+# v4.0.0
+
+This release makes some breaking changes in order to more thoroughly
+address the vulnerabilities discussed in [Three New Attacks Against JSON Web
+Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
+token".
+
+## Changed
+
+ - Limit JWT encryption types (exclude password or public key types) (#78)
+ - Enforce minimum length for HMAC keys (#85)
+ - jwt: match any audience in a list, rather than requiring all audiences (#81)
+ - jwt: accept only Compact Serialization (#75)
+ - jws: Add expected algorithms for signatures (#74)
+ - Require specifying expected algorithms for ParseEncrypted,
+ ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
+ jwt.ParseSignedAndEncrypted (#69, #74)
+ - Usually there is a small, known set of appropriate algorithms for a program
+ to use and it's a mistake to allow unexpected algorithms. For instance the
+ "billion hash attack" relies in part on programs accepting the PBES2
+ encryption algorithm and doing the necessary work even if they weren't
+ specifically configured to allow PBES2.
+ - Revert "Strip padding off base64 strings" (#82)
+ - The specs require base64url encoding without padding.
+ - Minimum supported Go version is now 1.21
+
+## Added
+
+ - ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
+ - These allow parsing a specific serialization, as opposed to ParseSigned and
+ ParseEncrypted, which try to automatically detect which serialization was
+ provided. It's common to require a specific serialization for a specific
+ protocol - for instance JWT requires Compact serialization.
+
+[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
+
+# v3.0.2
+
+## Fixed
+
+ - DecryptMulti: handle decompression error (#19)
+
+## Changed
+
+ - jwe/CompactSerialize: improve performance (#67)
+ - Increase the default number of PBKDF2 iterations to 600k (#48)
+ - Return the proper algorithm for ECDSA keys (#45)
+
+## Added
+
+ - Add Thumbprint support for opaque signers (#38)
+
+# v3.0.1
+
+## Fixed
+
+ - Security issue: an attacker specifying a large "p2c" value can cause
+ JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
+ amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
+ disclosure and to Tom Tervoort for originally publishing the category of attack.
+ https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
diff --git a/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md
new file mode 100644
index 00000000000..b63e1f8fee5
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md
@@ -0,0 +1,15 @@
+# Contributing
+
+If you would like to contribute code to go-jose you can do so through GitHub by
+forking the repository and sending a pull request.
+
+When submitting code, please make every effort to follow existing conventions
+and style in order to keep the code as readable as possible. Please also make
+sure all tests pass by running `go test`, and format your code with `go fmt`.
+We also recommend using `golint` and `errcheck`.
+
+Before your code can be accepted into the project you must also sign the
+Individual Contributor License Agreement. We use [cla-assistant.io][1] and you
+will be prompted to sign once a pull request is opened.
+
+[1]: https://cla-assistant.io/
diff --git a/vendor/github.com/go-jose/go-jose/v4/LICENSE b/vendor/github.com/go-jose/go-jose/v4/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/go-jose/go-jose/v4/README.md b/vendor/github.com/go-jose/go-jose/v4/README.md
new file mode 100644
index 00000000000..79a7c5ecc87
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/README.md
@@ -0,0 +1,114 @@
+# Go JOSE
+
+[](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
+[](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
+[](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)
+[](https://github.com/go-jose/go-jose/actions)
+
+Package jose aims to provide an implementation of the Javascript Object Signing
+and Encryption set of standards. This includes support for JSON Web Encryption,
+JSON Web Signature, and JSON Web Token standards.
+
+**Disclaimer**: This library contains encryption software that is subject to
+the U.S. Export Administration Regulations. You may not export, re-export,
+transfer or download this code or any part of it in violation of any United
+States law, directive or regulation. In particular this software may not be
+exported or re-exported in any form or on any media to Iran, North Sudan,
+Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any
+US maintained blocked list.
+
+## Overview
+
+The implementation follows the
+[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516),
+[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
+[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
+Tables of supported algorithms are shown below. The library supports both
+the compact and JWS/JWE JSON Serialization formats, and has optional support for
+multiple recipients. It also comes with a small command-line utility
+([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util))
+for dealing with JOSE messages in a shell.
+
+**Note**: We use a forked version of the `encoding/json` package from the Go
+standard library which uses case-sensitive matching for member names (instead
+of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)).
+This is to avoid differences in interpretation of messages between go-jose and
+libraries in other languages.
+
+### Versions
+
+[Version 4](https://github.com/go-jose/go-jose)
+([branch](https://github.com/go-jose/go-jose/tree/main),
+[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version:
+
+ import "github.com/go-jose/go-jose/v4"
+
+The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which
+are still useable but not actively developed anymore.
+
+Version 3, in this repo, is still receiving security fixes but not functionality
+updates.
+
+### Supported algorithms
+
+See below for a table of supported algorithms. Algorithm identifiers match
+the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)
+standard where possible. The Godoc reference has a list of constants.
+
+ Key encryption | Algorithm identifier(s)
+ :------------------------- | :------------------------------
+ RSA-PKCS#1v1.5 | RSA1_5
+ RSA-OAEP | RSA-OAEP, RSA-OAEP-256
+ AES key wrap | A128KW, A192KW, A256KW
+ AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW
+ ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
+ ECDH-ES (direct) | ECDH-ES1
+ Direct encryption | dir1
+
+1. Not supported in multi-recipient mode
+
+ Signing / MAC | Algorithm identifier(s)
+ :------------------------- | :------------------------------
+ RSASSA-PKCS#1v1.5 | RS256, RS384, RS512
+ RSASSA-PSS | PS256, PS384, PS512
+ HMAC | HS256, HS384, HS512
+ ECDSA | ES256, ES384, ES512
+ Ed25519 | EdDSA2
+
+2. Only available in version 2 of the package
+
+ Content encryption | Algorithm identifier(s)
+ :------------------------- | :------------------------------
+ AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512
+ AES-GCM | A128GCM, A192GCM, A256GCM
+
+ Compression | Algorithm identifiers(s)
+ :------------------------- | -------------------------------
+ DEFLATE (RFC 1951) | DEF
+
+### Supported key types
+
+See below for a table of supported key types. These are understood by the
+library, and can be passed to corresponding functions such as `NewEncrypter` or
+`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which
+allows attaching a key id.
+
+ Algorithm(s) | Corresponding types
+ :------------------------- | -------------------------------
+ RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)
+ ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)
+ EdDSA1 | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey)
+ AES, HMAC | []byte
+
+1. Only available in version 2 or later of the package
+
+## Examples
+
+[](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
+[](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
+
+Examples can be found in the Godoc
+reference for this package. The
+[`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util)
+subdirectory also contains a small command-line utility which might be useful
+as an example as well.
diff --git a/vendor/github.com/go-jose/go-jose/v4/SECURITY.md b/vendor/github.com/go-jose/go-jose/v4/SECURITY.md
new file mode 100644
index 00000000000..2f18a75a822
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+This document explains how to contact the Let's Encrypt security team to report security vulnerabilities.
+
+## Supported Versions
+| Version | Supported |
+| ------- | ----------|
+| >= v3 | ✓ |
+| v2 | ✗ |
+| v1 | ✗ |
+
+## Reporting a vulnerability
+
+Please see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email.
diff --git a/vendor/github.com/go-jose/go-jose/v4/asymmetric.go b/vendor/github.com/go-jose/go-jose/v4/asymmetric.go
new file mode 100644
index 00000000000..f8d5774ef56
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/asymmetric.go
@@ -0,0 +1,595 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jose
+
+import (
+ "crypto"
+ "crypto/aes"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/sha256"
+ "errors"
+ "fmt"
+ "math/big"
+
+ josecipher "github.com/go-jose/go-jose/v4/cipher"
+ "github.com/go-jose/go-jose/v4/json"
+)
+
+// A generic RSA-based encrypter/verifier
+type rsaEncrypterVerifier struct {
+ publicKey *rsa.PublicKey
+}
+
+// A generic RSA-based decrypter/signer
+type rsaDecrypterSigner struct {
+ privateKey *rsa.PrivateKey
+}
+
+// A generic EC-based encrypter/verifier
+type ecEncrypterVerifier struct {
+ publicKey *ecdsa.PublicKey
+}
+
+type edEncrypterVerifier struct {
+ publicKey ed25519.PublicKey
+}
+
+// A key generator for ECDH-ES
+type ecKeyGenerator struct {
+ size int
+ algID string
+ publicKey *ecdsa.PublicKey
+}
+
+// A generic EC-based decrypter/signer
+type ecDecrypterSigner struct {
+ privateKey *ecdsa.PrivateKey
+}
+
+type edDecrypterSigner struct {
+ privateKey ed25519.PrivateKey
+}
+
+// newRSARecipient creates recipientKeyInfo based on the given key.
+func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) {
+ // Verify that key management algorithm is supported by this encrypter
+ switch keyAlg {
+ case RSA1_5, RSA_OAEP, RSA_OAEP_256:
+ default:
+ return recipientKeyInfo{}, ErrUnsupportedAlgorithm
+ }
+
+ if publicKey == nil {
+ return recipientKeyInfo{}, errors.New("invalid public key")
+ }
+
+ return recipientKeyInfo{
+ keyAlg: keyAlg,
+ keyEncrypter: &rsaEncrypterVerifier{
+ publicKey: publicKey,
+ },
+ }, nil
+}
+
+// newRSASigner creates a recipientSigInfo based on the given key.
+func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) {
+ // Verify that key management algorithm is supported by this encrypter
+ switch sigAlg {
+ case RS256, RS384, RS512, PS256, PS384, PS512:
+ default:
+ return recipientSigInfo{}, ErrUnsupportedAlgorithm
+ }
+
+ if privateKey == nil {
+ return recipientSigInfo{}, errors.New("invalid private key")
+ }
+
+ return recipientSigInfo{
+ sigAlg: sigAlg,
+ publicKey: staticPublicKey(&JSONWebKey{
+ Key: privateKey.Public(),
+ }),
+ signer: &rsaDecrypterSigner{
+ privateKey: privateKey,
+ },
+ }, nil
+}
+
+func newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) {
+ if sigAlg != EdDSA {
+ return recipientSigInfo{}, ErrUnsupportedAlgorithm
+ }
+
+ if privateKey == nil {
+ return recipientSigInfo{}, errors.New("invalid private key")
+ }
+ return recipientSigInfo{
+ sigAlg: sigAlg,
+ publicKey: staticPublicKey(&JSONWebKey{
+ Key: privateKey.Public(),
+ }),
+ signer: &edDecrypterSigner{
+ privateKey: privateKey,
+ },
+ }, nil
+}
+
+// newECDHRecipient creates recipientKeyInfo based on the given key.
+func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) {
+ // Verify that key management algorithm is supported by this encrypter
+ switch keyAlg {
+ case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
+ default:
+ return recipientKeyInfo{}, ErrUnsupportedAlgorithm
+ }
+
+ if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
+ return recipientKeyInfo{}, errors.New("invalid public key")
+ }
+
+ return recipientKeyInfo{
+ keyAlg: keyAlg,
+ keyEncrypter: &ecEncrypterVerifier{
+ publicKey: publicKey,
+ },
+ }, nil
+}
+
+// newECDSASigner creates a recipientSigInfo based on the given key.
+func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) {
+ // Verify that key management algorithm is supported by this encrypter
+ switch sigAlg {
+ case ES256, ES384, ES512:
+ default:
+ return recipientSigInfo{}, ErrUnsupportedAlgorithm
+ }
+
+ if privateKey == nil {
+ return recipientSigInfo{}, errors.New("invalid private key")
+ }
+
+ return recipientSigInfo{
+ sigAlg: sigAlg,
+ publicKey: staticPublicKey(&JSONWebKey{
+ Key: privateKey.Public(),
+ }),
+ signer: &ecDecrypterSigner{
+ privateKey: privateKey,
+ },
+ }, nil
+}
+
+// Encrypt the given payload and update the object.
+func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
+ encryptedKey, err := ctx.encrypt(cek, alg)
+ if err != nil {
+ return recipientInfo{}, err
+ }
+
+ return recipientInfo{
+ encryptedKey: encryptedKey,
+ header: &rawHeader{},
+ }, nil
+}
+
+// Encrypt the given payload. Based on the key encryption algorithm,
+// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
+func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) {
+ switch alg {
+ case RSA1_5:
+ return rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek)
+ case RSA_OAEP:
+ return rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{})
+ case RSA_OAEP_256:
+ return rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{})
+ }
+
+ return nil, ErrUnsupportedAlgorithm
+}
+
+// Decrypt the given payload and return the content encryption key.
+func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
+ return ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator)
+}
+
+// Decrypt the given payload. Based on the key encryption algorithm,
+// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
+func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) {
+ // Note: The random reader on decrypt operations is only used for blinding,
+ // so stubbing is meanlingless (hence the direct use of rand.Reader).
+ switch alg {
+ case RSA1_5:
+ defer func() {
+ // DecryptPKCS1v15SessionKey sometimes panics on an invalid payload
+ // because of an index out of bounds error, which we want to ignore.
+ // This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()
+ // only exists for preventing crashes with unpatched versions.
+ // See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k
+ // See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33
+ _ = recover()
+ }()
+
+ // Perform some input validation.
+ keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8
+ if keyBytes != len(jek) {
+ // Input size is incorrect, the encrypted payload should always match
+ // the size of the public modulus (e.g. using a 2048 bit key will
+ // produce 256 bytes of output). Reject this since it's invalid input.
+ return nil, ErrCryptoFailure
+ }
+
+ cek, _, err := generator.genKey()
+ if err != nil {
+ return nil, ErrCryptoFailure
+ }
+
+ // When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
+ // prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
+ // the Million Message Attack on Cryptographic Message Syntax". We are
+ // therefore deliberately ignoring errors here.
+ _ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)
+
+ return cek, nil
+ case RSA_OAEP:
+ // Use rand.Reader for RSA blinding
+ return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{})
+ case RSA_OAEP_256:
+ // Use rand.Reader for RSA blinding
+ return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{})
+ }
+
+ return nil, ErrUnsupportedAlgorithm
+}
+
+// Sign the given payload
+func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
+ var hash crypto.Hash
+
+ switch alg {
+ case RS256, PS256:
+ hash = crypto.SHA256
+ case RS384, PS384:
+ hash = crypto.SHA384
+ case RS512, PS512:
+ hash = crypto.SHA512
+ default:
+ return Signature{}, ErrUnsupportedAlgorithm
+ }
+
+ hasher := hash.New()
+
+ // According to documentation, Write() on hash never fails
+ _, _ = hasher.Write(payload)
+ hashed := hasher.Sum(nil)
+
+ var out []byte
+ var err error
+
+ switch alg {
+ case RS256, RS384, RS512:
+ // TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the
+ // random parameter is legacy and ignored, and it can be nil.
+ // https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1
+ out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
+ case PS256, PS384, PS512:
+ out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
+ SaltLength: rsa.PSSSaltLengthEqualsHash,
+ })
+ }
+
+ if err != nil {
+ return Signature{}, err
+ }
+
+ return Signature{
+ Signature: out,
+ protected: &rawHeader{},
+ }, nil
+}
+
+// Verify the given payload
+func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
+ var hash crypto.Hash
+
+ switch alg {
+ case RS256, PS256:
+ hash = crypto.SHA256
+ case RS384, PS384:
+ hash = crypto.SHA384
+ case RS512, PS512:
+ hash = crypto.SHA512
+ default:
+ return ErrUnsupportedAlgorithm
+ }
+
+ hasher := hash.New()
+
+ // According to documentation, Write() on hash never fails
+ _, _ = hasher.Write(payload)
+ hashed := hasher.Sum(nil)
+
+ switch alg {
+ case RS256, RS384, RS512:
+ return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)
+ case PS256, PS384, PS512:
+ return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)
+ }
+
+ return ErrUnsupportedAlgorithm
+}
+
+// Encrypt the given payload and update the object.
+func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
+ switch alg {
+ case ECDH_ES:
+ // ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key.
+ return recipientInfo{
+ header: &rawHeader{},
+ }, nil
+ case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
+ default:
+ return recipientInfo{}, ErrUnsupportedAlgorithm
+ }
+
+ generator := ecKeyGenerator{
+ algID: string(alg),
+ publicKey: ctx.publicKey,
+ }
+
+ switch alg {
+ case ECDH_ES_A128KW:
+ generator.size = 16
+ case ECDH_ES_A192KW:
+ generator.size = 24
+ case ECDH_ES_A256KW:
+ generator.size = 32
+ }
+
+ kek, header, err := generator.genKey()
+ if err != nil {
+ return recipientInfo{}, err
+ }
+
+ block, err := aes.NewCipher(kek)
+ if err != nil {
+ return recipientInfo{}, err
+ }
+
+ jek, err := josecipher.KeyWrap(block, cek)
+ if err != nil {
+ return recipientInfo{}, err
+ }
+
+ return recipientInfo{
+ encryptedKey: jek,
+ header: &header,
+ }, nil
+}
+
+// Get key size for EC key generator
+func (ctx ecKeyGenerator) keySize() int {
+ return ctx.size
+}
+
+// Get a content encryption key for ECDH-ES
+func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
+ priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader)
+ if err != nil {
+ return nil, rawHeader{}, err
+ }
+
+ out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size)
+
+ b, err := json.Marshal(&JSONWebKey{
+ Key: &priv.PublicKey,
+ })
+ if err != nil {
+ return nil, nil, err
+ }
+
+ headers := rawHeader{
+ headerEPK: makeRawMessage(b),
+ }
+
+ return out, headers, nil
+}
+
+// Decrypt the given payload and return the content encryption key.
+func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
+ epk, err := headers.getEPK()
+ if err != nil {
+ return nil, errors.New("go-jose/go-jose: invalid epk header")
+ }
+ if epk == nil {
+ return nil, errors.New("go-jose/go-jose: missing epk header")
+ }
+
+ publicKey, ok := epk.Key.(*ecdsa.PublicKey)
+ if publicKey == nil || !ok {
+ return nil, errors.New("go-jose/go-jose: invalid epk header")
+ }
+
+ if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
+ return nil, errors.New("go-jose/go-jose: invalid public key in epk header")
+ }
+
+ apuData, err := headers.getAPU()
+ if err != nil {
+ return nil, errors.New("go-jose/go-jose: invalid apu header")
+ }
+ apvData, err := headers.getAPV()
+ if err != nil {
+ return nil, errors.New("go-jose/go-jose: invalid apv header")
+ }
+
+ deriveKey := func(algID string, size int) []byte {
+ return josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size)
+ }
+
+ var keySize int
+
+ algorithm := headers.getAlgorithm()
+ switch algorithm {
+ case ECDH_ES:
+ // ECDH-ES uses direct key agreement, no key unwrapping necessary.
+ return deriveKey(string(headers.getEncryption()), generator.keySize()), nil
+ case ECDH_ES_A128KW:
+ keySize = 16
+ case ECDH_ES_A192KW:
+ keySize = 24
+ case ECDH_ES_A256KW:
+ keySize = 32
+ default:
+ return nil, ErrUnsupportedAlgorithm
+ }
+
+ key := deriveKey(string(algorithm), keySize)
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ return josecipher.KeyUnwrap(block, recipient.encryptedKey)
+}
+
+func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
+ if alg != EdDSA {
+ return Signature{}, ErrUnsupportedAlgorithm
+ }
+
+ sig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0))
+ if err != nil {
+ return Signature{}, err
+ }
+
+ return Signature{
+ Signature: sig,
+ protected: &rawHeader{},
+ }, nil
+}
+
+func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
+ if alg != EdDSA {
+ return ErrUnsupportedAlgorithm
+ }
+ ok := ed25519.Verify(ctx.publicKey, payload, signature)
+ if !ok {
+ return errors.New("go-jose/go-jose: ed25519 signature failed to verify")
+ }
+ return nil
+}
+
+// Sign the given payload
+func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
+ var expectedBitSize int
+ var hash crypto.Hash
+
+ switch alg {
+ case ES256:
+ expectedBitSize = 256
+ hash = crypto.SHA256
+ case ES384:
+ expectedBitSize = 384
+ hash = crypto.SHA384
+ case ES512:
+ expectedBitSize = 521
+ hash = crypto.SHA512
+ }
+
+ curveBits := ctx.privateKey.Curve.Params().BitSize
+ if expectedBitSize != curveBits {
+ return Signature{}, fmt.Errorf("go-jose/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
+ }
+
+ hasher := hash.New()
+
+ // According to documentation, Write() on hash never fails
+ _, _ = hasher.Write(payload)
+ hashed := hasher.Sum(nil)
+
+ r, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed)
+ if err != nil {
+ return Signature{}, err
+ }
+
+ keyBytes := curveBits / 8
+ if curveBits%8 > 0 {
+ keyBytes++
+ }
+
+ // We serialize the outputs (r and s) into big-endian byte arrays and pad
+ // them with zeros on the left to make sure the sizes work out. Both arrays
+ // must be keyBytes long, and the output must be 2*keyBytes long.
+ rBytes := r.Bytes()
+ rBytesPadded := make([]byte, keyBytes)
+ copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
+
+ sBytes := s.Bytes()
+ sBytesPadded := make([]byte, keyBytes)
+ copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
+
+ out := append(rBytesPadded, sBytesPadded...)
+
+ return Signature{
+ Signature: out,
+ protected: &rawHeader{},
+ }, nil
+}
+
+// Verify the given payload
+func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
+ var keySize int
+ var hash crypto.Hash
+
+ switch alg {
+ case ES256:
+ keySize = 32
+ hash = crypto.SHA256
+ case ES384:
+ keySize = 48
+ hash = crypto.SHA384
+ case ES512:
+ keySize = 66
+ hash = crypto.SHA512
+ default:
+ return ErrUnsupportedAlgorithm
+ }
+
+ if len(signature) != 2*keySize {
+ return fmt.Errorf("go-jose/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize)
+ }
+
+ hasher := hash.New()
+
+ // According to documentation, Write() on hash never fails
+ _, _ = hasher.Write(payload)
+ hashed := hasher.Sum(nil)
+
+ r := big.NewInt(0).SetBytes(signature[:keySize])
+ s := big.NewInt(0).SetBytes(signature[keySize:])
+
+ match := ecdsa.Verify(ctx.publicKey, hashed, r, s)
+ if !match {
+ return errors.New("go-jose/go-jose: ecdsa signature failed to verify")
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go b/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go
new file mode 100644
index 00000000000..af029cec0ba
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go
@@ -0,0 +1,196 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package josecipher
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/sha256"
+ "crypto/sha512"
+ "crypto/subtle"
+ "encoding/binary"
+ "errors"
+ "hash"
+)
+
+const (
+ nonceBytes = 16
+)
+
+// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC.
+func NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) {
+ keySize := len(key) / 2
+ integrityKey := key[:keySize]
+ encryptionKey := key[keySize:]
+
+ blockCipher, err := newBlockCipher(encryptionKey)
+ if err != nil {
+ return nil, err
+ }
+
+ var hash func() hash.Hash
+ switch keySize {
+ case 16:
+ hash = sha256.New
+ case 24:
+ hash = sha512.New384
+ case 32:
+ hash = sha512.New
+ }
+
+ return &cbcAEAD{
+ hash: hash,
+ blockCipher: blockCipher,
+ authtagBytes: keySize,
+ integrityKey: integrityKey,
+ }, nil
+}
+
+// An AEAD based on CBC+HMAC
+type cbcAEAD struct {
+ hash func() hash.Hash
+ authtagBytes int
+ integrityKey []byte
+ blockCipher cipher.Block
+}
+
+func (ctx *cbcAEAD) NonceSize() int {
+ return nonceBytes
+}
+
+func (ctx *cbcAEAD) Overhead() int {
+ // Maximum overhead is block size (for padding) plus auth tag length, where
+ // the length of the auth tag is equivalent to the key size.
+ return ctx.blockCipher.BlockSize() + ctx.authtagBytes
+}
+
+// Seal encrypts and authenticates the plaintext.
+func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
+ // Output buffer -- must take care not to mangle plaintext input.
+ ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]
+ copy(ciphertext, plaintext)
+ ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())
+
+ cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce)
+
+ cbc.CryptBlocks(ciphertext, ciphertext)
+ authtag := ctx.computeAuthTag(data, nonce, ciphertext)
+
+ ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))
+ copy(out, ciphertext)
+ copy(out[len(ciphertext):], authtag)
+
+ return ret
+}
+
+// Open decrypts and authenticates the ciphertext.
+func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
+ if len(ciphertext) < ctx.authtagBytes {
+ return nil, errors.New("go-jose/go-jose: invalid ciphertext (too short)")
+ }
+
+ offset := len(ciphertext) - ctx.authtagBytes
+ expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])
+ match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])
+ if match != 1 {
+ return nil, errors.New("go-jose/go-jose: invalid ciphertext (auth tag mismatch)")
+ }
+
+ cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)
+
+ // Make copy of ciphertext buffer, don't want to modify in place
+ buffer := append([]byte{}, ciphertext[:offset]...)
+
+ if len(buffer)%ctx.blockCipher.BlockSize() > 0 {
+ return nil, errors.New("go-jose/go-jose: invalid ciphertext (invalid length)")
+ }
+
+ cbc.CryptBlocks(buffer, buffer)
+
+ // Remove padding
+ plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize())
+ if err != nil {
+ return nil, err
+ }
+
+ ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))
+ copy(out, plaintext)
+
+ return ret, nil
+}
+
+// Compute an authentication tag
+func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
+ buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)
+ n := 0
+ n += copy(buffer, aad)
+ n += copy(buffer[n:], nonce)
+ n += copy(buffer[n:], ciphertext)
+ binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)
+
+ // According to documentation, Write() on hash.Hash never fails.
+ hmac := hmac.New(ctx.hash, ctx.integrityKey)
+ _, _ = hmac.Write(buffer)
+
+ return hmac.Sum(nil)[:ctx.authtagBytes]
+}
+
+// resize ensures that the given slice has a capacity of at least n bytes.
+// If the capacity of the slice is less than n, a new slice is allocated
+// and the existing data will be copied.
+func resize(in []byte, n uint64) (head, tail []byte) {
+ if uint64(cap(in)) >= n {
+ head = in[:n]
+ } else {
+ head = make([]byte, n)
+ copy(head, in)
+ }
+
+ tail = head[len(in):]
+ return
+}
+
+// Apply padding
+func padBuffer(buffer []byte, blockSize int) []byte {
+ missing := blockSize - (len(buffer) % blockSize)
+ ret, out := resize(buffer, uint64(len(buffer))+uint64(missing))
+ padding := bytes.Repeat([]byte{byte(missing)}, missing)
+ copy(out, padding)
+ return ret
+}
+
+// Remove padding
+func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) {
+ if len(buffer)%blockSize != 0 {
+ return nil, errors.New("go-jose/go-jose: invalid padding")
+ }
+
+ last := buffer[len(buffer)-1]
+ count := int(last)
+
+ if count == 0 || count > blockSize || count > len(buffer) {
+ return nil, errors.New("go-jose/go-jose: invalid padding")
+ }
+
+ padding := bytes.Repeat([]byte{last}, count)
+ if !bytes.HasSuffix(buffer, padding) {
+ return nil, errors.New("go-jose/go-jose: invalid padding")
+ }
+
+ return buffer[:len(buffer)-count], nil
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go b/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go
new file mode 100644
index 00000000000..f62c3bdba5d
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go
@@ -0,0 +1,75 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package josecipher
+
+import (
+ "crypto"
+ "encoding/binary"
+ "hash"
+ "io"
+)
+
+type concatKDF struct {
+ z, info []byte
+ i uint32
+ cache []byte
+ hasher hash.Hash
+}
+
+// NewConcatKDF builds a KDF reader based on the given inputs.
+func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {
+ buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))
+ n := 0
+ n += copy(buffer, algID)
+ n += copy(buffer[n:], ptyUInfo)
+ n += copy(buffer[n:], ptyVInfo)
+ n += copy(buffer[n:], supPubInfo)
+ copy(buffer[n:], supPrivInfo)
+
+ hasher := hash.New()
+
+ return &concatKDF{
+ z: z,
+ info: buffer,
+ hasher: hasher,
+ cache: []byte{},
+ i: 1,
+ }
+}
+
+func (ctx *concatKDF) Read(out []byte) (int, error) {
+ copied := copy(out, ctx.cache)
+ ctx.cache = ctx.cache[copied:]
+
+ for copied < len(out) {
+ ctx.hasher.Reset()
+
+ // Write on a hash.Hash never fails
+ _ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i)
+ _, _ = ctx.hasher.Write(ctx.z)
+ _, _ = ctx.hasher.Write(ctx.info)
+
+ hash := ctx.hasher.Sum(nil)
+ chunkCopied := copy(out[copied:], hash)
+ copied += chunkCopied
+ ctx.cache = hash[chunkCopied:]
+
+ ctx.i++
+ }
+
+ return copied, nil
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go b/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go
new file mode 100644
index 00000000000..093c646740b
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go
@@ -0,0 +1,86 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package josecipher
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "encoding/binary"
+)
+
+// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.
+// It is an error to call this function with a private/public key that are not on the same
+// curve. Callers must ensure that the keys are valid before calling this function. Output
+// size may be at most 1<<16 bytes (64 KiB).
+func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {
+ if size > 1<<16 {
+ panic("ECDH-ES output size too large, must be less than or equal to 1<<16")
+ }
+
+ // algId, partyUInfo, partyVInfo inputs must be prefixed with the length
+ algID := lengthPrefixed([]byte(alg))
+ ptyUInfo := lengthPrefixed(apuData)
+ ptyVInfo := lengthPrefixed(apvData)
+
+ // suppPubInfo is the encoded length of the output size in bits
+ supPubInfo := make([]byte, 4)
+ binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)
+
+ if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {
+ panic("public key not on same curve as private key")
+ }
+
+ z, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
+ zBytes := z.Bytes()
+
+ // Note that calling z.Bytes() on a big.Int may strip leading zero bytes from
+ // the returned byte array. This can lead to a problem where zBytes will be
+ // shorter than expected which breaks the key derivation. Therefore we must pad
+ // to the full length of the expected coordinate here before calling the KDF.
+ octSize := dSize(priv.Curve)
+ if len(zBytes) != octSize {
+ zBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...)
+ }
+
+ reader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
+ key := make([]byte, size)
+
+ // Read on the KDF will never fail
+ _, _ = reader.Read(key)
+
+ return key
+}
+
+// dSize returns the size in octets for a coordinate on a elliptic curve.
+func dSize(curve elliptic.Curve) int {
+ order := curve.Params().P
+ bitLen := order.BitLen()
+ size := bitLen / 8
+ if bitLen%8 != 0 {
+ size++
+ }
+ return size
+}
+
+func lengthPrefixed(data []byte) []byte {
+ out := make([]byte, len(data)+4)
+ binary.BigEndian.PutUint32(out, uint32(len(data)))
+ copy(out[4:], data)
+ return out
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go b/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go
new file mode 100644
index 00000000000..b9effbca8a4
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go
@@ -0,0 +1,109 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package josecipher
+
+import (
+ "crypto/cipher"
+ "crypto/subtle"
+ "encoding/binary"
+ "errors"
+)
+
+var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}
+
+// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher.
+func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
+ if len(cek)%8 != 0 {
+ return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
+ }
+
+ n := len(cek) / 8
+ r := make([][]byte, n)
+
+ for i := range r {
+ r[i] = make([]byte, 8)
+ copy(r[i], cek[i*8:])
+ }
+
+ buffer := make([]byte, 16)
+ tBytes := make([]byte, 8)
+ copy(buffer, defaultIV)
+
+ for t := 0; t < 6*n; t++ {
+ copy(buffer[8:], r[t%n])
+
+ block.Encrypt(buffer, buffer)
+
+ binary.BigEndian.PutUint64(tBytes, uint64(t+1))
+
+ for i := 0; i < 8; i++ {
+ buffer[i] ^= tBytes[i]
+ }
+ copy(r[t%n], buffer[8:])
+ }
+
+ out := make([]byte, (n+1)*8)
+ copy(out, buffer[:8])
+ for i := range r {
+ copy(out[(i+1)*8:], r[i])
+ }
+
+ return out, nil
+}
+
+// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher.
+func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
+ if len(ciphertext)%8 != 0 {
+ return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
+ }
+
+ n := (len(ciphertext) / 8) - 1
+ r := make([][]byte, n)
+
+ for i := range r {
+ r[i] = make([]byte, 8)
+ copy(r[i], ciphertext[(i+1)*8:])
+ }
+
+ buffer := make([]byte, 16)
+ tBytes := make([]byte, 8)
+ copy(buffer[:8], ciphertext[:8])
+
+ for t := 6*n - 1; t >= 0; t-- {
+ binary.BigEndian.PutUint64(tBytes, uint64(t+1))
+
+ for i := 0; i < 8; i++ {
+ buffer[i] ^= tBytes[i]
+ }
+ copy(buffer[8:], r[t%n])
+
+ block.Decrypt(buffer, buffer)
+
+ copy(r[t%n], buffer[8:])
+ }
+
+ if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 {
+ return nil, errors.New("go-jose/go-jose: failed to unwrap key")
+ }
+
+ out := make([]byte, n*8)
+ for i := range r {
+ copy(out[i*8:], r[i])
+ }
+
+ return out, nil
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/crypter.go b/vendor/github.com/go-jose/go-jose/v4/crypter.go
new file mode 100644
index 00000000000..aba08424c38
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/crypter.go
@@ -0,0 +1,593 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jose
+
+import (
+ "crypto/ecdsa"
+ "crypto/rsa"
+ "errors"
+ "fmt"
+
+ "github.com/go-jose/go-jose/v4/json"
+)
+
+// Encrypter represents an encrypter which produces an encrypted JWE object.
+type Encrypter interface {
+ Encrypt(plaintext []byte) (*JSONWebEncryption, error)
+ EncryptWithAuthData(plaintext []byte, aad []byte) (*JSONWebEncryption, error)
+ Options() EncrypterOptions
+}
+
+// A generic content cipher
+type contentCipher interface {
+ keySize() int
+ encrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error)
+ decrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error)
+}
+
+// A key generator (for generating/getting a CEK)
+type keyGenerator interface {
+ keySize() int
+ genKey() ([]byte, rawHeader, error)
+}
+
+// A generic key encrypter
+type keyEncrypter interface {
+ encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key
+}
+
+// A generic key decrypter
+type keyDecrypter interface {
+ decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key
+}
+
+// A generic encrypter based on the given key encrypter and content cipher.
+type genericEncrypter struct {
+ contentAlg ContentEncryption
+ compressionAlg CompressionAlgorithm
+ cipher contentCipher
+ recipients []recipientKeyInfo
+ keyGenerator keyGenerator
+ extraHeaders map[HeaderKey]interface{}
+}
+
+type recipientKeyInfo struct {
+ keyID string
+ keyAlg KeyAlgorithm
+ keyEncrypter keyEncrypter
+}
+
+// EncrypterOptions represents options that can be set on new encrypters.
+type EncrypterOptions struct {
+ Compression CompressionAlgorithm
+
+ // Optional map of name/value pairs to be inserted into the protected
+ // header of a JWS object. Some specifications which make use of
+ // JWS require additional values here.
+ //
+ // Values will be serialized by [json.Marshal] and must be valid inputs to
+ // that function.
+ //
+ // [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
+ ExtraHeaders map[HeaderKey]interface{}
+}
+
+// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
+// if necessary, and returns the updated EncrypterOptions.
+//
+// The v parameter will be serialized by [json.Marshal] and must be a valid
+// input to that function.
+//
+// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
+func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {
+ if eo.ExtraHeaders == nil {
+ eo.ExtraHeaders = map[HeaderKey]interface{}{}
+ }
+ eo.ExtraHeaders[k] = v
+ return eo
+}
+
+// WithContentType adds a content type ("cty") header and returns the updated
+// EncrypterOptions.
+func (eo *EncrypterOptions) WithContentType(contentType ContentType) *EncrypterOptions {
+ return eo.WithHeader(HeaderContentType, contentType)
+}
+
+// WithType adds a type ("typ") header and returns the updated EncrypterOptions.
+func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions {
+ return eo.WithHeader(HeaderType, typ)
+}
+
+// Recipient represents an algorithm/key to encrypt messages to.
+//
+// PBES2Count and PBES2Salt correspond with the "p2c" and "p2s" headers used
+// on the password-based encryption algorithms PBES2-HS256+A128KW,
+// PBES2-HS384+A192KW, and PBES2-HS512+A256KW. If they are not provided a safe
+// default of 100000 will be used for the count and a 128-bit random salt will
+// be generated.
+type Recipient struct {
+ Algorithm KeyAlgorithm
+ // Key must have one of these types:
+ // - ed25519.PublicKey
+ // - *ecdsa.PublicKey
+ // - *rsa.PublicKey
+ // - *JSONWebKey
+ // - JSONWebKey
+ // - []byte (a symmetric key)
+ // - Any type that satisfies the OpaqueKeyEncrypter interface
+ //
+ // The type of Key must match the value of Algorithm.
+ Key interface{}
+ KeyID string
+ PBES2Count int
+ PBES2Salt []byte
+}
+
+// NewEncrypter creates an appropriate encrypter based on the key type
+func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) {
+ encrypter := &genericEncrypter{
+ contentAlg: enc,
+ recipients: []recipientKeyInfo{},
+ cipher: getContentCipher(enc),
+ }
+ if opts != nil {
+ encrypter.compressionAlg = opts.Compression
+ encrypter.extraHeaders = opts.ExtraHeaders
+ }
+
+ if encrypter.cipher == nil {
+ return nil, ErrUnsupportedAlgorithm
+ }
+
+ var keyID string
+ var rawKey interface{}
+ switch encryptionKey := rcpt.Key.(type) {
+ case JSONWebKey:
+ keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key
+ case *JSONWebKey:
+ keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key
+ case OpaqueKeyEncrypter:
+ keyID, rawKey = encryptionKey.KeyID(), encryptionKey
+ default:
+ rawKey = encryptionKey
+ }
+
+ switch rcpt.Algorithm {
+ case DIRECT:
+ // Direct encryption mode must be treated differently
+ keyBytes, ok := rawKey.([]byte)
+ if !ok {
+ return nil, ErrUnsupportedKeyType
+ }
+ if encrypter.cipher.keySize() != len(keyBytes) {
+ return nil, ErrInvalidKeySize
+ }
+ encrypter.keyGenerator = staticKeyGenerator{
+ key: keyBytes,
+ }
+ recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes)
+ recipientInfo.keyID = keyID
+ if rcpt.KeyID != "" {
+ recipientInfo.keyID = rcpt.KeyID
+ }
+ encrypter.recipients = []recipientKeyInfo{recipientInfo}
+ return encrypter, nil
+ case ECDH_ES:
+ // ECDH-ES (w/o key wrapping) is similar to DIRECT mode
+ keyDSA, ok := rawKey.(*ecdsa.PublicKey)
+ if !ok {
+ return nil, ErrUnsupportedKeyType
+ }
+ encrypter.keyGenerator = ecKeyGenerator{
+ size: encrypter.cipher.keySize(),
+ algID: string(enc),
+ publicKey: keyDSA,
+ }
+ recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA)
+ recipientInfo.keyID = keyID
+ if rcpt.KeyID != "" {
+ recipientInfo.keyID = rcpt.KeyID
+ }
+ encrypter.recipients = []recipientKeyInfo{recipientInfo}
+ return encrypter, nil
+ default:
+ // Can just add a standard recipient
+ encrypter.keyGenerator = randomKeyGenerator{
+ size: encrypter.cipher.keySize(),
+ }
+ err := encrypter.addRecipient(rcpt)
+ return encrypter, err
+ }
+}
+
+// NewMultiEncrypter creates a multi-encrypter based on the given parameters
+func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error) {
+ cipher := getContentCipher(enc)
+
+ if cipher == nil {
+ return nil, ErrUnsupportedAlgorithm
+ }
+ if len(rcpts) == 0 {
+ return nil, fmt.Errorf("go-jose/go-jose: recipients is nil or empty")
+ }
+
+ encrypter := &genericEncrypter{
+ contentAlg: enc,
+ recipients: []recipientKeyInfo{},
+ cipher: cipher,
+ keyGenerator: randomKeyGenerator{
+ size: cipher.keySize(),
+ },
+ }
+
+ if opts != nil {
+ encrypter.compressionAlg = opts.Compression
+ encrypter.extraHeaders = opts.ExtraHeaders
+ }
+
+ for _, recipient := range rcpts {
+ err := encrypter.addRecipient(recipient)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return encrypter, nil
+}
+
+func (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) {
+ var recipientInfo recipientKeyInfo
+
+ switch recipient.Algorithm {
+ case DIRECT, ECDH_ES:
+ return fmt.Errorf("go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm)
+ }
+
+ recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key)
+ if recipient.KeyID != "" {
+ recipientInfo.keyID = recipient.KeyID
+ }
+
+ switch recipient.Algorithm {
+ case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
+ if sr, ok := recipientInfo.keyEncrypter.(*symmetricKeyCipher); ok {
+ sr.p2c = recipient.PBES2Count
+ sr.p2s = recipient.PBES2Salt
+ }
+ }
+
+ if err == nil {
+ ctx.recipients = append(ctx.recipients, recipientInfo)
+ }
+ return err
+}
+
+func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) {
+ switch encryptionKey := encryptionKey.(type) {
+ case *rsa.PublicKey:
+ return newRSARecipient(alg, encryptionKey)
+ case *ecdsa.PublicKey:
+ return newECDHRecipient(alg, encryptionKey)
+ case []byte:
+ return newSymmetricRecipient(alg, encryptionKey)
+ case string:
+ return newSymmetricRecipient(alg, []byte(encryptionKey))
+ case *JSONWebKey:
+ recipient, err := makeJWERecipient(alg, encryptionKey.Key)
+ recipient.keyID = encryptionKey.KeyID
+ return recipient, err
+ case OpaqueKeyEncrypter:
+ return newOpaqueKeyEncrypter(alg, encryptionKey)
+ }
+ return recipientKeyInfo{}, ErrUnsupportedKeyType
+}
+
+// newDecrypter creates an appropriate decrypter based on the key type
+func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {
+ switch decryptionKey := decryptionKey.(type) {
+ case *rsa.PrivateKey:
+ return &rsaDecrypterSigner{
+ privateKey: decryptionKey,
+ }, nil
+ case *ecdsa.PrivateKey:
+ return &ecDecrypterSigner{
+ privateKey: decryptionKey,
+ }, nil
+ case []byte:
+ return &symmetricKeyCipher{
+ key: decryptionKey,
+ }, nil
+ case string:
+ return &symmetricKeyCipher{
+ key: []byte(decryptionKey),
+ }, nil
+ case JSONWebKey:
+ return newDecrypter(decryptionKey.Key)
+ case *JSONWebKey:
+ return newDecrypter(decryptionKey.Key)
+ case OpaqueKeyDecrypter:
+ return &opaqueKeyDecrypter{decrypter: decryptionKey}, nil
+ default:
+ return nil, ErrUnsupportedKeyType
+ }
+}
+
+// Implementation of encrypt method producing a JWE object.
+func (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JSONWebEncryption, error) {
+ return ctx.EncryptWithAuthData(plaintext, nil)
+}
+
+// Implementation of encrypt method producing a JWE object.
+func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryption, error) {
+ obj := &JSONWebEncryption{}
+ obj.aad = aad
+
+ obj.protected = &rawHeader{}
+ err := obj.protected.set(headerEncryption, ctx.contentAlg)
+ if err != nil {
+ return nil, err
+ }
+
+ obj.recipients = make([]recipientInfo, len(ctx.recipients))
+
+ if len(ctx.recipients) == 0 {
+ return nil, fmt.Errorf("go-jose/go-jose: no recipients to encrypt to")
+ }
+
+ cek, headers, err := ctx.keyGenerator.genKey()
+ if err != nil {
+ return nil, err
+ }
+
+ obj.protected.merge(&headers)
+
+ for i, info := range ctx.recipients {
+ recipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg)
+ if err != nil {
+ return nil, err
+ }
+
+ err = recipient.header.set(headerAlgorithm, info.keyAlg)
+ if err != nil {
+ return nil, err
+ }
+
+ if info.keyID != "" {
+ err = recipient.header.set(headerKeyID, info.keyID)
+ if err != nil {
+ return nil, err
+ }
+ }
+ obj.recipients[i] = recipient
+ }
+
+ if len(ctx.recipients) == 1 {
+ // Move per-recipient headers into main protected header if there's
+ // only a single recipient.
+ obj.protected.merge(obj.recipients[0].header)
+ obj.recipients[0].header = nil
+ }
+
+ if ctx.compressionAlg != NONE {
+ plaintext, err = compress(ctx.compressionAlg, plaintext)
+ if err != nil {
+ return nil, err
+ }
+
+ err = obj.protected.set(headerCompression, ctx.compressionAlg)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ for k, v := range ctx.extraHeaders {
+ b, err := json.Marshal(v)
+ if err != nil {
+ return nil, err
+ }
+ (*obj.protected)[k] = makeRawMessage(b)
+ }
+
+ authData := obj.computeAuthData()
+ parts, err := ctx.cipher.encrypt(cek, authData, plaintext)
+ if err != nil {
+ return nil, err
+ }
+
+ obj.iv = parts.iv
+ obj.ciphertext = parts.ciphertext
+ obj.tag = parts.tag
+
+ return obj, nil
+}
+
+func (ctx *genericEncrypter) Options() EncrypterOptions {
+ return EncrypterOptions{
+ Compression: ctx.compressionAlg,
+ ExtraHeaders: ctx.extraHeaders,
+ }
+}
+
+// Decrypt and validate the object and return the plaintext. This
+// function does not support multi-recipient. If you desire multi-recipient
+// decryption use DecryptMulti instead.
+//
+// The decryptionKey argument must contain a private or symmetric key
+// and must have one of these types:
+// - *ecdsa.PrivateKey
+// - *rsa.PrivateKey
+// - *JSONWebKey
+// - JSONWebKey
+// - *JSONWebKeySet
+// - JSONWebKeySet
+// - []byte (a symmetric key)
+// - string (a symmetric key)
+// - Any type that satisfies the OpaqueKeyDecrypter interface.
+//
+// Note that ed25519 is only available for signatures, not encryption, so is
+// not an option here.
+//
+// Automatically decompresses plaintext, but returns an error if the decompressed
+// data would be >250kB or >10x the size of the compressed data, whichever is larger.
+func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
+ headers := obj.mergedHeaders(nil)
+
+ if len(obj.recipients) > 1 {
+ return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one")
+ }
+
+ critical, err := headers.getCritical()
+ if err != nil {
+ return nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
+ }
+
+ if len(critical) > 0 {
+ return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
+ }
+
+ key := tryJWKS(decryptionKey, obj.Header)
+ decrypter, err := newDecrypter(key)
+ if err != nil {
+ return nil, err
+ }
+
+ cipher := getContentCipher(headers.getEncryption())
+ if cipher == nil {
+ return nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(headers.getEncryption()))
+ }
+
+ generator := randomKeyGenerator{
+ size: cipher.keySize(),
+ }
+
+ parts := &aeadParts{
+ iv: obj.iv,
+ ciphertext: obj.ciphertext,
+ tag: obj.tag,
+ }
+
+ authData := obj.computeAuthData()
+
+ var plaintext []byte
+ recipient := obj.recipients[0]
+ recipientHeaders := obj.mergedHeaders(&recipient)
+
+ cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
+ if err == nil {
+ // Found a valid CEK -- let's try to decrypt.
+ plaintext, err = cipher.decrypt(cek, authData, parts)
+ }
+
+ if plaintext == nil {
+ return nil, ErrCryptoFailure
+ }
+
+ // The "zip" header parameter may only be present in the protected header.
+ if comp := obj.protected.getCompression(); comp != "" {
+ plaintext, err = decompress(comp, plaintext)
+ if err != nil {
+ return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
+ }
+ }
+
+ return plaintext, nil
+}
+
+// DecryptMulti decrypts and validates the object and returns the plaintexts,
+// with support for multiple recipients. It returns the index of the recipient
+// for which the decryption was successful, the merged headers for that recipient,
+// and the plaintext.
+//
+// The decryptionKey argument must have one of the types allowed for the
+// decryptionKey argument of Decrypt().
+//
+// Automatically decompresses plaintext, but returns an error if the decompressed
+// data would be >250kB or >3x the size of the compressed data, whichever is larger.
+func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
+ globalHeaders := obj.mergedHeaders(nil)
+
+ critical, err := globalHeaders.getCritical()
+ if err != nil {
+ return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
+ }
+
+ if len(critical) > 0 {
+ return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
+ }
+
+ key := tryJWKS(decryptionKey, obj.Header)
+ decrypter, err := newDecrypter(key)
+ if err != nil {
+ return -1, Header{}, nil, err
+ }
+
+ encryption := globalHeaders.getEncryption()
+ cipher := getContentCipher(encryption)
+ if cipher == nil {
+ return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(encryption))
+ }
+
+ generator := randomKeyGenerator{
+ size: cipher.keySize(),
+ }
+
+ parts := &aeadParts{
+ iv: obj.iv,
+ ciphertext: obj.ciphertext,
+ tag: obj.tag,
+ }
+
+ authData := obj.computeAuthData()
+
+ index := -1
+ var plaintext []byte
+ var headers rawHeader
+
+ for i, recipient := range obj.recipients {
+ recipientHeaders := obj.mergedHeaders(&recipient)
+
+ cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
+ if err == nil {
+ // Found a valid CEK -- let's try to decrypt.
+ plaintext, err = cipher.decrypt(cek, authData, parts)
+ if err == nil {
+ index = i
+ headers = recipientHeaders
+ break
+ }
+ }
+ }
+
+ if plaintext == nil {
+ return -1, Header{}, nil, ErrCryptoFailure
+ }
+
+ // The "zip" header parameter may only be present in the protected header.
+ if comp := obj.protected.getCompression(); comp != "" {
+ plaintext, err = decompress(comp, plaintext)
+ if err != nil {
+ return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
+ }
+ }
+
+ sanitized, err := headers.sanitized()
+ if err != nil {
+ return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to sanitize header: %v", err)
+ }
+
+ return index, sanitized, plaintext, err
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/doc.go b/vendor/github.com/go-jose/go-jose/v4/doc.go
new file mode 100644
index 00000000000..0ad40ca085f
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/doc.go
@@ -0,0 +1,25 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+Package jose aims to provide an implementation of the Javascript Object Signing
+and Encryption set of standards. It implements encryption and signing based on
+the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web
+Token support available in a sub-package. The library supports both the compact
+and JWS/JWE JSON Serialization formats, and has optional support for multiple
+recipients.
+*/
+package jose
diff --git a/vendor/github.com/go-jose/go-jose/v4/encoding.go b/vendor/github.com/go-jose/go-jose/v4/encoding.go
new file mode 100644
index 00000000000..4f6e0d4a5cf
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/encoding.go
@@ -0,0 +1,228 @@
+/*-
+ * Copyright 2014 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jose
+
+import (
+ "bytes"
+ "compress/flate"
+ "encoding/base64"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "math/big"
+ "strings"
+ "unicode"
+
+ "github.com/go-jose/go-jose/v4/json"
+)
+
+// Helper function to serialize known-good objects.
+// Precondition: value is not a nil pointer.
+func mustSerializeJSON(value interface{}) []byte {
+ out, err := json.Marshal(value)
+ if err != nil {
+ panic(err)
+ }
+ // We never want to serialize the top-level value "null," since it's not a
+ // valid JOSE message. But if a caller passes in a nil pointer to this method,
+ // MarshalJSON will happily serialize it as the top-level value "null". If
+ // that value is then embedded in another operation, for instance by being
+ // base64-encoded and fed as input to a signing algorithm
+ // (https://github.com/go-jose/go-jose/issues/22), the result will be
+ // incorrect. Because this method is intended for known-good objects, and a nil
+ // pointer is not a known-good object, we are free to panic in this case.
+ // Note: It's not possible to directly check whether the data pointed at by an
+ // interface is a nil pointer, so we do this hacky workaround.
+ // https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I
+ if string(out) == "null" {
+ panic("Tried to serialize a nil pointer.")
+ }
+ return out
+}
+
+// Strip all newlines and whitespace
+func stripWhitespace(data string) string {
+ buf := strings.Builder{}
+ buf.Grow(len(data))
+ for _, r := range data {
+ if !unicode.IsSpace(r) {
+ buf.WriteRune(r)
+ }
+ }
+ return buf.String()
+}
+
+// Perform compression based on algorithm
+func compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
+ switch algorithm {
+ case DEFLATE:
+ return deflate(input)
+ default:
+ return nil, ErrUnsupportedAlgorithm
+ }
+}
+
+// Perform decompression based on algorithm
+func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
+ switch algorithm {
+ case DEFLATE:
+ return inflate(input)
+ default:
+ return nil, ErrUnsupportedAlgorithm
+ }
+}
+
+// deflate compresses the input.
+func deflate(input []byte) ([]byte, error) {
+ output := new(bytes.Buffer)
+
+ // Writing to byte buffer, err is always nil
+ writer, _ := flate.NewWriter(output, 1)
+ _, _ = io.Copy(writer, bytes.NewBuffer(input))
+
+ err := writer.Close()
+ return output.Bytes(), err
+}
+
+// inflate decompresses the input.
+//
+// Errors if the decompressed data would be >250kB or >10x the size of the
+// compressed data, whichever is larger.
+func inflate(input []byte) ([]byte, error) {
+ output := new(bytes.Buffer)
+ reader := flate.NewReader(bytes.NewBuffer(input))
+
+ maxCompressedSize := max(250_000, 10*int64(len(input)))
+
+ limit := maxCompressedSize + 1
+ n, err := io.CopyN(output, reader, limit)
+ if err != nil && err != io.EOF {
+ return nil, err
+ }
+ if n == limit {
+ return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize)
+ }
+
+ err = reader.Close()
+ return output.Bytes(), err
+}
+
+// byteBuffer represents a slice of bytes that can be serialized to url-safe base64.
+type byteBuffer struct {
+ data []byte
+}
+
+func newBuffer(data []byte) *byteBuffer {
+ if data == nil {
+ return nil
+ }
+ return &byteBuffer{
+ data: data,
+ }
+}
+
+func newFixedSizeBuffer(data []byte, length int) *byteBuffer {
+ if len(data) > length {
+ panic("go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)")
+ }
+ pad := make([]byte, length-len(data))
+ return newBuffer(append(pad, data...))
+}
+
+func newBufferFromInt(num uint64) *byteBuffer {
+ data := make([]byte, 8)
+ binary.BigEndian.PutUint64(data, num)
+ return newBuffer(bytes.TrimLeft(data, "\x00"))
+}
+
+func (b *byteBuffer) MarshalJSON() ([]byte, error) {
+ return json.Marshal(b.base64())
+}
+
+func (b *byteBuffer) UnmarshalJSON(data []byte) error {
+ var encoded string
+ err := json.Unmarshal(data, &encoded)
+ if err != nil {
+ return err
+ }
+
+ if encoded == "" {
+ return nil
+ }
+
+ decoded, err := base64.RawURLEncoding.DecodeString(encoded)
+ if err != nil {
+ return err
+ }
+
+ *b = *newBuffer(decoded)
+
+ return nil
+}
+
+func (b *byteBuffer) base64() string {
+ return base64.RawURLEncoding.EncodeToString(b.data)
+}
+
+func (b *byteBuffer) bytes() []byte {
+ // Handling nil here allows us to transparently handle nil slices when serializing.
+ if b == nil {
+ return nil
+ }
+ return b.data
+}
+
+func (b byteBuffer) bigInt() *big.Int {
+ return new(big.Int).SetBytes(b.data)
+}
+
+func (b byteBuffer) toInt() int {
+ return int(b.bigInt().Int64())
+}
+
+func base64EncodeLen(sl []byte) int {
+ return base64.RawURLEncoding.EncodedLen(len(sl))
+}
+
+func base64JoinWithDots(inputs ...[]byte) string {
+ if len(inputs) == 0 {
+ return ""
+ }
+
+ // Count of dots.
+ totalCount := len(inputs) - 1
+
+ for _, input := range inputs {
+ totalCount += base64EncodeLen(input)
+ }
+
+ out := make([]byte, totalCount)
+ startEncode := 0
+ for i, input := range inputs {
+ base64.RawURLEncoding.Encode(out[startEncode:], input)
+
+ if i == len(inputs)-1 {
+ continue
+ }
+
+ startEncode += base64EncodeLen(input)
+ out[startEncode] = '.'
+ startEncode++
+ }
+
+ return string(out)
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/json/LICENSE b/vendor/github.com/go-jose/go-jose/v4/json/LICENSE
new file mode 100644
index 00000000000..74487567632
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/json/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/go-jose/go-jose/v4/json/README.md b/vendor/github.com/go-jose/go-jose/v4/json/README.md
new file mode 100644
index 00000000000..86de5e5581f
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/json/README.md
@@ -0,0 +1,13 @@
+# Safe JSON
+
+This repository contains a fork of the `encoding/json` package from Go 1.6.
+
+The following changes were made:
+
+* Object deserialization uses case-sensitive member name matching instead of
+ [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).
+ This is to avoid differences in the interpretation of JOSE messages between
+ go-jose and libraries written in other languages.
+* When deserializing a JSON object, we check for duplicate keys and reject the
+ input whenever we detect a duplicate. Rather than trying to work with malformed
+ data, we prefer to reject it right away.
diff --git a/vendor/github.com/go-jose/go-jose/v4/json/decode.go b/vendor/github.com/go-jose/go-jose/v4/json/decode.go
new file mode 100644
index 00000000000..50634dd8478
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/json/decode.go
@@ -0,0 +1,1216 @@
+// Copyright 2010 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.
+
+// Represents JSON data structure using native Go types: booleans, floats,
+// strings, arrays, and maps.
+
+package json
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "math"
+ "reflect"
+ "runtime"
+ "strconv"
+ "unicode"
+ "unicode/utf16"
+ "unicode/utf8"
+)
+
+// Unmarshal parses the JSON-encoded data and stores the result
+// in the value pointed to by v.
+//
+// Unmarshal uses the inverse of the encodings that
+// Marshal uses, allocating maps, slices, and pointers as necessary,
+// with the following additional rules:
+//
+// To unmarshal JSON into a pointer, Unmarshal first handles the case of
+// the JSON being the JSON literal null. In that case, Unmarshal sets
+// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
+// the value pointed at by the pointer. If the pointer is nil, Unmarshal
+// allocates a new value for it to point to.
+//
+// To unmarshal JSON into a struct, Unmarshal matches incoming object
+// keys to the keys used by Marshal (either the struct field name or its tag),
+// preferring an exact match but also accepting a case-insensitive match.
+// Unmarshal will only set exported fields of the struct.
+//
+// To unmarshal JSON into an interface value,
+// Unmarshal stores one of these in the interface value:
+//
+// bool, for JSON booleans
+// float64, for JSON numbers
+// string, for JSON strings
+// []interface{}, for JSON arrays
+// map[string]interface{}, for JSON objects
+// nil for JSON null
+//
+// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
+// to zero and then appends each element to the slice.
+// As a special case, to unmarshal an empty JSON array into a slice,
+// Unmarshal replaces the slice with a new empty slice.
+//
+// To unmarshal a JSON array into a Go array, Unmarshal decodes
+// JSON array elements into corresponding Go array elements.
+// If the Go array is smaller than the JSON array,
+// the additional JSON array elements are discarded.
+// If the JSON array is smaller than the Go array,
+// the additional Go array elements are set to zero values.
+//
+// To unmarshal a JSON object into a string-keyed map, Unmarshal first
+// establishes a map to use, If the map is nil, Unmarshal allocates a new map.
+// Otherwise Unmarshal reuses the existing map, keeping existing entries.
+// Unmarshal then stores key-value pairs from the JSON object into the map.
+//
+// If a JSON value is not appropriate for a given target type,
+// or if a JSON number overflows the target type, Unmarshal
+// skips that field and completes the unmarshaling as best it can.
+// If no more serious errors are encountered, Unmarshal returns
+// an UnmarshalTypeError describing the earliest such error.
+//
+// The JSON null value unmarshals into an interface, map, pointer, or slice
+// by setting that Go value to nil. Because null is often used in JSON to mean
+// “not present,” unmarshaling a JSON null into any other Go type has no effect
+// on the value and produces no error.
+//
+// When unmarshaling quoted strings, invalid UTF-8 or
+// invalid UTF-16 surrogate pairs are not treated as an error.
+// Instead, they are replaced by the Unicode replacement
+// character U+FFFD.
+func Unmarshal(data []byte, v interface{}) error {
+ // Check for well-formedness.
+ // Avoids filling out half a data structure
+ // before discovering a JSON syntax error.
+ var d decodeState
+ err := checkValid(data, &d.scan)
+ if err != nil {
+ return err
+ }
+
+ d.init(data)
+ return d.unmarshal(v)
+}
+
+// Unmarshaler is the interface implemented by objects
+// that can unmarshal a JSON description of themselves.
+// The input can be assumed to be a valid encoding of
+// a JSON value. UnmarshalJSON must copy the JSON data
+// if it wishes to retain the data after returning.
+type Unmarshaler interface {
+ UnmarshalJSON([]byte) error
+}
+
+// An UnmarshalTypeError describes a JSON value that was
+// not appropriate for a value of a specific Go type.
+type UnmarshalTypeError struct {
+ Value string // description of JSON value - "bool", "array", "number -5"
+ Type reflect.Type // type of Go value it could not be assigned to
+ Offset int64 // error occurred after reading Offset bytes
+}
+
+func (e *UnmarshalTypeError) Error() string {
+ return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
+}
+
+// An UnmarshalFieldError describes a JSON object key that
+// led to an unexported (and therefore unwritable) struct field.
+// (No longer used; kept for compatibility.)
+type UnmarshalFieldError struct {
+ Key string
+ Type reflect.Type
+ Field reflect.StructField
+}
+
+func (e *UnmarshalFieldError) Error() string {
+ return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
+}
+
+// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
+// (The argument to Unmarshal must be a non-nil pointer.)
+type InvalidUnmarshalError struct {
+ Type reflect.Type
+}
+
+func (e *InvalidUnmarshalError) Error() string {
+ if e.Type == nil {
+ return "json: Unmarshal(nil)"
+ }
+
+ if e.Type.Kind() != reflect.Ptr {
+ return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
+ }
+ return "json: Unmarshal(nil " + e.Type.String() + ")"
+}
+
+func (d *decodeState) unmarshal(v interface{}) (err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ if _, ok := r.(runtime.Error); ok {
+ panic(r)
+ }
+ err = r.(error)
+ }
+ }()
+
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr || rv.IsNil() {
+ return &InvalidUnmarshalError{reflect.TypeOf(v)}
+ }
+
+ d.scan.reset()
+ // We decode rv not rv.Elem because the Unmarshaler interface
+ // test must be applied at the top level of the value.
+ d.value(rv)
+ return d.savedError
+}
+
+// A Number represents a JSON number literal.
+type Number string
+
+// String returns the literal text of the number.
+func (n Number) String() string { return string(n) }
+
+// Float64 returns the number as a float64.
+func (n Number) Float64() (float64, error) {
+ return strconv.ParseFloat(string(n), 64)
+}
+
+// Int64 returns the number as an int64.
+func (n Number) Int64() (int64, error) {
+ return strconv.ParseInt(string(n), 10, 64)
+}
+
+// isValidNumber reports whether s is a valid JSON number literal.
+func isValidNumber(s string) bool {
+ // This function implements the JSON numbers grammar.
+ // See https://tools.ietf.org/html/rfc7159#section-6
+ // and http://json.org/number.gif
+
+ if s == "" {
+ return false
+ }
+
+ // Optional -
+ if s[0] == '-' {
+ s = s[1:]
+ if s == "" {
+ return false
+ }
+ }
+
+ // Digits
+ switch {
+ default:
+ return false
+
+ case s[0] == '0':
+ s = s[1:]
+
+ case '1' <= s[0] && s[0] <= '9':
+ s = s[1:]
+ for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+ s = s[1:]
+ }
+ }
+
+ // . followed by 1 or more digits.
+ if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
+ s = s[2:]
+ for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+ s = s[1:]
+ }
+ }
+
+ // e or E followed by an optional - or + and
+ // 1 or more digits.
+ if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
+ s = s[1:]
+ if s[0] == '+' || s[0] == '-' {
+ s = s[1:]
+ if s == "" {
+ return false
+ }
+ }
+ for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+ s = s[1:]
+ }
+ }
+
+ // Make sure we are at the end.
+ return s == ""
+}
+
+type NumberUnmarshalType int
+
+const (
+ // unmarshal a JSON number into an interface{} as a float64
+ UnmarshalFloat NumberUnmarshalType = iota
+ // unmarshal a JSON number into an interface{} as a `json.Number`
+ UnmarshalJSONNumber
+ // unmarshal a JSON number into an interface{} as a int64
+ // if value is an integer otherwise float64
+ UnmarshalIntOrFloat
+)
+
+// decodeState represents the state while decoding a JSON value.
+type decodeState struct {
+ data []byte
+ off int // read offset in data
+ scan scanner
+ nextscan scanner // for calls to nextValue
+ savedError error
+ numberType NumberUnmarshalType
+}
+
+// errPhase is used for errors that should not happen unless
+// there is a bug in the JSON decoder or something is editing
+// the data slice while the decoder executes.
+var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?")
+
+func (d *decodeState) init(data []byte) *decodeState {
+ d.data = data
+ d.off = 0
+ d.savedError = nil
+ return d
+}
+
+// error aborts the decoding by panicking with err.
+func (d *decodeState) error(err error) {
+ panic(err)
+}
+
+// saveError saves the first err it is called with,
+// for reporting at the end of the unmarshal.
+func (d *decodeState) saveError(err error) {
+ if d.savedError == nil {
+ d.savedError = err
+ }
+}
+
+// next cuts off and returns the next full JSON value in d.data[d.off:].
+// The next value is known to be an object or array, not a literal.
+func (d *decodeState) next() []byte {
+ c := d.data[d.off]
+ item, rest, err := nextValue(d.data[d.off:], &d.nextscan)
+ if err != nil {
+ d.error(err)
+ }
+ d.off = len(d.data) - len(rest)
+
+ // Our scanner has seen the opening brace/bracket
+ // and thinks we're still in the middle of the object.
+ // invent a closing brace/bracket to get it out.
+ if c == '{' {
+ d.scan.step(&d.scan, '}')
+ } else {
+ d.scan.step(&d.scan, ']')
+ }
+
+ return item
+}
+
+// scanWhile processes bytes in d.data[d.off:] until it
+// receives a scan code not equal to op.
+// It updates d.off and returns the new scan code.
+func (d *decodeState) scanWhile(op int) int {
+ var newOp int
+ for {
+ if d.off >= len(d.data) {
+ newOp = d.scan.eof()
+ d.off = len(d.data) + 1 // mark processed EOF with len+1
+ } else {
+ c := d.data[d.off]
+ d.off++
+ newOp = d.scan.step(&d.scan, c)
+ }
+ if newOp != op {
+ break
+ }
+ }
+ return newOp
+}
+
+// value decodes a JSON value from d.data[d.off:] into the value.
+// it updates d.off to point past the decoded value.
+func (d *decodeState) value(v reflect.Value) {
+ if !v.IsValid() {
+ _, rest, err := nextValue(d.data[d.off:], &d.nextscan)
+ if err != nil {
+ d.error(err)
+ }
+ d.off = len(d.data) - len(rest)
+
+ // d.scan thinks we're still at the beginning of the item.
+ // Feed in an empty string - the shortest, simplest value -
+ // so that it knows we got to the end of the value.
+ if d.scan.redo {
+ // rewind.
+ d.scan.redo = false
+ d.scan.step = stateBeginValue
+ }
+ d.scan.step(&d.scan, '"')
+ d.scan.step(&d.scan, '"')
+
+ n := len(d.scan.parseState)
+ if n > 0 && d.scan.parseState[n-1] == parseObjectKey {
+ // d.scan thinks we just read an object key; finish the object
+ d.scan.step(&d.scan, ':')
+ d.scan.step(&d.scan, '"')
+ d.scan.step(&d.scan, '"')
+ d.scan.step(&d.scan, '}')
+ }
+
+ return
+ }
+
+ switch op := d.scanWhile(scanSkipSpace); op {
+ default:
+ d.error(errPhase)
+
+ case scanBeginArray:
+ d.array(v)
+
+ case scanBeginObject:
+ d.object(v)
+
+ case scanBeginLiteral:
+ d.literal(v)
+ }
+}
+
+type unquotedValue struct{}
+
+// valueQuoted is like value but decodes a
+// quoted string literal or literal null into an interface value.
+// If it finds anything other than a quoted string literal or null,
+// valueQuoted returns unquotedValue{}.
+func (d *decodeState) valueQuoted() interface{} {
+ switch op := d.scanWhile(scanSkipSpace); op {
+ default:
+ d.error(errPhase)
+
+ case scanBeginArray:
+ d.array(reflect.Value{})
+
+ case scanBeginObject:
+ d.object(reflect.Value{})
+
+ case scanBeginLiteral:
+ switch v := d.literalInterface().(type) {
+ case nil, string:
+ return v
+ }
+ }
+ return unquotedValue{}
+}
+
+// indirect walks down v allocating pointers as needed,
+// until it gets to a non-pointer.
+// if it encounters an Unmarshaler, indirect stops and returns that.
+// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
+func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
+ // If v is a named type and is addressable,
+ // start with its address, so that if the type has pointer methods,
+ // we find them.
+ if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
+ v = v.Addr()
+ }
+ for {
+ // Load value from interface, but only if the result will be
+ // usefully addressable.
+ if v.Kind() == reflect.Interface && !v.IsNil() {
+ e := v.Elem()
+ if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
+ v = e
+ continue
+ }
+ }
+
+ if v.Kind() != reflect.Ptr {
+ break
+ }
+
+ if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
+ break
+ }
+ if v.IsNil() {
+ v.Set(reflect.New(v.Type().Elem()))
+ }
+ if v.Type().NumMethod() > 0 {
+ if u, ok := v.Interface().(Unmarshaler); ok {
+ return u, nil, reflect.Value{}
+ }
+ if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
+ return nil, u, reflect.Value{}
+ }
+ }
+ v = v.Elem()
+ }
+ return nil, nil, v
+}
+
+// array consumes an array from d.data[d.off-1:], decoding into the value v.
+// the first byte of the array ('[') has been read already.
+func (d *decodeState) array(v reflect.Value) {
+ // Check for unmarshaler.
+ u, ut, pv := d.indirect(v, false)
+ if u != nil {
+ d.off--
+ err := u.UnmarshalJSON(d.next())
+ if err != nil {
+ d.error(err)
+ }
+ return
+ }
+ if ut != nil {
+ d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)})
+ d.off--
+ d.next()
+ return
+ }
+
+ v = pv
+
+ // Check type of target.
+ switch v.Kind() {
+ case reflect.Interface:
+ if v.NumMethod() == 0 {
+ // Decoding into nil interface? Switch to non-reflect code.
+ v.Set(reflect.ValueOf(d.arrayInterface()))
+ return
+ }
+ // Otherwise it's invalid.
+ fallthrough
+ default:
+ d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)})
+ d.off--
+ d.next()
+ return
+ case reflect.Array:
+ case reflect.Slice:
+ break
+ }
+
+ i := 0
+ for {
+ // Look ahead for ] - can only happen on first iteration.
+ op := d.scanWhile(scanSkipSpace)
+ if op == scanEndArray {
+ break
+ }
+
+ // Back up so d.value can have the byte we just read.
+ d.off--
+ d.scan.undo(op)
+
+ // Get element of array, growing if necessary.
+ if v.Kind() == reflect.Slice {
+ // Grow slice if necessary
+ if i >= v.Cap() {
+ newcap := v.Cap() + v.Cap()/2
+ if newcap < 4 {
+ newcap = 4
+ }
+ newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
+ reflect.Copy(newv, v)
+ v.Set(newv)
+ }
+ if i >= v.Len() {
+ v.SetLen(i + 1)
+ }
+ }
+
+ if i < v.Len() {
+ // Decode into element.
+ d.value(v.Index(i))
+ } else {
+ // Ran out of fixed array: skip.
+ d.value(reflect.Value{})
+ }
+ i++
+
+ // Next token must be , or ].
+ op = d.scanWhile(scanSkipSpace)
+ if op == scanEndArray {
+ break
+ }
+ if op != scanArrayValue {
+ d.error(errPhase)
+ }
+ }
+
+ if i < v.Len() {
+ if v.Kind() == reflect.Array {
+ // Array. Zero the rest.
+ z := reflect.Zero(v.Type().Elem())
+ for ; i < v.Len(); i++ {
+ v.Index(i).Set(z)
+ }
+ } else {
+ v.SetLen(i)
+ }
+ }
+ if i == 0 && v.Kind() == reflect.Slice {
+ v.Set(reflect.MakeSlice(v.Type(), 0, 0))
+ }
+}
+
+var nullLiteral = []byte("null")
+
+// object consumes an object from d.data[d.off-1:], decoding into the value v.
+// the first byte ('{') of the object has been read already.
+func (d *decodeState) object(v reflect.Value) {
+ // Check for unmarshaler.
+ u, ut, pv := d.indirect(v, false)
+ if u != nil {
+ d.off--
+ err := u.UnmarshalJSON(d.next())
+ if err != nil {
+ d.error(err)
+ }
+ return
+ }
+ if ut != nil {
+ d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
+ d.off--
+ d.next() // skip over { } in input
+ return
+ }
+ v = pv
+
+ // Decoding into nil interface? Switch to non-reflect code.
+ if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
+ v.Set(reflect.ValueOf(d.objectInterface()))
+ return
+ }
+
+ // Check type of target: struct or map[string]T
+ switch v.Kind() {
+ case reflect.Map:
+ // map must have string kind
+ t := v.Type()
+ if t.Key().Kind() != reflect.String {
+ d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
+ d.off--
+ d.next() // skip over { } in input
+ return
+ }
+ if v.IsNil() {
+ v.Set(reflect.MakeMap(t))
+ }
+ case reflect.Struct:
+
+ default:
+ d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
+ d.off--
+ d.next() // skip over { } in input
+ return
+ }
+
+ var mapElem reflect.Value
+ keys := map[string]bool{}
+
+ for {
+ // Read opening " of string key or closing }.
+ op := d.scanWhile(scanSkipSpace)
+ if op == scanEndObject {
+ // closing } - can only happen on first iteration.
+ break
+ }
+ if op != scanBeginLiteral {
+ d.error(errPhase)
+ }
+
+ // Read key.
+ start := d.off - 1
+ op = d.scanWhile(scanContinue)
+ item := d.data[start : d.off-1]
+ key, ok := unquote(item)
+ if !ok {
+ d.error(errPhase)
+ }
+
+ // Check for duplicate keys.
+ _, ok = keys[key]
+ if !ok {
+ keys[key] = true
+ } else {
+ d.error(fmt.Errorf("json: duplicate key '%s' in object", key))
+ }
+
+ // Figure out field corresponding to key.
+ var subv reflect.Value
+ destring := false // whether the value is wrapped in a string to be decoded first
+
+ if v.Kind() == reflect.Map {
+ elemType := v.Type().Elem()
+ if !mapElem.IsValid() {
+ mapElem = reflect.New(elemType).Elem()
+ } else {
+ mapElem.Set(reflect.Zero(elemType))
+ }
+ subv = mapElem
+ } else {
+ var f *field
+ fields := cachedTypeFields(v.Type())
+ for i := range fields {
+ ff := &fields[i]
+ if bytes.Equal(ff.nameBytes, []byte(key)) {
+ f = ff
+ break
+ }
+ }
+ if f != nil {
+ subv = v
+ destring = f.quoted
+ for _, i := range f.index {
+ if subv.Kind() == reflect.Ptr {
+ if subv.IsNil() {
+ subv.Set(reflect.New(subv.Type().Elem()))
+ }
+ subv = subv.Elem()
+ }
+ subv = subv.Field(i)
+ }
+ }
+ }
+
+ // Read : before value.
+ if op == scanSkipSpace {
+ op = d.scanWhile(scanSkipSpace)
+ }
+ if op != scanObjectKey {
+ d.error(errPhase)
+ }
+
+ // Read value.
+ if destring {
+ switch qv := d.valueQuoted().(type) {
+ case nil:
+ d.literalStore(nullLiteral, subv, false)
+ case string:
+ d.literalStore([]byte(qv), subv, true)
+ default:
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type()))
+ }
+ } else {
+ d.value(subv)
+ }
+
+ // Write value back to map;
+ // if using struct, subv points into struct already.
+ if v.Kind() == reflect.Map {
+ kv := reflect.ValueOf(key).Convert(v.Type().Key())
+ v.SetMapIndex(kv, subv)
+ }
+
+ // Next token must be , or }.
+ op = d.scanWhile(scanSkipSpace)
+ if op == scanEndObject {
+ break
+ }
+ if op != scanObjectValue {
+ d.error(errPhase)
+ }
+ }
+}
+
+// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
+// The first byte of the literal has been read already
+// (that's how the caller knows it's a literal).
+func (d *decodeState) literal(v reflect.Value) {
+ // All bytes inside literal return scanContinue op code.
+ start := d.off - 1
+ op := d.scanWhile(scanContinue)
+
+ // Scan read one byte too far; back up.
+ d.off--
+ d.scan.undo(op)
+
+ d.literalStore(d.data[start:d.off], v, false)
+}
+
+// convertNumber converts the number literal s to a float64, int64 or a Number
+// depending on d.numberDecodeType.
+func (d *decodeState) convertNumber(s string) (interface{}, error) {
+ switch d.numberType {
+
+ case UnmarshalJSONNumber:
+ return Number(s), nil
+ case UnmarshalIntOrFloat:
+ v, err := strconv.ParseInt(s, 10, 64)
+ if err == nil {
+ return v, nil
+ }
+
+ // tries to parse integer number in scientific notation
+ f, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)}
+ }
+
+ // if it has no decimal value use int64
+ if fi, fd := math.Modf(f); fd == 0.0 {
+ return int64(fi), nil
+ }
+ return f, nil
+ default:
+ f, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)}
+ }
+ return f, nil
+ }
+
+}
+
+var numberType = reflect.TypeOf(Number(""))
+
+// literalStore decodes a literal stored in item into v.
+//
+// fromQuoted indicates whether this literal came from unwrapping a
+// string from the ",string" struct tag option. this is used only to
+// produce more helpful error messages.
+func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) {
+ // Check for unmarshaler.
+ if len(item) == 0 {
+ //Empty string given
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ return
+ }
+ wantptr := item[0] == 'n' // null
+ u, ut, pv := d.indirect(v, wantptr)
+ if u != nil {
+ err := u.UnmarshalJSON(item)
+ if err != nil {
+ d.error(err)
+ }
+ return
+ }
+ if ut != nil {
+ if item[0] != '"' {
+ if fromQuoted {
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
+ }
+ return
+ }
+ s, ok := unquoteBytes(item)
+ if !ok {
+ if fromQuoted {
+ d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.error(errPhase)
+ }
+ }
+ err := ut.UnmarshalText(s)
+ if err != nil {
+ d.error(err)
+ }
+ return
+ }
+
+ v = pv
+
+ switch c := item[0]; c {
+ case 'n': // null
+ switch v.Kind() {
+ case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
+ v.Set(reflect.Zero(v.Type()))
+ // otherwise, ignore null for primitives/string
+ }
+ case 't', 'f': // true, false
+ value := c == 't'
+ switch v.Kind() {
+ default:
+ if fromQuoted {
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)})
+ }
+ case reflect.Bool:
+ v.SetBool(value)
+ case reflect.Interface:
+ if v.NumMethod() == 0 {
+ v.Set(reflect.ValueOf(value))
+ } else {
+ d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)})
+ }
+ }
+
+ case '"': // string
+ s, ok := unquoteBytes(item)
+ if !ok {
+ if fromQuoted {
+ d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.error(errPhase)
+ }
+ }
+ switch v.Kind() {
+ default:
+ d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
+ case reflect.Slice:
+ if v.Type().Elem().Kind() != reflect.Uint8 {
+ d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
+ break
+ }
+ b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
+ n, err := base64.StdEncoding.Decode(b, s)
+ if err != nil {
+ d.saveError(err)
+ break
+ }
+ v.SetBytes(b[:n])
+ case reflect.String:
+ v.SetString(string(s))
+ case reflect.Interface:
+ if v.NumMethod() == 0 {
+ v.Set(reflect.ValueOf(string(s)))
+ } else {
+ d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
+ }
+ }
+
+ default: // number
+ if c != '-' && (c < '0' || c > '9') {
+ if fromQuoted {
+ d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.error(errPhase)
+ }
+ }
+ s := string(item)
+ switch v.Kind() {
+ default:
+ if v.Kind() == reflect.String && v.Type() == numberType {
+ v.SetString(s)
+ if !isValidNumber(s) {
+ d.error(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item))
+ }
+ break
+ }
+ if fromQuoted {
+ d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)})
+ }
+ case reflect.Interface:
+ n, err := d.convertNumber(s)
+ if err != nil {
+ d.saveError(err)
+ break
+ }
+ if v.NumMethod() != 0 {
+ d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)})
+ break
+ }
+ v.Set(reflect.ValueOf(n))
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ n, err := strconv.ParseInt(s, 10, 64)
+ if err != nil || v.OverflowInt(n) {
+ d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
+ break
+ }
+ v.SetInt(n)
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ n, err := strconv.ParseUint(s, 10, 64)
+ if err != nil || v.OverflowUint(n) {
+ d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
+ break
+ }
+ v.SetUint(n)
+
+ case reflect.Float32, reflect.Float64:
+ n, err := strconv.ParseFloat(s, v.Type().Bits())
+ if err != nil || v.OverflowFloat(n) {
+ d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
+ break
+ }
+ v.SetFloat(n)
+ }
+ }
+}
+
+// The xxxInterface routines build up a value to be stored
+// in an empty interface. They are not strictly necessary,
+// but they avoid the weight of reflection in this common case.
+
+// valueInterface is like value but returns interface{}
+func (d *decodeState) valueInterface() interface{} {
+ switch d.scanWhile(scanSkipSpace) {
+ default:
+ d.error(errPhase)
+ panic("unreachable")
+ case scanBeginArray:
+ return d.arrayInterface()
+ case scanBeginObject:
+ return d.objectInterface()
+ case scanBeginLiteral:
+ return d.literalInterface()
+ }
+}
+
+// arrayInterface is like array but returns []interface{}.
+func (d *decodeState) arrayInterface() []interface{} {
+ var v = make([]interface{}, 0)
+ for {
+ // Look ahead for ] - can only happen on first iteration.
+ op := d.scanWhile(scanSkipSpace)
+ if op == scanEndArray {
+ break
+ }
+
+ // Back up so d.value can have the byte we just read.
+ d.off--
+ d.scan.undo(op)
+
+ v = append(v, d.valueInterface())
+
+ // Next token must be , or ].
+ op = d.scanWhile(scanSkipSpace)
+ if op == scanEndArray {
+ break
+ }
+ if op != scanArrayValue {
+ d.error(errPhase)
+ }
+ }
+ return v
+}
+
+// objectInterface is like object but returns map[string]interface{}.
+func (d *decodeState) objectInterface() map[string]interface{} {
+ m := make(map[string]interface{})
+ keys := map[string]bool{}
+
+ for {
+ // Read opening " of string key or closing }.
+ op := d.scanWhile(scanSkipSpace)
+ if op == scanEndObject {
+ // closing } - can only happen on first iteration.
+ break
+ }
+ if op != scanBeginLiteral {
+ d.error(errPhase)
+ }
+
+ // Read string key.
+ start := d.off - 1
+ op = d.scanWhile(scanContinue)
+ item := d.data[start : d.off-1]
+ key, ok := unquote(item)
+ if !ok {
+ d.error(errPhase)
+ }
+
+ // Check for duplicate keys.
+ _, ok = keys[key]
+ if !ok {
+ keys[key] = true
+ } else {
+ d.error(fmt.Errorf("json: duplicate key '%s' in object", key))
+ }
+
+ // Read : before value.
+ if op == scanSkipSpace {
+ op = d.scanWhile(scanSkipSpace)
+ }
+ if op != scanObjectKey {
+ d.error(errPhase)
+ }
+
+ // Read value.
+ m[key] = d.valueInterface()
+
+ // Next token must be , or }.
+ op = d.scanWhile(scanSkipSpace)
+ if op == scanEndObject {
+ break
+ }
+ if op != scanObjectValue {
+ d.error(errPhase)
+ }
+ }
+ return m
+}
+
+// literalInterface is like literal but returns an interface value.
+func (d *decodeState) literalInterface() interface{} {
+ // All bytes inside literal return scanContinue op code.
+ start := d.off - 1
+ op := d.scanWhile(scanContinue)
+
+ // Scan read one byte too far; back up.
+ d.off--
+ d.scan.undo(op)
+ item := d.data[start:d.off]
+
+ switch c := item[0]; c {
+ case 'n': // null
+ return nil
+
+ case 't', 'f': // true, false
+ return c == 't'
+
+ case '"': // string
+ s, ok := unquote(item)
+ if !ok {
+ d.error(errPhase)
+ }
+ return s
+
+ default: // number
+ if c != '-' && (c < '0' || c > '9') {
+ d.error(errPhase)
+ }
+ n, err := d.convertNumber(string(item))
+ if err != nil {
+ d.saveError(err)
+ }
+ return n
+ }
+}
+
+// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
+// or it returns -1.
+func getu4(s []byte) rune {
+ if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
+ return -1
+ }
+ r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
+ if err != nil {
+ return -1
+ }
+ return rune(r)
+}
+
+// unquote converts a quoted JSON string literal s into an actual string t.
+// The rules are different than for Go, so cannot use strconv.Unquote.
+func unquote(s []byte) (t string, ok bool) {
+ s, ok = unquoteBytes(s)
+ t = string(s)
+ return
+}
+
+func unquoteBytes(s []byte) (t []byte, ok bool) {
+ if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
+ return
+ }
+ s = s[1 : len(s)-1]
+
+ // Check for unusual characters. If there are none,
+ // then no unquoting is needed, so return a slice of the
+ // original bytes.
+ r := 0
+ for r < len(s) {
+ c := s[r]
+ if c == '\\' || c == '"' || c < ' ' {
+ break
+ }
+ if c < utf8.RuneSelf {
+ r++
+ continue
+ }
+ rr, size := utf8.DecodeRune(s[r:])
+ if rr == utf8.RuneError && size == 1 {
+ break
+ }
+ r += size
+ }
+ if r == len(s) {
+ return s, true
+ }
+
+ b := make([]byte, len(s)+2*utf8.UTFMax)
+ w := copy(b, s[0:r])
+ for r < len(s) {
+ // Out of room? Can only happen if s is full of
+ // malformed UTF-8 and we're replacing each
+ // byte with RuneError.
+ if w >= len(b)-2*utf8.UTFMax {
+ nb := make([]byte, (len(b)+utf8.UTFMax)*2)
+ copy(nb, b[0:w])
+ b = nb
+ }
+ switch c := s[r]; {
+ case c == '\\':
+ r++
+ if r >= len(s) {
+ return
+ }
+ switch s[r] {
+ default:
+ return
+ case '"', '\\', '/', '\'':
+ b[w] = s[r]
+ r++
+ w++
+ case 'b':
+ b[w] = '\b'
+ r++
+ w++
+ case 'f':
+ b[w] = '\f'
+ r++
+ w++
+ case 'n':
+ b[w] = '\n'
+ r++
+ w++
+ case 'r':
+ b[w] = '\r'
+ r++
+ w++
+ case 't':
+ b[w] = '\t'
+ r++
+ w++
+ case 'u':
+ r--
+ rr := getu4(s[r:])
+ if rr < 0 {
+ return
+ }
+ r += 6
+ if utf16.IsSurrogate(rr) {
+ rr1 := getu4(s[r:])
+ if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
+ // A valid pair; consume.
+ r += 6
+ w += utf8.EncodeRune(b[w:], dec)
+ break
+ }
+ // Invalid surrogate; fall back to replacement rune.
+ rr = unicode.ReplacementChar
+ }
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+
+ // Quote, control characters are invalid.
+ case c == '"', c < ' ':
+ return
+
+ // ASCII
+ case c < utf8.RuneSelf:
+ b[w] = c
+ r++
+ w++
+
+ // Coerce to well-formed UTF-8.
+ default:
+ rr, size := utf8.DecodeRune(s[r:])
+ r += size
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+ }
+ return b[0:w], true
+}
diff --git a/vendor/github.com/go-jose/go-jose/v4/json/encode.go b/vendor/github.com/go-jose/go-jose/v4/json/encode.go
new file mode 100644
index 00000000000..98de68ce1e9
--- /dev/null
+++ b/vendor/github.com/go-jose/go-jose/v4/json/encode.go
@@ -0,0 +1,1197 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package json implements encoding and decoding of JSON objects as defined in
+// RFC 4627. The mapping between JSON objects and Go values is described
+// in the documentation for the Marshal and Unmarshal functions.
+//
+// See "JSON and Go" for an introduction to this package:
+// https://golang.org/doc/articles/json_and_go.html
+package json
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/base64"
+ "fmt"
+ "math"
+ "reflect"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "unicode"
+ "unicode/utf8"
+)
+
+// Marshal returns the JSON encoding of v.
+//
+// Marshal traverses the value v recursively.
+// If an encountered value implements the Marshaler interface
+// and is not a nil pointer, Marshal calls its MarshalJSON method
+// to produce JSON. If no MarshalJSON method is present but the
+// value implements encoding.TextMarshaler instead, Marshal calls
+// its MarshalText method.
+// The nil pointer exception is not strictly necessary
+// but mimics a similar, necessary exception in the behavior of
+// UnmarshalJSON.
+//
+// Otherwise, Marshal uses the following type-dependent default encodings:
+//
+// Boolean values encode as JSON booleans.
+//
+// Floating point, integer, and Number values encode as JSON numbers.
+//
+// String values encode as JSON strings coerced to valid UTF-8,
+// replacing invalid bytes with the Unicode replacement rune.
+// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
+// to keep some browsers from misinterpreting JSON output as HTML.
+// Ampersand "&" is also escaped to "\u0026" for the same reason.
+//
+// Array and slice values encode as JSON arrays, except that
+// []byte encodes as a base64-encoded string, and a nil slice
+// encodes as the null JSON object.
+//
+// Struct values encode as JSON objects. Each exported struct field
+// becomes a member of the object unless
+// - the field's tag is "-", or
+// - the field is empty and its tag specifies the "omitempty" option.
+//
+// The empty values are false, 0, any
+// nil pointer or interface value, and any array, slice, map, or string of
+// length zero. The object's default key string is the struct field name
+// but can be specified in the struct field's tag value. The "json" key in
+// the struct field's tag value is the key name, followed by an optional comma
+// and options. Examples:
+//
+// // Field is ignored by this package.
+// Field int `json:"-"`
+//
+// // Field appears in JSON as key "myName".
+// Field int `json:"myName"`
+//
+// // Field appears in JSON as key "myName" and
+// // the field is omitted from the object if its value is empty,
+// // as defined above.
+// Field int `json:"myName,omitempty"`
+//
+// // Field appears in JSON as key "Field" (the default), but
+// // the field is skipped if empty.
+// // Note the leading comma.
+// Field int `json:",omitempty"`
+//
+// The "string" option signals that a field is stored as JSON inside a
+// JSON-encoded string. It applies only to fields of string, floating point,
+// integer, or boolean types. This extra level of encoding is sometimes used
+// when communicating with JavaScript programs:
+//
+// Int64String int64 `json:",string"`
+//
+// The key name will be used if it's a non-empty string consisting of
+// only Unicode letters, digits, dollar signs, percent signs, hyphens,
+// underscores and slashes.
+//
+// Anonymous struct fields are usually marshaled as if their inner exported fields
+// were fields in the outer struct, subject to the usual Go visibility rules amended
+// as described in the next paragraph.
+// An anonymous struct field with a name given in its JSON tag is treated as
+// having that name, rather than being anonymous.
+// An anonymous struct field of interface type is treated the same as having
+// that type as its name, rather than being anonymous.
+//
+// The Go visibility rules for struct fields are amended for JSON when
+// deciding which field to marshal or unmarshal. If there are
+// multiple fields at the same level, and that level is the least
+// nested (and would therefore be the nesting level selected by the
+// usual Go rules), the following extra rules apply:
+//
+// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
+// even if there are multiple untagged fields that would otherwise conflict.
+// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
+// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
+//
+// Handling of anonymous struct fields is new in Go 1.1.
+// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
+// an anonymous struct field in both current and earlier versions, give the field
+// a JSON tag of "-".
+//
+// Map values encode as JSON objects.
+// The map's key type must be string; the map keys are used as JSON object
+// keys, subject to the UTF-8 coercion described for string values above.
+//
+// Pointer values encode as the value pointed to.
+// A nil pointer encodes as the null JSON object.
+//
+// Interface values encode as the value contained in the interface.
+// A nil interface value encodes as the null JSON object.
+//
+// Channel, complex, and function values cannot be encoded in JSON.
+// Attempting to encode such a value causes Marshal to return
+// an UnsupportedTypeError.
+//
+// JSON cannot represent cyclic data structures and Marshal does not
+// handle them. Passing cyclic structures to Marshal will result in
+// an infinite recursion.
+func Marshal(v interface{}) ([]byte, error) {
+ e := &encodeState{}
+ err := e.marshal(v)
+ if err != nil {
+ return nil, err
+ }
+ return e.Bytes(), nil
+}
+
+// MarshalIndent is like Marshal but applies Indent to format the output.
+func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+ b, err := Marshal(v)
+ if err != nil {
+ return nil, err
+ }
+ var buf bytes.Buffer
+ err = Indent(&buf, b, prefix, indent)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
+// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
+// so that the JSON will be safe to embed inside HTML