You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ze...@apache.org on 2023/06/21 14:38:36 UTC
[arrow-adbc] branch main updated: feat(go/adbc/driver/flightsql): Add cookie middleware option (#825)
This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 17a13f9f feat(go/adbc/driver/flightsql): Add cookie middleware option (#825)
17a13f9f is described below
commit 17a13f9f5e6ee0c6f5d3fa7951b74fa5cbb6a96b
Author: Matt Topol <zo...@gmail.com>
AuthorDate: Wed Jun 21 10:38:31 2023 -0400
feat(go/adbc/driver/flightsql): Add cookie middleware option (#825)
Fixes #716
---
docs/source/driver/flight_sql.rst | 6 +
go/adbc/driver/flightsql/flightsql_adbc.go | 33 ++++-
.../driver/flightsql/flightsql_adbc_server_test.go | 152 +++++++++++++++++----
go/adbc/go.mod | 22 ++-
go/adbc/go.sum | 44 +++---
5 files changed, 190 insertions(+), 67 deletions(-)
diff --git a/docs/source/driver/flight_sql.rst b/docs/source/driver/flight_sql.rst
index f0f7363a..3721c779 100644
--- a/docs/source/driver/flight_sql.rst
+++ b/docs/source/driver/flight_sql.rst
@@ -222,6 +222,12 @@ These options map 1:1 with the options in FlightClientOptions:
defaults to 16 MiB since Flight services tend to return larger
reponse payloads. Should be a positive integer number of bytes.
+``adbc.flight.sql.rpc.with_cookie_middleware``
+ Enable or disable middleware that processes and handles "set-cookie"
+ metadata headers returned from the server and sends "Cookie" headers
+ back from the client. Value should be ``true`` or ``false``. Default
+ is ``false``.
+
Custom Call Headers
-------------------
diff --git a/go/adbc/driver/flightsql/flightsql_adbc.go b/go/adbc/driver/flightsql/flightsql_adbc.go
index 03bdefac..e038354c 100644
--- a/go/adbc/driver/flightsql/flightsql_adbc.go
+++ b/go/adbc/driver/flightsql/flightsql_adbc.go
@@ -80,6 +80,7 @@ const (
OptionTimeoutQuery = "adbc.flight.sql.rpc.timeout_seconds.query"
OptionTimeoutUpdate = "adbc.flight.sql.rpc.timeout_seconds.update"
OptionRPCCallHeaderPrefix = "adbc.flight.sql.rpc.call_header."
+ OptionCookieMiddleware = "adbc.flight.sql.rpc.with_cookie_middleware"
infoDriverName = "ADBC Flight SQL Driver - Go"
)
@@ -184,12 +185,13 @@ func (d *dbDialOpts) rebuild() {
}
type database struct {
- uri *url.URL
- creds credentials.TransportCredentials
- user, pass string
- hdrs metadata.MD
- timeout timeoutOption
- dialOpts dbDialOpts
+ uri *url.URL
+ creds credentials.TransportCredentials
+ user, pass string
+ hdrs metadata.MD
+ timeout timeoutOption
+ dialOpts dbDialOpts
+ enableCookies bool
alloc memory.Allocator
}
@@ -327,6 +329,7 @@ func (d *database) SetOptions(cnOptions map[string]string) error {
}
delete(cnOptions, OptionWithBlock)
}
+
if val, ok := cnOptions[OptionWithMaxMsgSize]; ok {
var err error
var size int
@@ -346,6 +349,20 @@ func (d *database) SetOptions(cnOptions map[string]string) error {
}
d.dialOpts.rebuild()
+ if val, ok := cnOptions[OptionCookieMiddleware]; ok {
+ if val == adbc.OptionValueEnabled {
+ d.enableCookies = true
+ } else if val == adbc.OptionValueDisabled {
+ d.enableCookies = false
+ } else {
+ return adbc.Error{
+ Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionCookieMiddleware, val),
+ Code: adbc.StatusInvalidArgument,
+ }
+ }
+ delete(cnOptions, OptionCookieMiddleware)
+ }
+
for key, val := range cnOptions {
if strings.HasPrefix(key, OptionRPCCallHeaderPrefix) {
d.hdrs.Append(strings.TrimPrefix(key, OptionRPCCallHeaderPrefix), val)
@@ -544,6 +561,10 @@ func getFlightClient(ctx context.Context, loc string, d *database) (*flightsql.C
},
}
+ if d.enableCookies {
+ middleware = append(middleware, flight.NewClientCookieMiddleware())
+ }
+
uri, err := url.Parse(loc)
if err != nil {
return nil, adbc.Error{Msg: fmt.Sprintf("Invalid URI '%s': %s", loc, err), Code: adbc.StatusInvalidArgument}
diff --git a/go/adbc/driver/flightsql/flightsql_adbc_server_test.go b/go/adbc/driver/flightsql/flightsql_adbc_server_test.go
index c4b5524f..9d959ac4 100644
--- a/go/adbc/driver/flightsql/flightsql_adbc_server_test.go
+++ b/go/adbc/driver/flightsql/flightsql_adbc_server_test.go
@@ -21,6 +21,9 @@ package flightsql_test
import (
"context"
+ "errors"
+ "fmt"
+ "net/textproto"
"os"
"strings"
"testing"
@@ -71,17 +74,17 @@ func (suite *ServerBasedTests) DoSetupSuite(srv flightsql.Server, srvMiddleware
suite.Require().NoError(err)
}
-func (suite *ServerBasedTests) DoSetupTest() {
+func (suite *ServerBasedTests) SetupTest() {
var err error
suite.cnxn, err = suite.db.Open(context.Background())
suite.Require().NoError(err)
}
-func (suite *ServerBasedTests) DoTearDownTest() {
+func (suite *ServerBasedTests) TearDownTest() {
suite.Require().NoError(suite.cnxn.Close())
}
-func (suite *ServerBasedTests) DoTearDownSuite() {
+func (suite *ServerBasedTests) TearDownSuite() {
suite.db = nil
suite.s.Shutdown()
}
@@ -96,6 +99,10 @@ func TestTimeout(t *testing.T) {
suite.Run(t, &TimeoutTests{})
}
+func TestCookies(t *testing.T) {
+ suite.Run(t, &CookieTests{})
+}
+
// ---- AuthN Tests --------------------
type AuthnTestServer struct {
@@ -183,18 +190,6 @@ func (suite *AuthnTests) SetupSuite() {
})
}
-func (suite *AuthnTests) SetupTest() {
- suite.DoSetupTest()
-}
-
-func (suite *AuthnTests) TearDownTest() {
- suite.DoTearDownTest()
-}
-
-func (suite *AuthnTests) TearDownSuite() {
- suite.DoTearDownSuite()
-}
-
func (suite *AuthnTests) TestBearerTokenUpdated() {
// apache/arrow-adbc#584: when setting the auth header directly, the client should use any updated token value from the server if given
stmt, err := suite.cnxn.NewStatement()
@@ -291,18 +286,6 @@ func (suite *TimeoutTests) SetupSuite() {
suite.DoSetupSuite(&TimeoutTestServer{}, nil, nil)
}
-func (suite *TimeoutTests) SetupTest() {
- suite.DoSetupTest()
-}
-
-func (suite *TimeoutTests) TearDownTest() {
- suite.DoTearDownTest()
-}
-
-func (suite *TimeoutTests) TearDownSuite() {
- suite.DoTearDownSuite()
-}
-
func (ts *TimeoutTests) TestInvalidValues() {
keys := []string{
"adbc.flight.sql.rpc.timeout_seconds.fetch",
@@ -424,3 +407,118 @@ func (ts *TimeoutTests) TestDontTimeout() {
defer expected.Release()
ts.Truef(array.RecordEqual(rec, expected), "expected: %s\nactual: %s", expected, rec)
}
+
+// ---- Cookie Tests --------------------
+type CookieTestServer struct {
+ flightsql.BaseServer
+
+ cur time.Time
+}
+
+func (server *CookieTestServer) GetFlightInfoStatement(ctx context.Context, cmd flightsql.StatementQuery, desc *flight.FlightDescriptor) (*flight.FlightInfo, error) {
+ md := metadata.MD{}
+ md.Append("set-cookie", "foo=bar")
+ md.Append("set-cookie", "bar=baz; Max-Age=1")
+ server.cur = time.Now()
+
+ if err := grpc.SendHeader(ctx, md); err != nil {
+ return nil, err
+ }
+
+ tkt, _ := flightsql.CreateStatementQueryTicket([]byte{})
+ info := &flight.FlightInfo{
+ FlightDescriptor: desc,
+ Endpoint: []*flight.FlightEndpoint{
+ {Ticket: &flight.Ticket{Ticket: tkt}},
+ },
+ TotalRecords: -1,
+ TotalBytes: -1,
+ }
+
+ return info, nil
+}
+
+func (server *CookieTestServer) DoGetStatement(ctx context.Context, tkt flightsql.StatementQueryTicket) (*arrow.Schema, <-chan flight.StreamChunk, error) {
+ var (
+ foundFoo, foundBar bool
+ )
+
+ cookies := metadata.ValueFromIncomingContext(ctx, "cookie")
+ for _, line := range cookies {
+ line = textproto.TrimString(line)
+
+ var part string
+ for len(line) > 0 {
+ part, line, _ = strings.Cut(line, ";")
+ part = textproto.TrimString(part)
+ if part == "" {
+ continue
+ }
+
+ name, val, _ := strings.Cut(part, "=")
+ name = textproto.TrimString(name)
+ if len(val) > 1 && val[0] == '"' && val[len(val)-1] == '"' {
+ val = val[1 : len(val)-1]
+ }
+
+ switch name {
+ case "foo":
+ if val == "bar" {
+ foundFoo = true
+ }
+ case "bar":
+ if val == "baz" {
+ foundBar = true
+ }
+ default:
+ return nil, nil, fmt.Errorf("found unexpected cookie '%s' = '%s'", name, val)
+ }
+ }
+ }
+
+ if !foundFoo {
+ return nil, nil, errors.New("missing cookie 'foo'='bar'")
+ }
+
+ if !foundBar && time.Now().Before(server.cur.Add(1*time.Second)) {
+ return nil, nil, errors.New("missing cookie 'bar'='baz'")
+ }
+
+ sc := arrow.NewSchema([]arrow.Field{{Name: "a", Type: arrow.PrimitiveTypes.Int32, Nullable: true}}, nil)
+ rec, _, err := array.RecordFromJSON(memory.DefaultAllocator, sc, strings.NewReader(`[{"a": 5}]`))
+ if err != nil {
+ return nil, nil, err
+ }
+
+ ch := make(chan flight.StreamChunk)
+ go func() {
+ defer close(ch)
+ ch <- flight.StreamChunk{
+ Data: rec,
+ Desc: nil,
+ Err: nil,
+ }
+ }()
+ return sc, ch, nil
+}
+
+type CookieTests struct {
+ ServerBasedTests
+}
+
+func (suite *CookieTests) SetupSuite() {
+ suite.DoSetupSuite(&CookieTestServer{}, nil, map[string]string{
+ driver.OptionCookieMiddleware: adbc.OptionValueEnabled,
+ })
+}
+
+func (suite *CookieTests) TestCookieUsage() {
+ stmt, err := suite.cnxn.NewStatement()
+ suite.Require().NoError(err)
+ defer stmt.Close()
+
+ suite.Require().NoError(stmt.SetSqlQuery("timeout"))
+ reader, _, err := stmt.ExecuteQuery(context.Background())
+ suite.Require().NoError(err)
+ defer reader.Release()
+}
diff --git a/go/adbc/go.mod b/go/adbc/go.mod
index c01265db..21bfad3e 100644
--- a/go/adbc/go.mod
+++ b/go/adbc/go.mod
@@ -20,14 +20,14 @@ module github.com/apache/arrow-adbc/go/adbc
go 1.18
require (
- github.com/apache/arrow/go/v13 v13.0.0-20230612164931-b642707f6de7
+ github.com/apache/arrow/go/v13 v13.0.0-20230620164925-94af6c3c9646
github.com/bluele/gcache v0.0.2
github.com/google/uuid v1.3.0
github.com/snowflakedb/gosnowflake v1.6.21
github.com/stretchr/testify v1.8.2
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
- golang.org/x/sync v0.2.0
- golang.org/x/tools v0.9.1
+ golang.org/x/sync v0.3.0
+ golang.org/x/tools v0.10.0
google.golang.org/grpc v1.54.0
google.golang.org/protobuf v1.30.0
)
@@ -65,7 +65,7 @@ require (
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
- github.com/google/flatbuffers v23.5.9+incompatible // indirect
+ github.com/google/flatbuffers v23.5.26+incompatible // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
@@ -82,12 +82,12 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
- golang.org/x/crypto v0.9.0 // indirect
- golang.org/x/mod v0.10.0 // indirect
- golang.org/x/net v0.10.0 // indirect
- golang.org/x/sys v0.8.0 // indirect
- golang.org/x/term v0.8.0 // indirect
- golang.org/x/text v0.9.0 // indirect
+ golang.org/x/crypto v0.10.0 // indirect
+ golang.org/x/mod v0.11.0 // indirect
+ golang.org/x/net v0.11.0 // indirect
+ golang.org/x/sys v0.9.0 // indirect
+ golang.org/x/term v0.9.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
@@ -102,5 +102,3 @@ require (
modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.1.0 // indirect
)
-
-replace github.com/apache/arrow/go/v12 v12.0.0 => github.com/apache/arrow/go/v12 v12.0.0-20230428025921-06d49ee63e26
diff --git a/go/adbc/go.sum b/go/adbc/go.sum
index d861fbbe..97634848 100644
--- a/go/adbc/go.sum
+++ b/go/adbc/go.sum
@@ -14,10 +14,10 @@ github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvK
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
-github.com/apache/arrow/go/v12 v12.0.0-20230428025921-06d49ee63e26 h1:30dVB4xxWsw05PFJnTTpebmxdpDJeEbX7xDwUMCFwDk=
-github.com/apache/arrow/go/v12 v12.0.0-20230428025921-06d49ee63e26/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw=
-github.com/apache/arrow/go/v13 v13.0.0-20230612164931-b642707f6de7 h1:/IGOeniBVzIXM2HWFKOhUTw8cE9DLxrvqSam8NYgFSA=
-github.com/apache/arrow/go/v13 v13.0.0-20230612164931-b642707f6de7/go.mod h1:W69eByFNO0ZR30q1/7Sr9d83zcVZmF2MiP3fFYAWJOc=
+github.com/apache/arrow/go/v12 v12.0.0 h1:xtZE63VWl7qLdB0JObIXvvhGjoVNrQ9ciIHG2OK5cmc=
+github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg=
+github.com/apache/arrow/go/v13 v13.0.0-20230620164925-94af6c3c9646 h1:hLcsUn9hiiD7jDfJDKOe1tBfOL5v0wgrya5S8XXqzLw=
+github.com/apache/arrow/go/v13 v13.0.0-20230620164925-94af6c3c9646/go.mod h1:W69eByFNO0ZR30q1/7Sr9d83zcVZmF2MiP3fFYAWJOc=
github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY=
@@ -85,8 +85,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/flatbuffers v23.5.9+incompatible h1:mTPHyMn3/qO7lvBcm5S9p0olWUQgtQhBf2QWiz1U3qA=
-github.com/google/flatbuffers v23.5.9+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
+github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg=
+github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
@@ -150,20 +150,20 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
-golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
+golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
+golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
-golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -171,16 +171,16 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
+golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
-golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
+golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
+golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=