[Vendor] Update directly used dependencys (#15593)
* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3 * github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0 * github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2 * github.com/go-chi/cors v1.1.1 -> v1.2.0 * github.com/go-git/go-billy v5.0.0 -> v5.1.0 * github.com/go-git/go-git v5.2.0 -> v5.3.0 * github.com/go-ldap/ldap v3.2.4 -> v3.3.0 * github.com/go-redis/redis v8.6.0 -> v8.8.2 * github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0 * github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0 * github.com/lib/pq v1.9.0 -> v1.10.1 * github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7 * github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0 * github.com/issue9/identicon v1.0.1 -> v1.2.0 * github.com/klauspost/compress v1.11.8 -> v1.12.1 * github.com/mgechev/revive v1.0.3 -> v1.0.6 * github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8 * github.com/niklasfasching/go-org v1.4.0 -> v1.5.0 * github.com/olivere/elastic v7.0.22 -> v7.0.24 * github.com/pelletier/go-toml v1.8.1 -> v1.9.0 * github.com/prometheus/client_golang v1.9.0 -> v1.10.0 * github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0 * github.com/yuin/goldmark v1.3.3 -> v1.3.5 * github.com/6543/go-version v1.2.4 -> v1.3.1 * do github.com/lib/pq v1.10.0 -> v1.10.1 again ...release/v1.15
parent
834fc74873
commit
792b4dba2c
81
go.mod
81
go.mod
|
@ -11,81 +11,74 @@ require (
|
||||||
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
|
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
|
||||||
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee
|
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee
|
||||||
gitea.com/lunny/levelqueue v0.3.0
|
gitea.com/lunny/levelqueue v0.3.0
|
||||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
github.com/Microsoft/go-winio v0.4.18 // indirect
|
||||||
github.com/NYTimes/gziphandler v1.1.1
|
github.com/NYTimes/gziphandler v1.1.1
|
||||||
github.com/PuerkitoBio/goquery v1.5.1
|
github.com/PuerkitoBio/goquery v1.5.1
|
||||||
github.com/RoaringBitmap/roaring v0.5.5 // indirect
|
github.com/RoaringBitmap/roaring v0.6.0 // indirect
|
||||||
github.com/alecthomas/chroma v0.8.2
|
github.com/alecthomas/chroma v0.8.2
|
||||||
github.com/andybalholm/brotli v1.0.1 // indirect
|
github.com/andybalholm/brotli v1.0.1 // indirect
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
||||||
github.com/blevesearch/bleve/v2 v2.0.2
|
github.com/blevesearch/bleve/v2 v2.0.3
|
||||||
github.com/boombuler/barcode v1.0.1 // indirect
|
github.com/boombuler/barcode v1.0.1 // indirect
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
||||||
github.com/caddyserver/certmagic v0.13.0
|
github.com/caddyserver/certmagic v0.13.0
|
||||||
|
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect
|
||||||
github.com/chi-middleware/proxy v1.1.1
|
github.com/chi-middleware/proxy v1.1.1
|
||||||
github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect
|
github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect
|
||||||
github.com/couchbase/gomemcached v0.1.2 // indirect
|
github.com/couchbase/gomemcached v0.1.2 // indirect
|
||||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect
|
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/denisenkom/go-mssqldb v0.10.0
|
||||||
github.com/denisenkom/go-mssqldb v0.9.0
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1
|
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2
|
||||||
github.com/emirpasic/gods v1.12.0
|
github.com/emirpasic/gods v1.12.0
|
||||||
github.com/ethantkoenig/rupture v1.0.0
|
github.com/ethantkoenig/rupture v1.0.0
|
||||||
github.com/gliderlabs/ssh v0.3.2
|
github.com/gliderlabs/ssh v0.3.2
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96 // indirect
|
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
|
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
|
||||||
github.com/go-chi/chi v1.5.4
|
github.com/go-chi/chi v1.5.4
|
||||||
github.com/go-chi/cors v1.1.1
|
github.com/go-chi/cors v1.2.0
|
||||||
github.com/go-enry/go-enry/v2 v2.6.1
|
github.com/go-enry/go-enry/v2 v2.6.1
|
||||||
github.com/go-git/go-billy/v5 v5.0.0
|
github.com/go-git/go-billy/v5 v5.1.0
|
||||||
github.com/go-git/go-git/v5 v5.2.0
|
github.com/go-git/go-git/v5 v5.3.0
|
||||||
github.com/go-ldap/ldap/v3 v3.2.4
|
github.com/go-ldap/ldap/v3 v3.3.0
|
||||||
github.com/go-openapi/errors v0.20.0 // indirect
|
github.com/go-redis/redis/v8 v8.8.2
|
||||||
github.com/go-openapi/validate v0.20.2 // indirect
|
github.com/go-sql-driver/mysql v1.6.0
|
||||||
github.com/go-redis/redis/v8 v8.6.0
|
github.com/go-swagger/go-swagger v0.27.0
|
||||||
github.com/go-sql-driver/mysql v1.5.0
|
github.com/go-testfixtures/testfixtures/v3 v3.6.0
|
||||||
github.com/go-swagger/go-swagger v0.26.1
|
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.5.0
|
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||||
github.com/golang/snappy v0.0.3 // indirect
|
|
||||||
github.com/google/go-github/v32 v32.1.0
|
github.com/google/go-github/v32 v32.1.0
|
||||||
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.2.0
|
github.com/google/uuid v1.2.0
|
||||||
github.com/gorilla/context v1.1.1
|
github.com/gorilla/context v1.1.1
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gorilla/sessions v1.2.1 // indirect
|
github.com/gorilla/sessions v1.2.1 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
|
github.com/hashicorp/go-version v1.3.1
|
||||||
github.com/hashicorp/go-version v1.2.1
|
|
||||||
github.com/huandu/xstrings v1.3.2
|
github.com/huandu/xstrings v1.3.2
|
||||||
github.com/imdario/mergo v0.3.11 // indirect
|
github.com/issue9/identicon v1.2.0
|
||||||
github.com/issue9/assert v1.3.2 // indirect
|
|
||||||
github.com/issue9/identicon v1.0.1
|
|
||||||
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7
|
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7
|
||||||
github.com/json-iterator/go v1.1.10
|
github.com/json-iterator/go v1.1.10
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
github.com/kevinburke/ssh_config v1.1.0 // indirect
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
||||||
github.com/klauspost/compress v1.11.8
|
github.com/klauspost/compress v1.12.1
|
||||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||||
github.com/lafriks/xormstore v1.4.0
|
github.com/lafriks/xormstore v1.4.0
|
||||||
github.com/lib/pq v1.9.0
|
github.com/lib/pq v1.10.1
|
||||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
|
||||||
github.com/markbates/goth v1.67.1
|
github.com/markbates/goth v1.67.1
|
||||||
github.com/mattn/go-isatty v0.0.12
|
github.com/mattn/go-isatty v0.0.12
|
||||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
github.com/mattn/go-runewidth v0.0.12 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.6
|
github.com/mattn/go-sqlite3 v1.14.7
|
||||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81
|
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81
|
||||||
github.com/mgechev/revive v1.0.3
|
github.com/mgechev/revive v1.0.6
|
||||||
github.com/mholt/archiver/v3 v3.5.0
|
github.com/mholt/archiver/v3 v3.5.0
|
||||||
github.com/microcosm-cc/bluemonday v1.0.7
|
github.com/microcosm-cc/bluemonday v1.0.8
|
||||||
github.com/miekg/dns v1.1.41 // indirect
|
github.com/miekg/dns v1.1.40 // indirect
|
||||||
github.com/minio/md5-simd v1.1.2 // indirect
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
github.com/minio/minio-go/v7 v7.0.10
|
github.com/minio/minio-go/v7 v7.0.10
|
||||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||||
|
@ -93,28 +86,23 @@ require (
|
||||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
|
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
|
||||||
github.com/msteinert/pam v0.0.0-20201130170657-e61372126161
|
github.com/msteinert/pam v0.0.0-20201130170657-e61372126161
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/niklasfasching/go-org v1.4.0
|
github.com/niklasfasching/go-org v1.5.0
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
|
||||||
github.com/oliamb/cutter v0.2.2
|
github.com/oliamb/cutter v0.2.2
|
||||||
github.com/olivere/elastic/v7 v7.0.22
|
github.com/olivere/elastic/v7 v7.0.24
|
||||||
github.com/pelletier/go-toml v1.8.1
|
github.com/pelletier/go-toml v1.9.0
|
||||||
github.com/pierrec/lz4/v4 v4.1.3 // indirect
|
github.com/pierrec/lz4/v4 v4.1.3 // indirect
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pquerna/otp v1.3.0
|
github.com/pquerna/otp v1.3.0
|
||||||
github.com/prometheus/client_golang v1.9.0
|
github.com/prometheus/client_golang v1.10.0
|
||||||
github.com/prometheus/common v0.18.0 // indirect
|
|
||||||
github.com/prometheus/procfs v0.6.0 // indirect
|
|
||||||
github.com/quasoft/websspi v1.0.0
|
github.com/quasoft/websspi v1.0.0
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sergi/go-diff v1.1.0
|
github.com/sergi/go-diff v1.2.0
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||||
github.com/spf13/afero v1.5.1 // indirect
|
|
||||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
github.com/tinylib/msgp v1.1.5 // indirect
|
|
||||||
github.com/tstranex/u2f v1.0.0
|
github.com/tstranex/u2f v1.0.0
|
||||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||||
github.com/unknwon/com v1.0.1
|
github.com/unknwon/com v1.0.1
|
||||||
|
@ -123,10 +111,9 @@ require (
|
||||||
github.com/unrolled/render v1.1.0
|
github.com/unrolled/render v1.1.0
|
||||||
github.com/urfave/cli v1.22.5
|
github.com/urfave/cli v1.22.5
|
||||||
github.com/willf/bitset v1.1.11 // indirect
|
github.com/willf/bitset v1.1.11 // indirect
|
||||||
github.com/xanzy/go-gitlab v0.44.0
|
github.com/xanzy/go-gitlab v0.48.0
|
||||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
|
||||||
github.com/yohcop/openid-go v1.0.0
|
github.com/yohcop/openid-go v1.0.0
|
||||||
github.com/yuin/goldmark v1.3.3
|
github.com/yuin/goldmark v1.3.5
|
||||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
||||||
github.com/yuin/goldmark-meta v1.0.0
|
github.com/yuin/goldmark-meta v1.0.0
|
||||||
go.jolheiser.com/hcaptcha v0.0.4
|
go.jolheiser.com/hcaptcha v0.0.4
|
||||||
|
@ -135,7 +122,7 @@ require (
|
||||||
go.uber.org/zap v1.16.0 // indirect
|
go.uber.org/zap v1.16.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
||||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758
|
golang.org/x/net v0.0.0-20210421230115-4e50805a0758
|
||||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93
|
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78
|
||||||
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08
|
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08
|
||||||
golang.org/x/text v0.3.6
|
golang.org/x/text v0.3.6
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||||
|
@ -150,4 +137,4 @@ require (
|
||||||
xorm.io/xorm v1.0.7
|
xorm.io/xorm v1.0.7
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.2.4
|
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
|
||||||
|
|
248
go.sum
248
go.sum
|
@ -53,8 +53,8 @@ gitea.com/lunny/levelqueue v0.3.0 h1:MHn1GuSZkxvVEDMyAPqlc7A3cOW+q8RcGhRgH/xtm6I
|
||||||
gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
|
gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
github.com/6543/go-version v1.2.4 h1:MPsSnqNrM0HwA9tnmWNnsMdQMg4/u4fflARjwomoof4=
|
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
|
||||||
github.com/6543/go-version v1.2.4/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
|
@ -64,8 +64,9 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo
|
||||||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
|
||||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||||
|
github.com/Microsoft/go-winio v0.4.18 h1:yjwCO1nhWEShaA5qsmPOBzAOjRCa2PRLsDNZ5yBWXpg=
|
||||||
|
github.com/Microsoft/go-winio v0.4.18/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
@ -77,8 +78,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||||
github.com/RoaringBitmap/roaring v0.5.5 h1:naNqvO1mNnghk2UvcsqnzHDBn9DRbCIRy94GmDTRVTQ=
|
github.com/RoaringBitmap/roaring v0.6.0 h1:tZcn2nJpUrZf+xQY8x+9QY7BxSETMjkdNG4Ts5zahyU=
|
||||||
github.com/RoaringBitmap/roaring v0.5.5/go.mod h1:puNo5VdzwbaIQxSiDIwfXl4Hnc+fbovcX4IW/dSTtUk=
|
github.com/RoaringBitmap/roaring v0.6.0/go.mod h1:WZ83fjBF/7uBHi6QoFyfGL4+xuV4Qn+xFkm4+vSzrhE=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
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/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
@ -127,12 +128,13 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||||
github.com/aws/aws-sdk-go v1.35.20/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
|
@ -144,8 +146,8 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/blevesearch/bleve/v2 v2.0.1/go.mod h1:OBP2Pktqik8vEiUlGhuWjYx7KiO4zD542+DHqICwM5w=
|
github.com/blevesearch/bleve/v2 v2.0.1/go.mod h1:OBP2Pktqik8vEiUlGhuWjYx7KiO4zD542+DHqICwM5w=
|
||||||
github.com/blevesearch/bleve/v2 v2.0.2 h1:D93VfhOiR6wALovgjsK5XNPeDRrZQlUEIq4YWFeaiTw=
|
github.com/blevesearch/bleve/v2 v2.0.3 h1:mDrwrsRIA4PDYkfUNjoh5zGECvquuJIA3MJU5ivaO8E=
|
||||||
github.com/blevesearch/bleve/v2 v2.0.2/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8=
|
github.com/blevesearch/bleve/v2 v2.0.3/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.0 h1:Ds3XeuTxjXCkG6pgIwWDRyooJKNIuOKemnN0N0IkhTU=
|
github.com/blevesearch/bleve_index_api v1.0.0 h1:Ds3XeuTxjXCkG6pgIwWDRyooJKNIuOKemnN0N0IkhTU=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||||
|
@ -194,6 +196,9 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/chavacava/garif v0.0.0-20210405163807-87a70f3d418b/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
|
||||||
|
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI=
|
||||||
|
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
|
||||||
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
|
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
|
||||||
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
|
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
|
@ -248,8 +253,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
|
||||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
@ -270,8 +275,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
|
||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
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/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/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1 h1:ELDiPZji50x20Wvf9FnP4pb7fE3PV/DNhNd6MRlhgfI=
|
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2 h1:1lkDpSoAaFLrgYTVJ/eNCV+lkDSv/j9Wm0jcvDfVVEo=
|
||||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1/go.mod h1:UHV4+gECABtht7ALQkPdc5gzP77D+4WDUOZAfx8ifx8=
|
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2/go.mod h1:IXeWRVO4LZRoNunhHh/oP6BQvTs94nB2pNvbw32l8tQ=
|
||||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
|
@ -308,9 +313,6 @@ github.com/gliderlabs/ssh v0.3.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
|
||||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96 h1:rCXyLrgJ598XNj7KTqPzAvwTzlyvI+clqasoNfLQStE=
|
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
|
||||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
|
||||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag=
|
github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag=
|
||||||
|
@ -320,28 +322,29 @@ github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
|
||||||
github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg=
|
github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg=
|
||||||
github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo=
|
github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo=
|
||||||
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw=
|
github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
|
||||||
github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I=
|
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0=
|
github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0=
|
||||||
github.com/go-enry/go-enry/v2 v2.6.1/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
github.com/go-enry/go-enry/v2 v2.6.1/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
|
||||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
|
github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk=
|
||||||
|
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||||
github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI=
|
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
|
||||||
github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
|
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
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/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
github.com/go-ldap/ldap/v3 v3.2.4 h1:PFavAq2xTgzo/loE8qNXcQaofAaqIpI4WgaLdv+1l3E=
|
github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
|
||||||
github.com/go-ldap/ldap/v3 v3.2.4/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
|
@ -388,7 +391,6 @@ github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2e
|
||||||
github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
|
github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
|
||||||
github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
|
github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
|
||||||
github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
|
github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
|
||||||
github.com/go-openapi/loads v0.20.1/go.mod h1:/6LfFL8fDvTSX8ypmYXIq3U9Q7nfniSOStW22m864WM=
|
|
||||||
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
|
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
|
||||||
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
|
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
|
||||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||||
|
@ -397,8 +399,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g
|
||||||
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
|
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
|
||||||
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
|
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
|
||||||
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
|
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
|
||||||
github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0=
|
github.com/go-openapi/runtime v0.19.27 h1:4zrQCJoP7rqNCUaApDv1MdPkaa5TuPfO05Lq5WLhX9I=
|
||||||
github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
github.com/go-openapi/runtime v0.19.27/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
||||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||||
|
@ -408,7 +410,6 @@ github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHK
|
||||||
github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
||||||
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
||||||
github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ=
|
github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ=
|
||||||
github.com/go-openapi/spec v0.20.2/go.mod h1:RW6Xcbs6LOyWLU/mXGdzn2Qc+3aj+ASfI7rvSZh1Vls=
|
|
||||||
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
|
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
|
||||||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
||||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||||
|
@ -419,8 +420,9 @@ github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6
|
||||||
github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
||||||
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
||||||
github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
|
github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
|
||||||
github.com/go-openapi/strfmt v0.20.0 h1:l2omNtmNbMc39IGptl9BuXBEKcZfS8zjrTsPKTiJiDM=
|
|
||||||
github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
|
github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
|
||||||
|
github.com/go-openapi/strfmt v0.20.1 h1:1VgxvehFne1mbChGeCmZ5pc0LxUf6yaACVSIYAR91Xc=
|
||||||
|
github.com/go-openapi/strfmt v0.20.1/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk=
|
||||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
|
@ -429,8 +431,9 @@ github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfT
|
||||||
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||||
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
|
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
|
||||||
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||||
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
|
|
||||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||||
|
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||||
|
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||||
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
|
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
|
||||||
|
@ -443,20 +446,21 @@ github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZ
|
||||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
|
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
|
||||||
github.com/go-redis/redis/v8 v8.6.0 h1:swqbqOrxaPztsj2Hf1p94M3YAgl7hYEpcw21z299hh8=
|
github.com/go-redis/redis/v8 v8.8.2 h1:O/NcHqobw7SEptA0yA6up6spZVFtwE06SXM8rgLtsP8=
|
||||||
github.com/go-redis/redis/v8 v8.6.0/go.mod h1:DQ9q4Rk2HtwkrwVrdgmphoOQDMfpvcd/nHEwRsicg8s=
|
github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-swagger/go-swagger v0.26.1 h1:1XUWLnH6hKxHzeKjJfA2gHkSqcT1Zgi4q/PZp2hDdN8=
|
github.com/go-swagger/go-swagger v0.27.0 h1:K7+nkBuf4oS1jTBrdvWqYFpqD69V5CN8HamZzCDDhAI=
|
||||||
github.com/go-swagger/go-swagger v0.26.1/go.mod h1:zlf/LHplZpdtU2mYXg9Ajd3+9TgHYltv5f/pEM6LjnI=
|
github.com/go-swagger/go-swagger v0.27.0/go.mod h1:WodZVysInJilkW7e6IRw+dZGp5yW6rlMFZ4cb+THl9A=
|
||||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
||||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
|
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.5.0 h1:fFJGHhFdcwy48oTLHvr0WRQ09rGiZE+as9ElvbRWS+c=
|
github.com/go-testfixtures/testfixtures/v3 v3.6.0 h1:fHrJWcZ0TOHA0UcExV0Nwx+5MR9QXVDWYdVfwe4DfmM=
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.5.0/go.mod h1:P4L3WxgOsCLbAeUC50qX5rdj1ULZfUMqgCbqah3OH5U=
|
github.com/go-testfixtures/testfixtures/v3 v3.6.0/go.mod h1:YUBpgqvleDRhkx4MQbzdA7A3G5ca2wLtf9bHbDqNaRQ=
|
||||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||||
|
@ -523,8 +527,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
|
||||||
github.com/golang/protobuf v1.4.3/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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||||
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
@ -541,12 +547,14 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/go-cmp v0.5.1/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.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.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
|
||||||
github.com/google/go-cmp v0.5.4/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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
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.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
|
@ -614,7 +622,6 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
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.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
|
||||||
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
|
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
|
||||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||||
|
@ -637,16 +644,14 @@ github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
|
||||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
github.com/issue9/assert v1.4.1 h1:gUtOpMTeaE4JTe9kACma5foOHBvVt1p5XTFrULDwdXI=
|
||||||
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
github.com/issue9/assert v1.4.1/go.mod h1:Yktk83hAVl1SPSYtd9kjhBizuiBIqUQyj+D5SE2yjVY=
|
||||||
github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
github.com/issue9/identicon v1.2.0 h1:ek+UcTTyMW/G0iNbLOAlrPC13eSzXTWhbJSs8PHhHGQ=
|
||||||
github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9Og=
|
github.com/issue9/identicon v1.2.0/go.mod h1:A9toNT0ky/1WP5iNFyDmrkNiYH6eX3HcN5V6uH0g0ec=
|
||||||
github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk=
|
|
||||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
|
@ -693,8 +698,9 @@ github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 h1:g0fAGBisHaE
|
||||||
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||||
|
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
|
@ -720,9 +726,9 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR
|
||||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o=
|
||||||
|
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4=
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4=
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
|
@ -731,8 +737,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
||||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.11.8 h1:difgzQsp5mdAz9v8lm3P/I+EpDKMU/6uTMw1y1FObuo=
|
github.com/klauspost/compress v1.12.1 h1:/+xsCsk06wE38cyiqOR/o7U2fSftcH72xD+BQXmja/g=
|
||||||
github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.12.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/cpuid v1.2.5/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
github.com/klauspost/cpuid v1.2.5/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||||
|
@ -765,10 +771,10 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
|
||||||
|
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI=
|
github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI=
|
||||||
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||||
|
@ -780,8 +786,8 @@ github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VOb
|
||||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
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.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
|
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
@ -810,30 +816,29 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
|
||||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM=
|
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM=
|
||||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||||
github.com/mgechev/revive v1.0.3 h1:z3FL6IFFN3JKzHYHD8O1ExH9g/4lAGJ5x1+9rPZgsFg=
|
github.com/mgechev/revive v1.0.6 h1:MgRQ3ys2uQCyVjelaDhVs8oSvOPYInzGA/nNGMa+MNU=
|
||||||
github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE=
|
github.com/mgechev/revive v1.0.6/go.mod h1:Lj5gIVxjBlH8REa3icEOkdfchwYc291nShzZ4QYWyMo=
|
||||||
github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk=
|
github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk=
|
||||||
github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
|
github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
|
||||||
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
|
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
|
||||||
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
|
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.7 h1:6yAQfk4XT+PI/dk1ZeBp1gr3Q2Hd1DR0O3aEyPUJVTE=
|
github.com/microcosm-cc/bluemonday v1.0.8 h1:JGc6zQRHqlp+UlLrsbUbbp0mOaJLV44vvQmBSU0Sfj0=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.7/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=
|
github.com/microcosm-cc/bluemonday v1.0.8/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
|
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
||||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
|
@ -882,10 +887,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
|
||||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/niklasfasching/go-org v1.4.0 h1:qPy4VEdX55f5QcLiaD3X7N/tY5XOgk4y2uEyQa02i7A=
|
github.com/niklasfasching/go-org v1.5.0 h1:V8IwoSPm/d61bceyWFxxnQLtlvNT+CjiYIhtZLdnMF0=
|
||||||
github.com/niklasfasching/go-org v1.4.0/go.mod h1:4FWT4U/Anir9ewjwNpbZIzMjG5RaXFafkyWZNEPRdk8=
|
github.com/niklasfasching/go-org v1.5.0/go.mod h1:sSb8ylwnAG+h8MGFDB3R1D5bxf8wA08REfhjShg3kjA=
|
||||||
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||||
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
||||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
|
@ -893,15 +897,15 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
||||||
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
||||||
github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s=
|
github.com/olivere/elastic/v7 v7.0.24 h1:9ZcCQP3Pvgese7TaypYiVAL49sCEphyIwkVxtRf8jb8=
|
||||||
github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8=
|
github.com/olivere/elastic/v7 v7.0.24/go.mod h1:OuWmD2DiuYhddWegBKPWQuelVKBLrW0fa/VUYgxuGTY=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
@ -932,12 +936,11 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
|
||||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||||
|
github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0=
|
||||||
|
github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||||
github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ=
|
|
||||||
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
|
||||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
@ -953,7 +956,7 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
|
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
|
||||||
github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs=
|
github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs=
|
||||||
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
@ -962,8 +965,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU=
|
github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg=
|
||||||
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
|
github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
@ -977,7 +980,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
|
||||||
github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y=
|
github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y=
|
||||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
@ -986,7 +988,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
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.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.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
|
||||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
@ -1016,8 +1017,9 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
|
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||||
|
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||||
|
@ -1034,6 +1036,7 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
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/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
|
github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
|
||||||
|
@ -1048,14 +1051,14 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
||||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||||
github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg=
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
|
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
|
@ -1064,6 +1067,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
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/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
|
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
|
||||||
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
||||||
|
@ -1090,15 +1094,12 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP
|
||||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||||
github.com/tinylib/msgp v1.1.5 h1:2gXmtWueD2HefZHQe1QOy9HVzmFrLOVvsXwXBQ0ayy0=
|
|
||||||
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
|
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
||||||
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
||||||
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
||||||
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
||||||
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
|
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||||
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
|
@ -1123,11 +1124,13 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv
|
||||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
||||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||||
github.com/xanzy/go-gitlab v0.44.0 h1:cEiGhqu7EpFGuei2a2etAwB+x6403E5CvpLn35y+GPs=
|
github.com/xanzy/go-gitlab v0.48.0 h1:RP9r4pMDIwE2fbtc+QYiC1euDsPGHcAjPkhje4X3QPU=
|
||||||
github.com/xanzy/go-gitlab v0.44.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
github.com/xanzy/go-gitlab v0.48.0/go.mod h1:UW8JJbyBbqtOyBYNHRo261IRdHUFJr2m0y0z1xUiu+E=
|
||||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
|
||||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||||
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
|
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||||
|
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||||
|
@ -1136,13 +1139,14 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE=
|
github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE=
|
||||||
github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI=
|
github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||||
github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
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.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/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.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.3 h1:37BdQwPx8VOSic8eDSWee6QL9mRpZRm9VJp/QugNrW0=
|
github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
|
||||||
github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
|
||||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
||||||
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
||||||
|
@ -1164,9 +1168,9 @@ go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS
|
||||||
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
||||||
go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||||
go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||||
go.mongodb.org/mongo-driver v1.4.5/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
|
||||||
go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU=
|
|
||||||
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||||
|
go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI=
|
||||||
|
go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
|
@ -1175,15 +1179,16 @@ 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.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/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.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||||
|
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||||
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
|
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
|
||||||
go.opentelemetry.io/otel v0.17.0 h1:6MKOu8WY4hmfpQ4oQn34u6rYhnf2sWf1LXYO/UFm71U=
|
go.opentelemetry.io/otel v0.19.0 h1:Lenfy7QHRXPZVsw/12CWpxX6d/JkrX8wrx2vO8G80Ng=
|
||||||
go.opentelemetry.io/otel v0.17.0/go.mod h1:Oqtdxmf7UtEvL037ohlgnaYa1h7GtMh0NcSd9eqkC9s=
|
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
|
||||||
go.opentelemetry.io/otel/metric v0.17.0 h1:t+5EioN8YFXQ2EH+1j6FHCKMUj+57zIDSnSGr/mWuug=
|
go.opentelemetry.io/otel/metric v0.19.0 h1:dtZ1Ju44gkJkYvo+3qGqVXmf88tc+a42edOywypengg=
|
||||||
go.opentelemetry.io/otel/metric v0.17.0/go.mod h1:hUz9lH1rNXyEwWAhIWCMFWKhYtpASgSnObJFnU26dJ0=
|
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
|
||||||
go.opentelemetry.io/otel/oteltest v0.17.0 h1:TyAihUowTDLqb4+m5ePAsR71xPJaTBJl4KDArIdi9k4=
|
go.opentelemetry.io/otel/oteltest v0.19.0 h1:YVfA0ByROYqTwOxqHVZYZExzEpfZor+MU1rU+ip2v9Q=
|
||||||
go.opentelemetry.io/otel/oteltest v0.17.0/go.mod h1:JT/LGFxPwpN+nlsTiinSYjdIx3hZIGqHCpChcIZmdoE=
|
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
|
||||||
go.opentelemetry.io/otel/trace v0.17.0 h1:SBOj64/GAOyWzs5F680yW1ITIfJkm6cJWL2YAvuL9xY=
|
go.opentelemetry.io/otel/trace v0.19.0 h1:1ucYlenXIDA1OlHVLDZKX0ObXV5RLaq06DtUKz5e5zc=
|
||||||
go.opentelemetry.io/otel/trace v0.17.0/go.mod h1:bIujpqg6ZL6xUTubIUgziI1jSaUPthmabA/ygf/6Cfg=
|
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
@ -1226,7 +1231,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
@ -1262,8 +1267,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
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.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.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||||
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -1318,6 +1324,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||||
|
golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
|
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
|
||||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||||
|
@ -1331,8 +1339,9 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/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-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-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 h1:alLDrZkL34Y2bnGHfvC1CYBRBXCXgx8AC2vY4MRtYX4=
|
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/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-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -1343,9 +1352,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
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-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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -1358,7 +1366,6 @@ golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/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-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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -1409,20 +1416,19 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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-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-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-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU=
|
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU=
|
||||||
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -1502,9 +1508,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/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-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
@ -1617,16 +1621,19 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
@ -1651,7 +1658,6 @@ 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=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
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 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
* @microsoft/containerplat
|
|
@ -5,21 +5,14 @@ package winio
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
|
||||||
|
|
||||||
//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
|
"golang.org/x/sys/windows"
|
||||||
//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
|
|
||||||
|
|
||||||
const (
|
|
||||||
fileBasicInfo = 0
|
|
||||||
fileIDInfo = 0x12
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileBasicInfo contains file access time and file attributes information.
|
// FileBasicInfo contains file access time and file attributes information.
|
||||||
type FileBasicInfo struct {
|
type FileBasicInfo struct {
|
||||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
|
CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime
|
||||||
FileAttributes uint32
|
FileAttributes uint32
|
||||||
pad uint32 // padding
|
pad uint32 // padding
|
||||||
}
|
}
|
||||||
|
@ -27,7 +20,7 @@ type FileBasicInfo struct {
|
||||||
// GetFileBasicInfo retrieves times and attributes for a file.
|
// GetFileBasicInfo retrieves times and attributes for a file.
|
||||||
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
||||||
bi := &FileBasicInfo{}
|
bi := &FileBasicInfo{}
|
||||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||||
}
|
}
|
||||||
runtime.KeepAlive(f)
|
runtime.KeepAlive(f)
|
||||||
|
@ -36,13 +29,32 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
||||||
|
|
||||||
// SetFileBasicInfo sets times and attributes for a file.
|
// SetFileBasicInfo sets times and attributes for a file.
|
||||||
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
||||||
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
if err := windows.SetFileInformationByHandle(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||||
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
||||||
}
|
}
|
||||||
runtime.KeepAlive(f)
|
runtime.KeepAlive(f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileStandardInfo contains extended information for the file.
|
||||||
|
// FILE_STANDARD_INFO in WinBase.h
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
|
||||||
|
type FileStandardInfo struct {
|
||||||
|
AllocationSize, EndOfFile int64
|
||||||
|
NumberOfLinks uint32
|
||||||
|
DeletePending, Directory bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileStandardInfo retrieves ended information for the file.
|
||||||
|
func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {
|
||||||
|
si := &FileStandardInfo{}
|
||||||
|
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileStandardInfo, (*byte)(unsafe.Pointer(si)), uint32(unsafe.Sizeof(*si))); err != nil {
|
||||||
|
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||||
|
}
|
||||||
|
runtime.KeepAlive(f)
|
||||||
|
return si, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
|
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
|
||||||
// unique on a system.
|
// unique on a system.
|
||||||
type FileIDInfo struct {
|
type FileIDInfo struct {
|
||||||
|
@ -53,7 +65,7 @@ type FileIDInfo struct {
|
||||||
// GetFileID retrieves the unique (volume, file ID) pair for a file.
|
// GetFileID retrieves the unique (volume, file ID) pair for a file.
|
||||||
func GetFileID(f *os.File) (*FileIDInfo, error) {
|
func GetFileID(f *os.File) (*FileIDInfo, error) {
|
||||||
fileID := &FileIDInfo{}
|
fileID := &FileIDInfo{}
|
||||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileIdInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
||||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||||
}
|
}
|
||||||
runtime.KeepAlive(f)
|
runtime.KeepAlive(f)
|
||||||
|
|
|
@ -4,6 +4,6 @@ go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.7.0
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
package winio
|
package winio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
// Package guid provides a GUID type. The backing structure for a GUID is
|
// Package guid provides a GUID type. The backing structure for a GUID is
|
||||||
// identical to that used by the golang.org/x/sys/windows GUID type.
|
// identical to that used by the golang.org/x/sys/windows GUID type.
|
||||||
// There are two main binary encodings used for a GUID, the big-endian encoding,
|
// There are two main binary encodings used for a GUID, the big-endian encoding,
|
||||||
|
|
|
@ -28,8 +28,9 @@ const (
|
||||||
|
|
||||||
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
|
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
|
||||||
|
|
||||||
SeBackupPrivilege = "SeBackupPrivilege"
|
SeBackupPrivilege = "SeBackupPrivilege"
|
||||||
SeRestorePrivilege = "SeRestorePrivilege"
|
SeRestorePrivilege = "SeRestorePrivilege"
|
||||||
|
SeSecurityPrivilege = "SeSecurityPrivilege"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
package winio
|
package winio
|
||||||
|
|
||||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
||||||
|
|
|
@ -19,6 +19,7 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||||
|
errERROR_EINVAL error = syscall.EINVAL
|
||||||
)
|
)
|
||||||
|
|
||||||
// errnoErr returns common boxed Errno values, to prevent
|
// errnoErr returns common boxed Errno values, to prevent
|
||||||
|
@ -26,7 +27,7 @@ var (
|
||||||
func errnoErr(e syscall.Errno) error {
|
func errnoErr(e syscall.Errno) error {
|
||||||
switch e {
|
switch e {
|
||||||
case 0:
|
case 0:
|
||||||
return nil
|
return errERROR_EINVAL
|
||||||
case errnoERROR_IO_PENDING:
|
case errnoERROR_IO_PENDING:
|
||||||
return errERROR_IO_PENDING
|
return errERROR_IO_PENDING
|
||||||
}
|
}
|
||||||
|
@ -37,243 +38,62 @@ func errnoErr(e syscall.Errno) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
|
||||||
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
|
||||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
|
||||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
|
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
|
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||||
|
|
||||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
||||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
|
||||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
|
||||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
|
||||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
|
||||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
|
||||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
|
||||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
|
||||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
|
||||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
|
||||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
|
||||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
|
||||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
|
||||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
|
||||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
|
||||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
|
||||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
|
||||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
||||||
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
|
||||||
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
|
||||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
|
||||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
||||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
|
||||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
|
||||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
|
||||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
|
||||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||||
|
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
||||||
|
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||||
|
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||||
|
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||||
|
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||||
|
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||||
|
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||||
|
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||||
|
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||||
|
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||||
|
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||||
|
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||||
|
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||||
|
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||||
|
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||||
|
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||||
|
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||||
|
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||||
|
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||||
|
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||||
|
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||||
procbind = modws2_32.NewProc("bind")
|
procbind = modws2_32.NewProc("bind")
|
||||||
)
|
)
|
||||||
|
|
||||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
|
||||||
newport = syscall.Handle(r0)
|
|
||||||
if newport == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if wait {
|
if releaseAll {
|
||||||
_p0 = 1
|
_p0 = 1
|
||||||
} else {
|
|
||||||
_p0 = 0
|
|
||||||
}
|
}
|
||||||
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
||||||
|
success = r0 != 0
|
||||||
|
if true {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
|
||||||
handle = syscall.Handle(r0)
|
|
||||||
if handle == syscall.InvalidHandle {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
|
||||||
handle = syscall.Handle(r0)
|
|
||||||
if handle == syscall.InvalidHandle {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
|
||||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
|
||||||
ptr = uintptr(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
|
||||||
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
|
||||||
status = ntstatus(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
|
||||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
|
||||||
if r0 != 0 {
|
|
||||||
winerr = syscall.Errno(r0)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
|
||||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
|
||||||
status = ntstatus(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
|
||||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
|
||||||
status = ntstatus(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -281,11 +101,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS
|
||||||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -302,126 +118,73 @@ func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision ui
|
||||||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func localFree(mem uintptr) {
|
|
||||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
||||||
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
||||||
len = uint32(r0)
|
len = uint32(r0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
|
||||||
var _p0 uint32
|
|
||||||
if releaseAll {
|
|
||||||
_p0 = 1
|
|
||||||
} else {
|
|
||||||
_p0 = 0
|
|
||||||
}
|
|
||||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
|
||||||
success = r0 != 0
|
|
||||||
if true {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func impersonateSelf(level uint32) (err error) {
|
func impersonateSelf(level uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func revertToSelf() (err error) {
|
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
var _p0 *uint16
|
||||||
|
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||||
var _p0 uint32
|
var _p0 *uint16
|
||||||
if openAsSelf {
|
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||||
_p0 = 1
|
if err != nil {
|
||||||
} else {
|
return
|
||||||
_p0 = 0
|
|
||||||
}
|
}
|
||||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCurrentThread() (h syscall.Handle) {
|
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
var _p0 *uint16
|
||||||
h = syscall.Handle(r0)
|
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,53 +205,27 @@ func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err err
|
||||||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
||||||
var _p0 *uint16
|
var _p0 uint32
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
if openAsSelf {
|
||||||
if err != nil {
|
_p0 = 1
|
||||||
return
|
|
||||||
}
|
}
|
||||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
func revertToSelf() (err error) {
|
||||||
var _p0 *uint16
|
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -501,22 +238,14 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce
|
||||||
var _p1 uint32
|
var _p1 uint32
|
||||||
if abort {
|
if abort {
|
||||||
_p1 = 1
|
_p1 = 1
|
||||||
} else {
|
|
||||||
_p1 = 0
|
|
||||||
}
|
}
|
||||||
var _p2 uint32
|
var _p2 uint32
|
||||||
if processSecurity {
|
if processSecurity {
|
||||||
_p2 = 1
|
_p2 = 1
|
||||||
} else {
|
|
||||||
_p2 = 0
|
|
||||||
}
|
}
|
||||||
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -529,22 +258,162 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
||||||
var _p1 uint32
|
var _p1 uint32
|
||||||
if abort {
|
if abort {
|
||||||
_p1 = 1
|
_p1 = 1
|
||||||
} else {
|
|
||||||
_p1 = 0
|
|
||||||
}
|
}
|
||||||
var _p2 uint32
|
var _p2 uint32
|
||||||
if processSecurity {
|
if processSecurity {
|
||||||
_p2 = 1
|
_p2 = 1
|
||||||
} else {
|
|
||||||
_p2 = 0
|
|
||||||
}
|
}
|
||||||
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
}
|
||||||
} else {
|
return
|
||||||
err = syscall.EINVAL
|
}
|
||||||
}
|
|
||||||
|
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||||
|
var _p0 *uint16
|
||||||
|
_p0, err = syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
||||||
|
handle = syscall.Handle(r0)
|
||||||
|
if handle == syscall.InvalidHandle {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
||||||
|
newport = syscall.Handle(r0)
|
||||||
|
if newport == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||||
|
var _p0 *uint16
|
||||||
|
_p0, err = syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
||||||
|
handle = syscall.Handle(r0)
|
||||||
|
if handle == syscall.InvalidHandle {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCurrentThread() (h syscall.Handle) {
|
||||||
|
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
||||||
|
h = syscall.Handle(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
||||||
|
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
||||||
|
ptr = uintptr(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func localFree(mem uintptr) {
|
||||||
|
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
||||||
|
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||||
|
status = ntstatus(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||||
|
status = ntstatus(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
||||||
|
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||||
|
status = ntstatus(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
winerr = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||||
|
var _p0 uint32
|
||||||
|
if wait {
|
||||||
|
_p0 = 1
|
||||||
|
}
|
||||||
|
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -552,11 +421,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
||||||
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
||||||
if r1 == socketError {
|
if r1 == socketError {
|
||||||
if e1 != 0 {
|
err = errnoErr(e1)
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,4 +3,3 @@ roaring-fuzz.zip
|
||||||
workdir
|
workdir
|
||||||
coverage.out
|
coverage.out
|
||||||
testdata/all3.classic
|
testdata/all3.classic
|
||||||
testdata/all3.msgp.snappy
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
script:
|
script:
|
||||||
- goveralls -v -service travis-ci -ignore arraycontainer_gen.go,bitmapcontainer_gen.go,rle16_gen.go,rle_gen.go,roaringarray_gen.go,rle.go || go test
|
- goveralls -v -service travis-ci -ignore rle16_gen.go,rle_gen.go,rle.go || go test
|
||||||
- go test -race -run TestConcurrent*
|
- go test -race -run TestConcurrent*
|
||||||
- go build -tags appengine
|
- go build -tags appengine
|
||||||
- go test -tags appengine
|
- go test -tags appengine
|
||||||
|
|
|
@ -97,10 +97,6 @@ nuke:
|
||||||
rm -rf ./target
|
rm -rf ./target
|
||||||
GOPATH=$(GOPATH) go clean -i ./...
|
GOPATH=$(GOPATH) go clean -i ./...
|
||||||
|
|
||||||
|
|
||||||
ser:
|
|
||||||
go generate
|
|
||||||
|
|
||||||
cover:
|
cover:
|
||||||
go test -coverprofile=coverage.out
|
go test -coverprofile=coverage.out
|
||||||
go tool cover -html=coverage.out
|
go tool cover -html=coverage.out
|
||||||
|
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate msgp -unexported
|
|
||||||
|
|
||||||
type arrayContainer struct {
|
type arrayContainer struct {
|
||||||
content []uint16
|
content []uint16
|
||||||
}
|
}
|
||||||
|
@ -485,7 +483,7 @@ func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int {
|
||||||
func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
|
func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
|
||||||
value1 := ac
|
value1 := ac
|
||||||
maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
|
maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
|
||||||
if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!^M
|
if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!
|
||||||
bc := newBitmapContainer()
|
bc := newBitmapContainer()
|
||||||
for k := 0; k < len(value2.content); k++ {
|
for k := 0; k < len(value2.content); k++ {
|
||||||
v := value2.content[k]
|
v := value2.content[k]
|
||||||
|
|
|
@ -1,134 +0,0 @@
|
||||||
package roaring
|
|
||||||
|
|
||||||
// NOTE: THIS FILE WAS PRODUCED BY THE
|
|
||||||
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
|
|
||||||
// DO NOT EDIT
|
|
||||||
|
|
||||||
import "github.com/tinylib/msgp/msgp"
|
|
||||||
|
|
||||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *arrayContainer) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zbzg uint32
|
|
||||||
zbzg, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zbzg > 0 {
|
|
||||||
zbzg--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "content":
|
|
||||||
var zbai uint32
|
|
||||||
zbai, err = dc.ReadArrayHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.content) >= int(zbai) {
|
|
||||||
z.content = (z.content)[:zbai]
|
|
||||||
} else {
|
|
||||||
z.content = make([]uint16, zbai)
|
|
||||||
}
|
|
||||||
for zxvk := range z.content {
|
|
||||||
z.content[zxvk], err = dc.ReadUint16()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
|
||||||
func (z *arrayContainer) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
// map header, size 1
|
|
||||||
// write "content"
|
|
||||||
err = en.Append(0x81, 0xa7, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteArrayHeader(uint32(len(z.content)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zxvk := range z.content {
|
|
||||||
err = en.WriteUint16(z.content[zxvk])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z *arrayContainer) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
// map header, size 1
|
|
||||||
// string "content"
|
|
||||||
o = append(o, 0x81, 0xa7, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74)
|
|
||||||
o = msgp.AppendArrayHeader(o, uint32(len(z.content)))
|
|
||||||
for zxvk := range z.content {
|
|
||||||
o = msgp.AppendUint16(o, z.content[zxvk])
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *arrayContainer) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zcmr uint32
|
|
||||||
zcmr, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zcmr > 0 {
|
|
||||||
zcmr--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "content":
|
|
||||||
var zajw uint32
|
|
||||||
zajw, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.content) >= int(zajw) {
|
|
||||||
z.content = (z.content)[:zajw]
|
|
||||||
} else {
|
|
||||||
z.content = make([]uint16, zajw)
|
|
||||||
}
|
|
||||||
for zxvk := range z.content {
|
|
||||||
z.content[zxvk], bts, err = msgp.ReadUint16Bytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z *arrayContainer) Msgsize() (s int) {
|
|
||||||
s = 1 + 8 + msgp.ArrayHeaderSize + (len(z.content) * (msgp.Uint16Size))
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate msgp -unexported
|
|
||||||
|
|
||||||
type bitmapContainer struct {
|
type bitmapContainer struct {
|
||||||
cardinality int
|
cardinality int
|
||||||
bitmap []uint64
|
bitmap []uint64
|
||||||
|
@ -115,7 +113,7 @@ type bitmapContainerShortIterator struct {
|
||||||
|
|
||||||
func (bcsi *bitmapContainerShortIterator) next() uint16 {
|
func (bcsi *bitmapContainerShortIterator) next() uint16 {
|
||||||
j := bcsi.i
|
j := bcsi.i
|
||||||
bcsi.i = bcsi.ptr.NextSetBit(bcsi.i + 1)
|
bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1)
|
||||||
return uint16(j)
|
return uint16(j)
|
||||||
}
|
}
|
||||||
func (bcsi *bitmapContainerShortIterator) hasNext() bool {
|
func (bcsi *bitmapContainerShortIterator) hasNext() bool {
|
||||||
|
@ -128,7 +126,7 @@ func (bcsi *bitmapContainerShortIterator) peekNext() uint16 {
|
||||||
|
|
||||||
func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) {
|
func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) {
|
||||||
if bcsi.hasNext() && bcsi.peekNext() < minval {
|
if bcsi.hasNext() && bcsi.peekNext() < minval {
|
||||||
bcsi.i = bcsi.ptr.NextSetBit(int(minval))
|
bcsi.i = bcsi.ptr.NextSetBit(uint(minval))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,20 +1007,23 @@ func (bc *bitmapContainer) fillArray(container []uint16) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *bitmapContainer) NextSetBit(i int) int {
|
func (bc *bitmapContainer) NextSetBit(i uint) int {
|
||||||
x := i / 64
|
var (
|
||||||
if x >= len(bc.bitmap) {
|
x = i / 64
|
||||||
|
length = uint(len(bc.bitmap))
|
||||||
|
)
|
||||||
|
if x >= length {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
w := bc.bitmap[x]
|
w := bc.bitmap[x]
|
||||||
w = w >> uint(i%64)
|
w = w >> uint(i%64)
|
||||||
if w != 0 {
|
if w != 0 {
|
||||||
return i + countTrailingZeros(w)
|
return int(i) + countTrailingZeros(w)
|
||||||
}
|
}
|
||||||
x++
|
x++
|
||||||
for ; x < len(bc.bitmap); x++ {
|
for ; x < length; x++ {
|
||||||
if bc.bitmap[x] != 0 {
|
if bc.bitmap[x] != 0 {
|
||||||
return (x * 64) + countTrailingZeros(bc.bitmap[x])
|
return int(x*64) + countTrailingZeros(bc.bitmap[x])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
|
|
|
@ -1,415 +0,0 @@
|
||||||
package roaring
|
|
||||||
|
|
||||||
// NOTE: THIS FILE WAS PRODUCED BY THE
|
|
||||||
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
|
|
||||||
// DO NOT EDIT
|
|
||||||
|
|
||||||
import "github.com/tinylib/msgp/msgp"
|
|
||||||
|
|
||||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *bitmapContainer) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zbzg uint32
|
|
||||||
zbzg, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zbzg > 0 {
|
|
||||||
zbzg--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "cardinality":
|
|
||||||
z.cardinality, err = dc.ReadInt()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "bitmap":
|
|
||||||
var zbai uint32
|
|
||||||
zbai, err = dc.ReadArrayHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.bitmap) >= int(zbai) {
|
|
||||||
z.bitmap = (z.bitmap)[:zbai]
|
|
||||||
} else {
|
|
||||||
z.bitmap = make([]uint64, zbai)
|
|
||||||
}
|
|
||||||
for zxvk := range z.bitmap {
|
|
||||||
z.bitmap[zxvk], err = dc.ReadUint64()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
|
||||||
func (z *bitmapContainer) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
// map header, size 2
|
|
||||||
// write "cardinality"
|
|
||||||
err = en.Append(0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteInt(z.cardinality)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// write "bitmap"
|
|
||||||
err = en.Append(0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteArrayHeader(uint32(len(z.bitmap)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zxvk := range z.bitmap {
|
|
||||||
err = en.WriteUint64(z.bitmap[zxvk])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z *bitmapContainer) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
// map header, size 2
|
|
||||||
// string "cardinality"
|
|
||||||
o = append(o, 0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
|
||||||
o = msgp.AppendInt(o, z.cardinality)
|
|
||||||
// string "bitmap"
|
|
||||||
o = append(o, 0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
|
||||||
o = msgp.AppendArrayHeader(o, uint32(len(z.bitmap)))
|
|
||||||
for zxvk := range z.bitmap {
|
|
||||||
o = msgp.AppendUint64(o, z.bitmap[zxvk])
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *bitmapContainer) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zcmr uint32
|
|
||||||
zcmr, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zcmr > 0 {
|
|
||||||
zcmr--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "cardinality":
|
|
||||||
z.cardinality, bts, err = msgp.ReadIntBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "bitmap":
|
|
||||||
var zajw uint32
|
|
||||||
zajw, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.bitmap) >= int(zajw) {
|
|
||||||
z.bitmap = (z.bitmap)[:zajw]
|
|
||||||
} else {
|
|
||||||
z.bitmap = make([]uint64, zajw)
|
|
||||||
}
|
|
||||||
for zxvk := range z.bitmap {
|
|
||||||
z.bitmap[zxvk], bts, err = msgp.ReadUint64Bytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z *bitmapContainer) Msgsize() (s int) {
|
|
||||||
s = 1 + 12 + msgp.IntSize + 7 + msgp.ArrayHeaderSize + (len(z.bitmap) * (msgp.Uint64Size))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *bitmapContainerShortIterator) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zhct uint32
|
|
||||||
zhct, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zhct > 0 {
|
|
||||||
zhct--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "ptr":
|
|
||||||
if dc.IsNil() {
|
|
||||||
err = dc.ReadNil()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
z.ptr = nil
|
|
||||||
} else {
|
|
||||||
if z.ptr == nil {
|
|
||||||
z.ptr = new(bitmapContainer)
|
|
||||||
}
|
|
||||||
var zcua uint32
|
|
||||||
zcua, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zcua > 0 {
|
|
||||||
zcua--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "cardinality":
|
|
||||||
z.ptr.cardinality, err = dc.ReadInt()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "bitmap":
|
|
||||||
var zxhx uint32
|
|
||||||
zxhx, err = dc.ReadArrayHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.ptr.bitmap) >= int(zxhx) {
|
|
||||||
z.ptr.bitmap = (z.ptr.bitmap)[:zxhx]
|
|
||||||
} else {
|
|
||||||
z.ptr.bitmap = make([]uint64, zxhx)
|
|
||||||
}
|
|
||||||
for zwht := range z.ptr.bitmap {
|
|
||||||
z.ptr.bitmap[zwht], err = dc.ReadUint64()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "i":
|
|
||||||
z.i, err = dc.ReadInt()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
|
||||||
func (z *bitmapContainerShortIterator) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
// map header, size 2
|
|
||||||
// write "ptr"
|
|
||||||
err = en.Append(0x82, 0xa3, 0x70, 0x74, 0x72)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if z.ptr == nil {
|
|
||||||
err = en.WriteNil()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// map header, size 2
|
|
||||||
// write "cardinality"
|
|
||||||
err = en.Append(0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteInt(z.ptr.cardinality)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// write "bitmap"
|
|
||||||
err = en.Append(0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteArrayHeader(uint32(len(z.ptr.bitmap)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zwht := range z.ptr.bitmap {
|
|
||||||
err = en.WriteUint64(z.ptr.bitmap[zwht])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// write "i"
|
|
||||||
err = en.Append(0xa1, 0x69)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteInt(z.i)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z *bitmapContainerShortIterator) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
// map header, size 2
|
|
||||||
// string "ptr"
|
|
||||||
o = append(o, 0x82, 0xa3, 0x70, 0x74, 0x72)
|
|
||||||
if z.ptr == nil {
|
|
||||||
o = msgp.AppendNil(o)
|
|
||||||
} else {
|
|
||||||
// map header, size 2
|
|
||||||
// string "cardinality"
|
|
||||||
o = append(o, 0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
|
||||||
o = msgp.AppendInt(o, z.ptr.cardinality)
|
|
||||||
// string "bitmap"
|
|
||||||
o = append(o, 0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
|
||||||
o = msgp.AppendArrayHeader(o, uint32(len(z.ptr.bitmap)))
|
|
||||||
for zwht := range z.ptr.bitmap {
|
|
||||||
o = msgp.AppendUint64(o, z.ptr.bitmap[zwht])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// string "i"
|
|
||||||
o = append(o, 0xa1, 0x69)
|
|
||||||
o = msgp.AppendInt(o, z.i)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *bitmapContainerShortIterator) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zlqf uint32
|
|
||||||
zlqf, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zlqf > 0 {
|
|
||||||
zlqf--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "ptr":
|
|
||||||
if msgp.IsNil(bts) {
|
|
||||||
bts, err = msgp.ReadNilBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
z.ptr = nil
|
|
||||||
} else {
|
|
||||||
if z.ptr == nil {
|
|
||||||
z.ptr = new(bitmapContainer)
|
|
||||||
}
|
|
||||||
var zdaf uint32
|
|
||||||
zdaf, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zdaf > 0 {
|
|
||||||
zdaf--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "cardinality":
|
|
||||||
z.ptr.cardinality, bts, err = msgp.ReadIntBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "bitmap":
|
|
||||||
var zpks uint32
|
|
||||||
zpks, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.ptr.bitmap) >= int(zpks) {
|
|
||||||
z.ptr.bitmap = (z.ptr.bitmap)[:zpks]
|
|
||||||
} else {
|
|
||||||
z.ptr.bitmap = make([]uint64, zpks)
|
|
||||||
}
|
|
||||||
for zwht := range z.ptr.bitmap {
|
|
||||||
z.ptr.bitmap[zwht], bts, err = msgp.ReadUint64Bytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "i":
|
|
||||||
z.i, bts, err = msgp.ReadIntBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z *bitmapContainerShortIterator) Msgsize() (s int) {
|
|
||||||
s = 1 + 4
|
|
||||||
if z.ptr == nil {
|
|
||||||
s += msgp.NilSize
|
|
||||||
} else {
|
|
||||||
s += 1 + 12 + msgp.IntSize + 7 + msgp.ArrayHeaderSize + (len(z.ptr.bitmap) * (msgp.Uint64Size))
|
|
||||||
}
|
|
||||||
s += 2 + msgp.IntSize
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,161 +0,0 @@
|
||||||
package roaring
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type byteInput interface {
|
|
||||||
// next returns a slice containing the next n bytes from the buffer,
|
|
||||||
// advancing the buffer as if the bytes had been returned by Read.
|
|
||||||
next(n int) ([]byte, error)
|
|
||||||
// readUInt32 reads uint32 with LittleEndian order
|
|
||||||
readUInt32() (uint32, error)
|
|
||||||
// readUInt16 reads uint16 with LittleEndian order
|
|
||||||
readUInt16() (uint16, error)
|
|
||||||
// getReadBytes returns read bytes
|
|
||||||
getReadBytes() int64
|
|
||||||
// skipBytes skips exactly n bytes
|
|
||||||
skipBytes(n int) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newByteInputFromReader(reader io.Reader) byteInput {
|
|
||||||
return &byteInputAdapter{
|
|
||||||
r: reader,
|
|
||||||
readBytes: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newByteInput(buf []byte) byteInput {
|
|
||||||
return &byteBuffer{
|
|
||||||
buf: buf,
|
|
||||||
off: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type byteBuffer struct {
|
|
||||||
buf []byte
|
|
||||||
off int
|
|
||||||
}
|
|
||||||
|
|
||||||
// next returns a slice containing the next n bytes from the reader
|
|
||||||
// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned
|
|
||||||
func (b *byteBuffer) next(n int) ([]byte, error) {
|
|
||||||
m := len(b.buf) - b.off
|
|
||||||
|
|
||||||
if n > m {
|
|
||||||
return nil, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
|
|
||||||
data := b.buf[b.off : b.off+n]
|
|
||||||
b.off += n
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// readUInt32 reads uint32 with LittleEndian order
|
|
||||||
func (b *byteBuffer) readUInt32() (uint32, error) {
|
|
||||||
if len(b.buf)-b.off < 4 {
|
|
||||||
return 0, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
|
|
||||||
v := binary.LittleEndian.Uint32(b.buf[b.off:])
|
|
||||||
b.off += 4
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// readUInt16 reads uint16 with LittleEndian order
|
|
||||||
func (b *byteBuffer) readUInt16() (uint16, error) {
|
|
||||||
if len(b.buf)-b.off < 2 {
|
|
||||||
return 0, io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
|
|
||||||
v := binary.LittleEndian.Uint16(b.buf[b.off:])
|
|
||||||
b.off += 2
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getReadBytes returns read bytes
|
|
||||||
func (b *byteBuffer) getReadBytes() int64 {
|
|
||||||
return int64(b.off)
|
|
||||||
}
|
|
||||||
|
|
||||||
// skipBytes skips exactly n bytes
|
|
||||||
func (b *byteBuffer) skipBytes(n int) error {
|
|
||||||
m := len(b.buf) - b.off
|
|
||||||
|
|
||||||
if n > m {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
|
|
||||||
b.off += n
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset resets the given buffer with a new byte slice
|
|
||||||
func (b *byteBuffer) reset(buf []byte) {
|
|
||||||
b.buf = buf
|
|
||||||
b.off = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type byteInputAdapter struct {
|
|
||||||
r io.Reader
|
|
||||||
readBytes int
|
|
||||||
}
|
|
||||||
|
|
||||||
// next returns a slice containing the next n bytes from the buffer,
|
|
||||||
// advancing the buffer as if the bytes had been returned by Read.
|
|
||||||
func (b *byteInputAdapter) next(n int) ([]byte, error) {
|
|
||||||
buf := make([]byte, n)
|
|
||||||
m, err := io.ReadAtLeast(b.r, buf, n)
|
|
||||||
b.readBytes += m
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// readUInt32 reads uint32 with LittleEndian order
|
|
||||||
func (b *byteInputAdapter) readUInt32() (uint32, error) {
|
|
||||||
buf, err := b.next(4)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return binary.LittleEndian.Uint32(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// readUInt16 reads uint16 with LittleEndian order
|
|
||||||
func (b *byteInputAdapter) readUInt16() (uint16, error) {
|
|
||||||
buf, err := b.next(2)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return binary.LittleEndian.Uint16(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getReadBytes returns read bytes
|
|
||||||
func (b *byteInputAdapter) getReadBytes() int64 {
|
|
||||||
return int64(b.readBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// skipBytes skips exactly n bytes
|
|
||||||
func (b *byteInputAdapter) skipBytes(n int) error {
|
|
||||||
_, err := b.next(n)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset resets the given buffer with a new stream
|
|
||||||
func (b *byteInputAdapter) reset(stream io.Reader) {
|
|
||||||
b.r = stream
|
|
||||||
b.readBytes = 0
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ require (
|
||||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae
|
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae
|
||||||
github.com/philhofer/fwd v1.0.0 // indirect
|
github.com/philhofer/fwd v1.0.0 // indirect
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/tinylib/msgp v1.1.0
|
|
||||||
github.com/willf/bitset v1.1.10
|
github.com/willf/bitset v1.1.10
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect
|
golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect
|
||||||
|
|
|
@ -20,8 +20,6 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=
|
|
||||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
|
||||||
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
||||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ByteInput typed interface around io.Reader or raw bytes
|
||||||
|
type ByteInput interface {
|
||||||
|
// Next returns a slice containing the next n bytes from the buffer,
|
||||||
|
// advancing the buffer as if the bytes had been returned by Read.
|
||||||
|
Next(n int) ([]byte, error)
|
||||||
|
// ReadUInt32 reads uint32 with LittleEndian order
|
||||||
|
ReadUInt32() (uint32, error)
|
||||||
|
// ReadUInt16 reads uint16 with LittleEndian order
|
||||||
|
ReadUInt16() (uint16, error)
|
||||||
|
// GetReadBytes returns read bytes
|
||||||
|
GetReadBytes() int64
|
||||||
|
// SkipBytes skips exactly n bytes
|
||||||
|
SkipBytes(n int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewByteInputFromReader creates reader wrapper
|
||||||
|
func NewByteInputFromReader(reader io.Reader) ByteInput {
|
||||||
|
return &ByteInputAdapter{
|
||||||
|
r: reader,
|
||||||
|
readBytes: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewByteInput creates raw bytes wrapper
|
||||||
|
func NewByteInput(buf []byte) ByteInput {
|
||||||
|
return &ByteBuffer{
|
||||||
|
buf: buf,
|
||||||
|
off: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByteBuffer raw bytes wrapper
|
||||||
|
type ByteBuffer struct {
|
||||||
|
buf []byte
|
||||||
|
off int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next returns a slice containing the next n bytes from the reader
|
||||||
|
// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned
|
||||||
|
func (b *ByteBuffer) Next(n int) ([]byte, error) {
|
||||||
|
m := len(b.buf) - b.off
|
||||||
|
|
||||||
|
if n > m {
|
||||||
|
return nil, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
|
||||||
|
data := b.buf[b.off : b.off+n]
|
||||||
|
b.off += n
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadUInt32 reads uint32 with LittleEndian order
|
||||||
|
func (b *ByteBuffer) ReadUInt32() (uint32, error) {
|
||||||
|
if len(b.buf)-b.off < 4 {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
|
||||||
|
v := binary.LittleEndian.Uint32(b.buf[b.off:])
|
||||||
|
b.off += 4
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadUInt16 reads uint16 with LittleEndian order
|
||||||
|
func (b *ByteBuffer) ReadUInt16() (uint16, error) {
|
||||||
|
if len(b.buf)-b.off < 2 {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
|
||||||
|
v := binary.LittleEndian.Uint16(b.buf[b.off:])
|
||||||
|
b.off += 2
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReadBytes returns read bytes
|
||||||
|
func (b *ByteBuffer) GetReadBytes() int64 {
|
||||||
|
return int64(b.off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkipBytes skips exactly n bytes
|
||||||
|
func (b *ByteBuffer) SkipBytes(n int) error {
|
||||||
|
m := len(b.buf) - b.off
|
||||||
|
|
||||||
|
if n > m {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
|
||||||
|
b.off += n
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the given buffer with a new byte slice
|
||||||
|
func (b *ByteBuffer) Reset(buf []byte) {
|
||||||
|
b.buf = buf
|
||||||
|
b.off = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByteInputAdapter reader wrapper
|
||||||
|
type ByteInputAdapter struct {
|
||||||
|
r io.Reader
|
||||||
|
readBytes int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next returns a slice containing the next n bytes from the buffer,
|
||||||
|
// advancing the buffer as if the bytes had been returned by Read.
|
||||||
|
func (b *ByteInputAdapter) Next(n int) ([]byte, error) {
|
||||||
|
buf := make([]byte, n)
|
||||||
|
m, err := io.ReadAtLeast(b.r, buf, n)
|
||||||
|
b.readBytes += m
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadUInt32 reads uint32 with LittleEndian order
|
||||||
|
func (b *ByteInputAdapter) ReadUInt32() (uint32, error) {
|
||||||
|
buf, err := b.Next(4)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return binary.LittleEndian.Uint32(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadUInt16 reads uint16 with LittleEndian order
|
||||||
|
func (b *ByteInputAdapter) ReadUInt16() (uint16, error) {
|
||||||
|
buf, err := b.Next(2)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return binary.LittleEndian.Uint16(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReadBytes returns read bytes
|
||||||
|
func (b *ByteInputAdapter) GetReadBytes() int64 {
|
||||||
|
return int64(b.readBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkipBytes skips exactly n bytes
|
||||||
|
func (b *ByteInputAdapter) SkipBytes(n int) error {
|
||||||
|
_, err := b.Next(n)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the given buffer with a new stream
|
||||||
|
func (b *ByteInputAdapter) Reset(stream io.Reader) {
|
||||||
|
b.r = stream
|
||||||
|
b.readBytes = 0
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ByteInputAdapterPool shared pool
|
||||||
|
ByteInputAdapterPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &ByteInputAdapter{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByteBufferPool shared pool
|
||||||
|
ByteBufferPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &ByteBuffer{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
|
@ -166,7 +166,6 @@ func appenderRoutine(bitmapChan chan<- *Bitmap, resultChan <-chan keyedContainer
|
||||||
make([]container, 0, expectedKeys),
|
make([]container, 0, expectedKeys),
|
||||||
make([]bool, 0, expectedKeys),
|
make([]bool, 0, expectedKeys),
|
||||||
false,
|
false,
|
||||||
nil,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range keys {
|
for i := range keys {
|
||||||
|
|
|
@ -11,7 +11,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
|
"github.com/RoaringBitmap/roaring/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bitmap represents a compressed bitmap where you can add integers.
|
// Bitmap represents a compressed bitmap where you can add integers.
|
||||||
|
@ -52,27 +53,19 @@ func (rb *Bitmap) ToBytes() ([]byte, error) {
|
||||||
return rb.highlowcontainer.toBytes()
|
return rb.highlowcontainer.toBytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: WriteToMsgpack writes a msgpack2/snappy-streaming compressed serialized
|
|
||||||
// version of this bitmap to stream. The format is not
|
|
||||||
// compatible with the WriteTo() format, and is
|
|
||||||
// experimental: it may produce smaller on disk
|
|
||||||
// footprint and/or be faster to read, depending
|
|
||||||
// on your content. Currently only the Go roaring
|
|
||||||
// implementation supports this format.
|
|
||||||
func (rb *Bitmap) WriteToMsgpack(stream io.Writer) (int64, error) {
|
|
||||||
return 0, rb.highlowcontainer.writeToMsgpack(stream)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFrom reads a serialized version of this bitmap from stream.
|
// ReadFrom reads a serialized version of this bitmap from stream.
|
||||||
// The format is compatible with other RoaringBitmap
|
// The format is compatible with other RoaringBitmap
|
||||||
// implementations (Java, C) and is documented here:
|
// implementations (Java, C) and is documented here:
|
||||||
// https://github.com/RoaringBitmap/RoaringFormatSpec
|
// https://github.com/RoaringBitmap/RoaringFormatSpec
|
||||||
func (rb *Bitmap) ReadFrom(reader io.Reader) (p int64, err error) {
|
// Since io.Reader is regarded as a stream and cannot be read twice.
|
||||||
stream := byteInputAdapterPool.Get().(*byteInputAdapter)
|
// So add cookieHeader to accept the 4-byte data that has been read in roaring64.ReadFrom.
|
||||||
stream.reset(reader)
|
// It is not necessary to pass cookieHeader when call roaring.ReadFrom to read the roaring32 data directly.
|
||||||
|
func (rb *Bitmap) ReadFrom(reader io.Reader, cookieHeader ...byte) (p int64, err error) {
|
||||||
|
stream := internal.ByteInputAdapterPool.Get().(*internal.ByteInputAdapter)
|
||||||
|
stream.Reset(reader)
|
||||||
|
|
||||||
p, err = rb.highlowcontainer.readFrom(stream)
|
p, err = rb.highlowcontainer.readFrom(stream, cookieHeader...)
|
||||||
byteInputAdapterPool.Put(stream)
|
internal.ByteInputAdapterPool.Put(stream)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -100,29 +93,15 @@ func (rb *Bitmap) ReadFrom(reader io.Reader) (p int64, err error) {
|
||||||
// call CloneCopyOnWriteContainers on all such bitmaps.
|
// call CloneCopyOnWriteContainers on all such bitmaps.
|
||||||
//
|
//
|
||||||
func (rb *Bitmap) FromBuffer(buf []byte) (p int64, err error) {
|
func (rb *Bitmap) FromBuffer(buf []byte) (p int64, err error) {
|
||||||
stream := byteBufferPool.Get().(*byteBuffer)
|
stream := internal.ByteBufferPool.Get().(*internal.ByteBuffer)
|
||||||
stream.reset(buf)
|
stream.Reset(buf)
|
||||||
|
|
||||||
p, err = rb.highlowcontainer.readFrom(stream)
|
p, err = rb.highlowcontainer.readFrom(stream)
|
||||||
byteBufferPool.Put(stream)
|
internal.ByteBufferPool.Put(stream)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
byteBufferPool = sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return &byteBuffer{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
byteInputAdapterPool = sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return &byteInputAdapter{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// RunOptimize attempts to further compress the runs of consecutive values found in the bitmap
|
// RunOptimize attempts to further compress the runs of consecutive values found in the bitmap
|
||||||
func (rb *Bitmap) RunOptimize() {
|
func (rb *Bitmap) RunOptimize() {
|
||||||
rb.highlowcontainer.runOptimize()
|
rb.highlowcontainer.runOptimize()
|
||||||
|
@ -133,14 +112,6 @@ func (rb *Bitmap) HasRunCompression() bool {
|
||||||
return rb.highlowcontainer.hasRunCompression()
|
return rb.highlowcontainer.hasRunCompression()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: ReadFromMsgpack reads a msgpack2/snappy-streaming serialized
|
|
||||||
// version of this bitmap from stream. The format is
|
|
||||||
// expected is that written by the WriteToMsgpack()
|
|
||||||
// call; see additional notes there.
|
|
||||||
func (rb *Bitmap) ReadFromMsgpack(stream io.Reader) (int64, error) {
|
|
||||||
return 0, rb.highlowcontainer.readFromMsgpack(stream)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary implements the encoding.BinaryMarshaler interface for the bitmap
|
// MarshalBinary implements the encoding.BinaryMarshaler interface for the bitmap
|
||||||
// (same as ToBytes)
|
// (same as ToBytes)
|
||||||
func (rb *Bitmap) MarshalBinary() ([]byte, error) {
|
func (rb *Bitmap) MarshalBinary() ([]byte, error) {
|
||||||
|
|
|
@ -5,13 +5,9 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"github.com/RoaringBitmap/roaring/internal"
|
||||||
snappy "github.com/glycerine/go-unsnap-stream"
|
|
||||||
"github.com/tinylib/msgp/msgp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate msgp -unexported
|
|
||||||
|
|
||||||
type container interface {
|
type container interface {
|
||||||
addOffset(uint16) []container
|
addOffset(uint16) []container
|
||||||
|
|
||||||
|
@ -103,18 +99,6 @@ type roaringArray struct {
|
||||||
containers []container `msg:"-"` // don't try to serialize directly.
|
containers []container `msg:"-"` // don't try to serialize directly.
|
||||||
needCopyOnWrite []bool
|
needCopyOnWrite []bool
|
||||||
copyOnWrite bool
|
copyOnWrite bool
|
||||||
|
|
||||||
// conserz is used at serialization time
|
|
||||||
// to serialize containers. Otherwise empty.
|
|
||||||
conserz []containerSerz
|
|
||||||
}
|
|
||||||
|
|
||||||
// containerSerz facilitates serializing container (tricky to
|
|
||||||
// serialize because it is an interface) by providing a
|
|
||||||
// light wrapper with a type identifier.
|
|
||||||
type containerSerz struct {
|
|
||||||
t contype `msg:"t"` // type
|
|
||||||
r msgp.Raw `msg:"r"` // Raw msgpack of the actual container type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRoaringArray() *roaringArray {
|
func newRoaringArray() *roaringArray {
|
||||||
|
@ -246,7 +230,6 @@ func (ra *roaringArray) resize(newsize int) {
|
||||||
func (ra *roaringArray) clear() {
|
func (ra *roaringArray) clear() {
|
||||||
ra.resize(0)
|
ra.resize(0)
|
||||||
ra.copyOnWrite = false
|
ra.copyOnWrite = false
|
||||||
ra.conserz = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ra *roaringArray) clone() *roaringArray {
|
func (ra *roaringArray) clone() *roaringArray {
|
||||||
|
@ -566,11 +549,19 @@ func (ra *roaringArray) toBytes() ([]byte, error) {
|
||||||
return buf.Bytes(), err
|
return buf.Bytes(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
func (ra *roaringArray) readFrom(stream internal.ByteInput, cookieHeader ...byte) (int64, error) {
|
||||||
cookie, err := stream.readUInt32()
|
var cookie uint32
|
||||||
|
var err error
|
||||||
if err != nil {
|
if len(cookieHeader) > 0 && len(cookieHeader) != 4 {
|
||||||
return stream.getReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err)
|
return int64(len(cookieHeader)), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: incorrect size of cookie header")
|
||||||
|
}
|
||||||
|
if len(cookieHeader) == 4 {
|
||||||
|
cookie = binary.LittleEndian.Uint32(cookieHeader)
|
||||||
|
} else {
|
||||||
|
cookie, err = stream.ReadUInt32()
|
||||||
|
if err != nil {
|
||||||
|
return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var size uint32
|
var size uint32
|
||||||
|
@ -580,37 +571,36 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
||||||
size = uint32(uint16(cookie>>16) + 1)
|
size = uint32(uint16(cookie>>16) + 1)
|
||||||
// create is-run-container bitmap
|
// create is-run-container bitmap
|
||||||
isRunBitmapSize := (int(size) + 7) / 8
|
isRunBitmapSize := (int(size) + 7) / 8
|
||||||
isRunBitmap, err = stream.next(isRunBitmapSize)
|
isRunBitmap, err = stream.Next(isRunBitmapSize)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err)
|
||||||
}
|
}
|
||||||
} else if cookie == serialCookieNoRunContainer {
|
} else if cookie == serialCookieNoRunContainer {
|
||||||
size, err = stream.readUInt32()
|
size, err = stream.ReadUInt32()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return stream.getReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header")
|
return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header")
|
||||||
}
|
}
|
||||||
|
|
||||||
if size > (1 << 16) {
|
if size > (1 << 16) {
|
||||||
return stream.getReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers")
|
return stream.GetReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers")
|
||||||
}
|
}
|
||||||
|
|
||||||
// descriptive header
|
// descriptive header
|
||||||
buf, err := stream.next(2 * 2 * int(size))
|
buf, err := stream.Next(2 * 2 * int(size))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
keycard := byteSliceAsUint16Slice(buf)
|
keycard := byteSliceAsUint16Slice(buf)
|
||||||
|
|
||||||
if isRunBitmap == nil || size >= noOffsetThreshold {
|
if isRunBitmap == nil || size >= noOffsetThreshold {
|
||||||
if err := stream.skipBytes(int(size) * 4); err != nil {
|
if err := stream.SkipBytes(int(size) * 4); err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("failed to skip bytes: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("failed to skip bytes: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,16 +631,16 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
||||||
|
|
||||||
if isRunBitmap != nil && isRunBitmap[i/8]&(1<<(i%8)) != 0 {
|
if isRunBitmap != nil && isRunBitmap[i/8]&(1<<(i%8)) != 0 {
|
||||||
// run container
|
// run container
|
||||||
nr, err := stream.readUInt16()
|
nr, err := stream.ReadUInt16()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to read runtime container size: %s", err)
|
return 0, fmt.Errorf("failed to read runtime container size: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := stream.next(int(nr) * 4)
|
buf, err := stream.Next(int(nr) * 4)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := runContainer16{
|
nb := runContainer16{
|
||||||
|
@ -661,10 +651,10 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
||||||
ra.containers[i] = &nb
|
ra.containers[i] = &nb
|
||||||
} else if card > arrayDefaultMaxSize {
|
} else if card > arrayDefaultMaxSize {
|
||||||
// bitmap container
|
// bitmap container
|
||||||
buf, err := stream.next(arrayDefaultMaxSize * 2)
|
buf, err := stream.Next(arrayDefaultMaxSize * 2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := bitmapContainer{
|
nb := bitmapContainer{
|
||||||
|
@ -675,10 +665,10 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
||||||
ra.containers[i] = &nb
|
ra.containers[i] = &nb
|
||||||
} else {
|
} else {
|
||||||
// array container
|
// array container
|
||||||
buf, err := stream.next(card * 2)
|
buf, err := stream.Next(card * 2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stream.getReadBytes(), fmt.Errorf("failed to read array container: %s", err)
|
return stream.GetReadBytes(), fmt.Errorf("failed to read array container: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := arrayContainer{
|
nb := arrayContainer{
|
||||||
|
@ -689,7 +679,7 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream.getReadBytes(), nil
|
return stream.GetReadBytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ra *roaringArray) hasRunCompression() bool {
|
func (ra *roaringArray) hasRunCompression() bool {
|
||||||
|
@ -702,84 +692,6 @@ func (ra *roaringArray) hasRunCompression() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ra *roaringArray) writeToMsgpack(stream io.Writer) error {
|
|
||||||
|
|
||||||
ra.conserz = make([]containerSerz, len(ra.containers))
|
|
||||||
for i, v := range ra.containers {
|
|
||||||
switch cn := v.(type) {
|
|
||||||
case *bitmapContainer:
|
|
||||||
bts, err := cn.MarshalMsg(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ra.conserz[i].t = bitmapContype
|
|
||||||
ra.conserz[i].r = bts
|
|
||||||
case *arrayContainer:
|
|
||||||
bts, err := cn.MarshalMsg(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ra.conserz[i].t = arrayContype
|
|
||||||
ra.conserz[i].r = bts
|
|
||||||
case *runContainer16:
|
|
||||||
bts, err := cn.MarshalMsg(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ra.conserz[i].t = run16Contype
|
|
||||||
ra.conserz[i].r = bts
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("Unrecognized container implementation: %T", cn))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w := snappy.NewWriter(stream)
|
|
||||||
err := msgp.Encode(w, ra)
|
|
||||||
ra.conserz = nil
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ra *roaringArray) readFromMsgpack(stream io.Reader) error {
|
|
||||||
r := snappy.NewReader(stream)
|
|
||||||
err := msgp.Decode(r, ra)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ra.containers) != len(ra.keys) {
|
|
||||||
ra.containers = make([]container, len(ra.keys))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range ra.conserz {
|
|
||||||
switch v.t {
|
|
||||||
case bitmapContype:
|
|
||||||
c := &bitmapContainer{}
|
|
||||||
_, err = c.UnmarshalMsg(v.r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ra.containers[i] = c
|
|
||||||
case arrayContype:
|
|
||||||
c := &arrayContainer{}
|
|
||||||
_, err = c.UnmarshalMsg(v.r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ra.containers[i] = c
|
|
||||||
case run16Contype:
|
|
||||||
c := &runContainer16{}
|
|
||||||
_, err = c.UnmarshalMsg(v.r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ra.containers[i] = c
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unrecognized contype serialization code: '%v'", v.t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ra.conserz = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ra *roaringArray) advanceUntil(min uint16, pos int) int {
|
func (ra *roaringArray) advanceUntil(min uint16, pos int) int {
|
||||||
lower := pos + 1
|
lower := pos + 1
|
||||||
|
|
||||||
|
|
|
@ -1,529 +0,0 @@
|
||||||
package roaring
|
|
||||||
|
|
||||||
// NOTE: THIS FILE WAS PRODUCED BY THE
|
|
||||||
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
|
|
||||||
// DO NOT EDIT
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/tinylib/msgp/msgp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *containerSerz) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zxvk uint32
|
|
||||||
zxvk, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zxvk > 0 {
|
|
||||||
zxvk--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "t":
|
|
||||||
{
|
|
||||||
var zbzg uint8
|
|
||||||
zbzg, err = dc.ReadUint8()
|
|
||||||
z.t = contype(zbzg)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "r":
|
|
||||||
err = z.r.DecodeMsg(dc)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
|
||||||
func (z *containerSerz) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
// map header, size 2
|
|
||||||
// write "t"
|
|
||||||
err = en.Append(0x82, 0xa1, 0x74)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteUint8(uint8(z.t))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// write "r"
|
|
||||||
err = en.Append(0xa1, 0x72)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = z.r.EncodeMsg(en)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z *containerSerz) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
// map header, size 2
|
|
||||||
// string "t"
|
|
||||||
o = append(o, 0x82, 0xa1, 0x74)
|
|
||||||
o = msgp.AppendUint8(o, uint8(z.t))
|
|
||||||
// string "r"
|
|
||||||
o = append(o, 0xa1, 0x72)
|
|
||||||
o, err = z.r.MarshalMsg(o)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *containerSerz) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zbai uint32
|
|
||||||
zbai, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zbai > 0 {
|
|
||||||
zbai--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "t":
|
|
||||||
{
|
|
||||||
var zcmr uint8
|
|
||||||
zcmr, bts, err = msgp.ReadUint8Bytes(bts)
|
|
||||||
z.t = contype(zcmr)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "r":
|
|
||||||
bts, err = z.r.UnmarshalMsg(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z *containerSerz) Msgsize() (s int) {
|
|
||||||
s = 1 + 2 + msgp.Uint8Size + 2 + z.r.Msgsize()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *contype) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
{
|
|
||||||
var zajw uint8
|
|
||||||
zajw, err = dc.ReadUint8()
|
|
||||||
(*z) = contype(zajw)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
|
||||||
func (z contype) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
err = en.WriteUint8(uint8(z))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z contype) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
o = msgp.AppendUint8(o, uint8(z))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *contype) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
{
|
|
||||||
var zwht uint8
|
|
||||||
zwht, bts, err = msgp.ReadUint8Bytes(bts)
|
|
||||||
(*z) = contype(zwht)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z contype) Msgsize() (s int) {
|
|
||||||
s = msgp.Uint8Size
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *roaringArray) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zlqf uint32
|
|
||||||
zlqf, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zlqf > 0 {
|
|
||||||
zlqf--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "keys":
|
|
||||||
var zdaf uint32
|
|
||||||
zdaf, err = dc.ReadArrayHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.keys) >= int(zdaf) {
|
|
||||||
z.keys = (z.keys)[:zdaf]
|
|
||||||
} else {
|
|
||||||
z.keys = make([]uint16, zdaf)
|
|
||||||
}
|
|
||||||
for zhct := range z.keys {
|
|
||||||
z.keys[zhct], err = dc.ReadUint16()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "needCopyOnWrite":
|
|
||||||
var zpks uint32
|
|
||||||
zpks, err = dc.ReadArrayHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.needCopyOnWrite) >= int(zpks) {
|
|
||||||
z.needCopyOnWrite = (z.needCopyOnWrite)[:zpks]
|
|
||||||
} else {
|
|
||||||
z.needCopyOnWrite = make([]bool, zpks)
|
|
||||||
}
|
|
||||||
for zcua := range z.needCopyOnWrite {
|
|
||||||
z.needCopyOnWrite[zcua], err = dc.ReadBool()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "copyOnWrite":
|
|
||||||
z.copyOnWrite, err = dc.ReadBool()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "conserz":
|
|
||||||
var zjfb uint32
|
|
||||||
zjfb, err = dc.ReadArrayHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.conserz) >= int(zjfb) {
|
|
||||||
z.conserz = (z.conserz)[:zjfb]
|
|
||||||
} else {
|
|
||||||
z.conserz = make([]containerSerz, zjfb)
|
|
||||||
}
|
|
||||||
for zxhx := range z.conserz {
|
|
||||||
var zcxo uint32
|
|
||||||
zcxo, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zcxo > 0 {
|
|
||||||
zcxo--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "t":
|
|
||||||
{
|
|
||||||
var zeff uint8
|
|
||||||
zeff, err = dc.ReadUint8()
|
|
||||||
z.conserz[zxhx].t = contype(zeff)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "r":
|
|
||||||
err = z.conserz[zxhx].r.DecodeMsg(dc)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
|
||||||
func (z *roaringArray) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
// map header, size 4
|
|
||||||
// write "keys"
|
|
||||||
err = en.Append(0x84, 0xa4, 0x6b, 0x65, 0x79, 0x73)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteArrayHeader(uint32(len(z.keys)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zhct := range z.keys {
|
|
||||||
err = en.WriteUint16(z.keys[zhct])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// write "needCopyOnWrite"
|
|
||||||
err = en.Append(0xaf, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteArrayHeader(uint32(len(z.needCopyOnWrite)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zcua := range z.needCopyOnWrite {
|
|
||||||
err = en.WriteBool(z.needCopyOnWrite[zcua])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// write "copyOnWrite"
|
|
||||||
err = en.Append(0xab, 0x63, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteBool(z.copyOnWrite)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// write "conserz"
|
|
||||||
err = en.Append(0xa7, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x7a)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteArrayHeader(uint32(len(z.conserz)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zxhx := range z.conserz {
|
|
||||||
// map header, size 2
|
|
||||||
// write "t"
|
|
||||||
err = en.Append(0x82, 0xa1, 0x74)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = en.WriteUint8(uint8(z.conserz[zxhx].t))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// write "r"
|
|
||||||
err = en.Append(0xa1, 0x72)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = z.conserz[zxhx].r.EncodeMsg(en)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z *roaringArray) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
// map header, size 4
|
|
||||||
// string "keys"
|
|
||||||
o = append(o, 0x84, 0xa4, 0x6b, 0x65, 0x79, 0x73)
|
|
||||||
o = msgp.AppendArrayHeader(o, uint32(len(z.keys)))
|
|
||||||
for zhct := range z.keys {
|
|
||||||
o = msgp.AppendUint16(o, z.keys[zhct])
|
|
||||||
}
|
|
||||||
// string "needCopyOnWrite"
|
|
||||||
o = append(o, 0xaf, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
|
||||||
o = msgp.AppendArrayHeader(o, uint32(len(z.needCopyOnWrite)))
|
|
||||||
for zcua := range z.needCopyOnWrite {
|
|
||||||
o = msgp.AppendBool(o, z.needCopyOnWrite[zcua])
|
|
||||||
}
|
|
||||||
// string "copyOnWrite"
|
|
||||||
o = append(o, 0xab, 0x63, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
|
||||||
o = msgp.AppendBool(o, z.copyOnWrite)
|
|
||||||
// string "conserz"
|
|
||||||
o = append(o, 0xa7, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x7a)
|
|
||||||
o = msgp.AppendArrayHeader(o, uint32(len(z.conserz)))
|
|
||||||
for zxhx := range z.conserz {
|
|
||||||
// map header, size 2
|
|
||||||
// string "t"
|
|
||||||
o = append(o, 0x82, 0xa1, 0x74)
|
|
||||||
o = msgp.AppendUint8(o, uint8(z.conserz[zxhx].t))
|
|
||||||
// string "r"
|
|
||||||
o = append(o, 0xa1, 0x72)
|
|
||||||
o, err = z.conserz[zxhx].r.MarshalMsg(o)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *roaringArray) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zrsw uint32
|
|
||||||
zrsw, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zrsw > 0 {
|
|
||||||
zrsw--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "keys":
|
|
||||||
var zxpk uint32
|
|
||||||
zxpk, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.keys) >= int(zxpk) {
|
|
||||||
z.keys = (z.keys)[:zxpk]
|
|
||||||
} else {
|
|
||||||
z.keys = make([]uint16, zxpk)
|
|
||||||
}
|
|
||||||
for zhct := range z.keys {
|
|
||||||
z.keys[zhct], bts, err = msgp.ReadUint16Bytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "needCopyOnWrite":
|
|
||||||
var zdnj uint32
|
|
||||||
zdnj, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.needCopyOnWrite) >= int(zdnj) {
|
|
||||||
z.needCopyOnWrite = (z.needCopyOnWrite)[:zdnj]
|
|
||||||
} else {
|
|
||||||
z.needCopyOnWrite = make([]bool, zdnj)
|
|
||||||
}
|
|
||||||
for zcua := range z.needCopyOnWrite {
|
|
||||||
z.needCopyOnWrite[zcua], bts, err = msgp.ReadBoolBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "copyOnWrite":
|
|
||||||
z.copyOnWrite, bts, err = msgp.ReadBoolBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "conserz":
|
|
||||||
var zobc uint32
|
|
||||||
zobc, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(z.conserz) >= int(zobc) {
|
|
||||||
z.conserz = (z.conserz)[:zobc]
|
|
||||||
} else {
|
|
||||||
z.conserz = make([]containerSerz, zobc)
|
|
||||||
}
|
|
||||||
for zxhx := range z.conserz {
|
|
||||||
var zsnv uint32
|
|
||||||
zsnv, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zsnv > 0 {
|
|
||||||
zsnv--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
case "t":
|
|
||||||
{
|
|
||||||
var zkgt uint8
|
|
||||||
zkgt, bts, err = msgp.ReadUint8Bytes(bts)
|
|
||||||
z.conserz[zxhx].t = contype(zkgt)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "r":
|
|
||||||
bts, err = z.conserz[zxhx].r.UnmarshalMsg(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z *roaringArray) Msgsize() (s int) {
|
|
||||||
s = 1 + 5 + msgp.ArrayHeaderSize + (len(z.keys) * (msgp.Uint16Size)) + 16 + msgp.ArrayHeaderSize + (len(z.needCopyOnWrite) * (msgp.BoolSize)) + 12 + msgp.BoolSize + 8 + msgp.ArrayHeaderSize
|
|
||||||
for zxhx := range z.conserz {
|
|
||||||
s += 1 + 2 + msgp.Uint8Size + 2 + z.conserz[zxhx].r.Msgsize()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -44,16 +44,11 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate msgp -unexported
|
|
||||||
|
|
||||||
// runContainer16 does run-length encoding of sets of
|
// runContainer16 does run-length encoding of sets of
|
||||||
// uint16 integers.
|
// uint16 integers.
|
||||||
type runContainer16 struct {
|
type runContainer16 struct {
|
||||||
iv []interval16
|
iv []interval16
|
||||||
card int64
|
card int64
|
||||||
|
|
||||||
// avoid allocation during search
|
|
||||||
myOpts searchOptions `msg:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// interval16 is the internal to runContainer16
|
// interval16 is the internal to runContainer16
|
||||||
|
@ -120,8 +115,6 @@ func (p uint16Slice) Less(i, j int) bool { return p[i] < p[j] }
|
||||||
// Swap swaps elements i and j.
|
// Swap swaps elements i and j.
|
||||||
func (p uint16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
func (p uint16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||||
|
|
||||||
//msgp:ignore addHelper
|
|
||||||
|
|
||||||
// addHelper helps build a runContainer16.
|
// addHelper helps build a runContainer16.
|
||||||
type addHelper16 struct {
|
type addHelper16 struct {
|
||||||
runstart uint16
|
runstart uint16
|
||||||
|
@ -617,10 +610,7 @@ func (rc *runContainer16) unionCardinality(b *runContainer16) uint64 {
|
||||||
|
|
||||||
// indexOfIntervalAtOrAfter is a helper for union.
|
// indexOfIntervalAtOrAfter is a helper for union.
|
||||||
func (rc *runContainer16) indexOfIntervalAtOrAfter(key int64, startIndex int64) int64 {
|
func (rc *runContainer16) indexOfIntervalAtOrAfter(key int64, startIndex int64) int64 {
|
||||||
rc.myOpts.startIndex = startIndex
|
w, already, _ := rc.searchRange(key, startIndex, 0)
|
||||||
rc.myOpts.endxIndex = 0
|
|
||||||
|
|
||||||
w, already, _ := rc.search(key, &rc.myOpts)
|
|
||||||
if already {
|
if already {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
@ -844,7 +834,7 @@ toploop:
|
||||||
|
|
||||||
// get returns true iff key is in the container.
|
// get returns true iff key is in the container.
|
||||||
func (rc *runContainer16) contains(key uint16) bool {
|
func (rc *runContainer16) contains(key uint16) bool {
|
||||||
_, in, _ := rc.search(int64(key), nil)
|
_, in, _ := rc.search(int64(key))
|
||||||
return in
|
return in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,22 +843,7 @@ func (rc *runContainer16) numIntervals() int {
|
||||||
return len(rc.iv)
|
return len(rc.iv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// searchOptions allows us to accelerate search with
|
// searchRange returns alreadyPresent to indicate if the
|
||||||
// prior knowledge of (mostly lower) bounds. This is used by Union
|
|
||||||
// and Intersect.
|
|
||||||
type searchOptions struct {
|
|
||||||
// start here instead of at 0
|
|
||||||
startIndex int64
|
|
||||||
|
|
||||||
// upper bound instead of len(rc.iv);
|
|
||||||
// endxIndex == 0 means ignore the bound and use
|
|
||||||
// endxIndex == n ==len(rc.iv) which is also
|
|
||||||
// naturally the default for search()
|
|
||||||
// when opt = nil.
|
|
||||||
endxIndex int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// search returns alreadyPresent to indicate if the
|
|
||||||
// key is already in one of our interval16s.
|
// key is already in one of our interval16s.
|
||||||
//
|
//
|
||||||
// If key is alreadyPresent, then whichInterval16 tells
|
// If key is alreadyPresent, then whichInterval16 tells
|
||||||
|
@ -892,24 +867,16 @@ type searchOptions struct {
|
||||||
//
|
//
|
||||||
// runContainer16.search always returns whichInterval16 < len(rc.iv).
|
// runContainer16.search always returns whichInterval16 < len(rc.iv).
|
||||||
//
|
//
|
||||||
// If not nil, opts can be used to further restrict
|
// The search space is from startIndex to endxIndex. If endxIndex is set to zero, then there
|
||||||
// the search space.
|
// no upper bound.
|
||||||
//
|
//
|
||||||
func (rc *runContainer16) search(key int64, opts *searchOptions) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
|
func (rc *runContainer16) searchRange(key int64, startIndex int64, endxIndex int64) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
|
||||||
n := int64(len(rc.iv))
|
n := int64(len(rc.iv))
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return -1, false, 0
|
return -1, false, 0
|
||||||
}
|
}
|
||||||
|
if endxIndex == 0 {
|
||||||
startIndex := int64(0)
|
endxIndex = n
|
||||||
endxIndex := n
|
|
||||||
if opts != nil {
|
|
||||||
startIndex = opts.startIndex
|
|
||||||
|
|
||||||
// let endxIndex == 0 mean no effect
|
|
||||||
if opts.endxIndex > 0 {
|
|
||||||
endxIndex = opts.endxIndex
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort.Search returns the smallest index i
|
// sort.Search returns the smallest index i
|
||||||
|
@ -979,6 +946,34 @@ func (rc *runContainer16) search(key int64, opts *searchOptions) (whichInterval1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// search returns alreadyPresent to indicate if the
|
||||||
|
// key is already in one of our interval16s.
|
||||||
|
//
|
||||||
|
// If key is alreadyPresent, then whichInterval16 tells
|
||||||
|
// you where.
|
||||||
|
//
|
||||||
|
// If key is not already present, then whichInterval16 is
|
||||||
|
// set as follows:
|
||||||
|
//
|
||||||
|
// a) whichInterval16 == len(rc.iv)-1 if key is beyond our
|
||||||
|
// last interval16 in rc.iv;
|
||||||
|
//
|
||||||
|
// b) whichInterval16 == -1 if key is before our first
|
||||||
|
// interval16 in rc.iv;
|
||||||
|
//
|
||||||
|
// c) whichInterval16 is set to the minimum index of rc.iv
|
||||||
|
// which comes strictly before the key;
|
||||||
|
// so rc.iv[whichInterval16].last < key,
|
||||||
|
// and if whichInterval16+1 exists, then key < rc.iv[whichInterval16+1].start
|
||||||
|
// (Note that whichInterval16+1 won't exist when
|
||||||
|
// whichInterval16 is the last interval.)
|
||||||
|
//
|
||||||
|
// runContainer16.search always returns whichInterval16 < len(rc.iv).
|
||||||
|
//
|
||||||
|
func (rc *runContainer16) search(key int64) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
|
||||||
|
return rc.searchRange(key, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// cardinality returns the count of the integers stored in the
|
// cardinality returns the count of the integers stored in the
|
||||||
// runContainer16.
|
// runContainer16.
|
||||||
func (rc *runContainer16) cardinality() int64 {
|
func (rc *runContainer16) cardinality() int64 {
|
||||||
|
@ -1072,7 +1067,7 @@ func (rc *runContainer16) Add(k uint16) (wasNew bool) {
|
||||||
|
|
||||||
k64 := int64(k)
|
k64 := int64(k)
|
||||||
|
|
||||||
index, present, _ := rc.search(k64, nil)
|
index, present, _ := rc.search(k64)
|
||||||
if present {
|
if present {
|
||||||
return // already there
|
return // already there
|
||||||
}
|
}
|
||||||
|
@ -1147,8 +1142,6 @@ func (rc *runContainer16) Add(k uint16) (wasNew bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//msgp:ignore runIterator
|
|
||||||
|
|
||||||
// runIterator16 advice: you must call hasNext()
|
// runIterator16 advice: you must call hasNext()
|
||||||
// before calling next()/peekNext() to insure there are contents.
|
// before calling next()/peekNext() to insure there are contents.
|
||||||
type runIterator16 struct {
|
type runIterator16 struct {
|
||||||
|
@ -1207,13 +1200,8 @@ func (ri *runIterator16) advanceIfNeeded(minval uint16) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := &searchOptions{
|
|
||||||
startIndex: ri.curIndex,
|
|
||||||
endxIndex: int64(len(ri.rc.iv)),
|
|
||||||
}
|
|
||||||
|
|
||||||
// interval cannot be -1 because of minval > peekNext
|
// interval cannot be -1 because of minval > peekNext
|
||||||
interval, isPresent, _ := ri.rc.search(int64(minval), opt)
|
interval, isPresent, _ := ri.rc.searchRange(int64(minval), ri.curIndex, int64(len(ri.rc.iv)))
|
||||||
|
|
||||||
// if the minval is present, set the curPosIndex at the right position
|
// if the minval is present, set the curPosIndex at the right position
|
||||||
if isPresent {
|
if isPresent {
|
||||||
|
@ -1366,7 +1354,7 @@ func (ri *runIterator16) nextMany64(hs uint64, buf []uint64) int {
|
||||||
func (rc *runContainer16) removeKey(key uint16) (wasPresent bool) {
|
func (rc *runContainer16) removeKey(key uint16) (wasPresent bool) {
|
||||||
|
|
||||||
var index int64
|
var index int64
|
||||||
index, wasPresent, _ = rc.search(int64(key), nil)
|
index, wasPresent, _ = rc.search(int64(key))
|
||||||
if !wasPresent {
|
if !wasPresent {
|
||||||
return // already removed, nothing to do.
|
return // already removed, nothing to do.
|
||||||
}
|
}
|
||||||
|
@ -1457,12 +1445,8 @@ func intersectWithLeftover16(astart, alast, bstart, blast int64) (isOverlap, isL
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *runContainer16) findNextIntervalThatIntersectsStartingFrom(startIndex int64, key int64) (index int64, done bool) {
|
func (rc *runContainer16) findNextIntervalThatIntersectsStartingFrom(startIndex int64, key int64) (index int64, done bool) {
|
||||||
|
w, _, _ := rc.searchRange(key, startIndex, 0)
|
||||||
rc.myOpts.startIndex = startIndex
|
|
||||||
rc.myOpts.endxIndex = 0
|
|
||||||
|
|
||||||
w, _, _ := rc.search(key, &rc.myOpts)
|
|
||||||
// rc.search always returns w < len(rc.iv)
|
// rc.search always returns w < len(rc.iv)
|
||||||
if w < startIndex {
|
if w < startIndex {
|
||||||
// not found and comes before lower bound startIndex,
|
// not found and comes before lower bound startIndex,
|
||||||
|
@ -1603,8 +1587,8 @@ func (rc *runContainer16) isubtract(del interval16) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// INVAR there is some intersection between rc and del
|
// INVAR there is some intersection between rc and del
|
||||||
istart, startAlready, _ := rc.search(int64(del.start), nil)
|
istart, startAlready, _ := rc.search(int64(del.start))
|
||||||
ilast, lastAlready, _ := rc.search(int64(del.last()), nil)
|
ilast, lastAlready, _ := rc.search(int64(del.last()))
|
||||||
rc.card = -1
|
rc.card = -1
|
||||||
if istart == -1 {
|
if istart == -1 {
|
||||||
if ilast == n-1 && !lastAlready {
|
if ilast == n-1 && !lastAlready {
|
||||||
|
@ -2356,7 +2340,7 @@ func (rc *runContainer16) getCardinality() int {
|
||||||
func (rc *runContainer16) rank(x uint16) int {
|
func (rc *runContainer16) rank(x uint16) int {
|
||||||
n := int64(len(rc.iv))
|
n := int64(len(rc.iv))
|
||||||
xx := int64(x)
|
xx := int64(x)
|
||||||
w, already, _ := rc.search(xx, nil)
|
w, already, _ := rc.search(xx)
|
||||||
if w < 0 {
|
if w < 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,8 +3,6 @@ package roaring
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/tinylib/msgp/msgp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// writeTo for runContainer16 follows this
|
// writeTo for runContainer16 follows this
|
||||||
|
@ -19,16 +17,3 @@ func (b *runContainer16) writeTo(stream io.Writer) (int, error) {
|
||||||
}
|
}
|
||||||
return stream.Write(buf)
|
return stream.Write(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *runContainer16) writeToMsgpack(stream io.Writer) (int, error) {
|
|
||||||
bts, err := b.MarshalMsg(nil)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return stream.Write(bts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *runContainer16) readFromMsgpack(stream io.Reader) (int, error) {
|
|
||||||
err := msgp.Decode(stream, b)
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
|
@ -177,6 +177,7 @@ func IsPrintableASCII(str string) bool
|
||||||
func IsRFC3339(str string) bool
|
func IsRFC3339(str string) bool
|
||||||
func IsRFC3339WithoutZone(str string) bool
|
func IsRFC3339WithoutZone(str string) bool
|
||||||
func IsRGBcolor(str string) bool
|
func IsRGBcolor(str string) bool
|
||||||
|
func IsRegex(str string) bool
|
||||||
func IsRequestURI(rawurl string) bool
|
func IsRequestURI(rawurl string) bool
|
||||||
func IsRequestURL(rawurl string) bool
|
func IsRequestURL(rawurl string) bool
|
||||||
func IsRipeMD128(str string) bool
|
func IsRipeMD128(str string) bool
|
||||||
|
@ -203,6 +204,7 @@ func IsUUID(str string) bool
|
||||||
func IsUUIDv3(str string) bool
|
func IsUUIDv3(str string) bool
|
||||||
func IsUUIDv4(str string) bool
|
func IsUUIDv4(str string) bool
|
||||||
func IsUUIDv5(str string) bool
|
func IsUUIDv5(str string) bool
|
||||||
|
func IsULID(str string) bool
|
||||||
func IsUnixTime(str string) bool
|
func IsUnixTime(str string) bool
|
||||||
func IsUpperCase(str string) bool
|
func IsUpperCase(str string) bool
|
||||||
func IsVariableWidth(str string) bool
|
func IsVariableWidth(str string) bool
|
||||||
|
@ -382,6 +384,7 @@ Here is a list of available validators for struct fields (validator - used funct
|
||||||
"rfc3339WithoutZone": IsRFC3339WithoutZone,
|
"rfc3339WithoutZone": IsRFC3339WithoutZone,
|
||||||
"ISO3166Alpha2": IsISO3166Alpha2,
|
"ISO3166Alpha2": IsISO3166Alpha2,
|
||||||
"ISO3166Alpha3": IsISO3166Alpha3,
|
"ISO3166Alpha3": IsISO3166Alpha3,
|
||||||
|
"ulid": IsULID,
|
||||||
```
|
```
|
||||||
Validators with parameters
|
Validators with parameters
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ const (
|
||||||
SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
|
SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
|
||||||
WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
|
WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
|
||||||
UnixPath string = `^(/[^/\x00]*)+/?$`
|
UnixPath string = `^(/[^/\x00]*)+/?$`
|
||||||
|
WinARPath string = `^(?:(?:[a-zA-Z]:|\\\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\\?[^\\/:*?"<>|\r\n]+\\?)(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
|
||||||
|
UnixARPath string = `^((\.{0,2}/)?([^/\x00]*))+/?$`
|
||||||
Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
|
Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
|
||||||
tagName string = "valid"
|
tagName string = "valid"
|
||||||
hasLowerCase string = ".*[[:lower:]]"
|
hasLowerCase string = ".*[[:lower:]]"
|
||||||
|
@ -50,6 +52,7 @@ const (
|
||||||
hasWhitespaceOnly string = "^[[:space:]]+$"
|
hasWhitespaceOnly string = "^[[:space:]]+$"
|
||||||
IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$"
|
IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$"
|
||||||
IMSI string = "^\\d{14,15}$"
|
IMSI string = "^\\d{14,15}$"
|
||||||
|
E164 string = `^\+?[1-9]\d{1,14}$`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Used by IsFilePath func
|
// Used by IsFilePath func
|
||||||
|
@ -97,6 +100,8 @@ var (
|
||||||
rxSSN = regexp.MustCompile(SSN)
|
rxSSN = regexp.MustCompile(SSN)
|
||||||
rxWinPath = regexp.MustCompile(WinPath)
|
rxWinPath = regexp.MustCompile(WinPath)
|
||||||
rxUnixPath = regexp.MustCompile(UnixPath)
|
rxUnixPath = regexp.MustCompile(UnixPath)
|
||||||
|
rxARWinPath = regexp.MustCompile(WinARPath)
|
||||||
|
rxARUnixPath = regexp.MustCompile(UnixARPath)
|
||||||
rxSemver = regexp.MustCompile(Semver)
|
rxSemver = regexp.MustCompile(Semver)
|
||||||
rxHasLowerCase = regexp.MustCompile(hasLowerCase)
|
rxHasLowerCase = regexp.MustCompile(hasLowerCase)
|
||||||
rxHasUpperCase = regexp.MustCompile(hasUpperCase)
|
rxHasUpperCase = regexp.MustCompile(hasUpperCase)
|
||||||
|
@ -104,4 +109,5 @@ var (
|
||||||
rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly)
|
rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly)
|
||||||
rxIMEI = regexp.MustCompile(IMEI)
|
rxIMEI = regexp.MustCompile(IMEI)
|
||||||
rxIMSI = regexp.MustCompile(IMSI)
|
rxIMSI = regexp.MustCompile(IMSI)
|
||||||
|
rxE164 = regexp.MustCompile(E164)
|
||||||
)
|
)
|
||||||
|
|
|
@ -165,6 +165,7 @@ var TagMap = map[string]Validator{
|
||||||
"ISO3166Alpha3": IsISO3166Alpha3,
|
"ISO3166Alpha3": IsISO3166Alpha3,
|
||||||
"ISO4217": IsISO4217,
|
"ISO4217": IsISO4217,
|
||||||
"IMEI": IsIMEI,
|
"IMEI": IsIMEI,
|
||||||
|
"ulid": IsULID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ISO3166Entry stores country codes
|
// ISO3166Entry stores country codes
|
||||||
|
|
|
@ -361,9 +361,96 @@ func IsUUID(str string) bool {
|
||||||
return rxUUID.MatchString(str)
|
return rxUUID.MatchString(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Byte to index table for O(1) lookups when unmarshaling.
|
||||||
|
// We use 0xFF as sentinel value for invalid indexes.
|
||||||
|
var ulidDec = [...]byte{
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||||
|
0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
|
||||||
|
0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
|
||||||
|
0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
|
||||||
|
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
|
||||||
|
0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
|
||||||
|
0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodedSize is the length of a text encoded ULID.
|
||||||
|
const ulidEncodedSize = 26
|
||||||
|
|
||||||
|
// IsULID checks if the string is a ULID.
|
||||||
|
//
|
||||||
|
// Implementation got from:
|
||||||
|
// https://github.com/oklog/ulid (Apache-2.0 License)
|
||||||
|
//
|
||||||
|
func IsULID(str string) bool {
|
||||||
|
// Check if a base32 encoded ULID is the right length.
|
||||||
|
if len(str) != ulidEncodedSize {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all the characters in a base32 encoded ULID are part of the
|
||||||
|
// expected base32 character set.
|
||||||
|
if ulidDec[str[0]] == 0xFF ||
|
||||||
|
ulidDec[str[1]] == 0xFF ||
|
||||||
|
ulidDec[str[2]] == 0xFF ||
|
||||||
|
ulidDec[str[3]] == 0xFF ||
|
||||||
|
ulidDec[str[4]] == 0xFF ||
|
||||||
|
ulidDec[str[5]] == 0xFF ||
|
||||||
|
ulidDec[str[6]] == 0xFF ||
|
||||||
|
ulidDec[str[7]] == 0xFF ||
|
||||||
|
ulidDec[str[8]] == 0xFF ||
|
||||||
|
ulidDec[str[9]] == 0xFF ||
|
||||||
|
ulidDec[str[10]] == 0xFF ||
|
||||||
|
ulidDec[str[11]] == 0xFF ||
|
||||||
|
ulidDec[str[12]] == 0xFF ||
|
||||||
|
ulidDec[str[13]] == 0xFF ||
|
||||||
|
ulidDec[str[14]] == 0xFF ||
|
||||||
|
ulidDec[str[15]] == 0xFF ||
|
||||||
|
ulidDec[str[16]] == 0xFF ||
|
||||||
|
ulidDec[str[17]] == 0xFF ||
|
||||||
|
ulidDec[str[18]] == 0xFF ||
|
||||||
|
ulidDec[str[19]] == 0xFF ||
|
||||||
|
ulidDec[str[20]] == 0xFF ||
|
||||||
|
ulidDec[str[21]] == 0xFF ||
|
||||||
|
ulidDec[str[22]] == 0xFF ||
|
||||||
|
ulidDec[str[23]] == 0xFF ||
|
||||||
|
ulidDec[str[24]] == 0xFF ||
|
||||||
|
ulidDec[str[25]] == 0xFF {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the first character in a base32 encoded ULID will overflow. This
|
||||||
|
// happens because the base32 representation encodes 130 bits, while the
|
||||||
|
// ULID is only 128 bits.
|
||||||
|
//
|
||||||
|
// See https://github.com/oklog/ulid/issues/9 for details.
|
||||||
|
if str[0] > '7' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// IsCreditCard checks if the string is a credit card.
|
// IsCreditCard checks if the string is a credit card.
|
||||||
func IsCreditCard(str string) bool {
|
func IsCreditCard(str string) bool {
|
||||||
sanitized := notNumberRegexp.ReplaceAllString(str, "")
|
sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "")
|
||||||
if !rxCreditCard.MatchString(sanitized) {
|
if !rxCreditCard.MatchString(sanitized) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -509,6 +596,27 @@ func IsFilePath(str string) (bool, int) {
|
||||||
return false, Unknown
|
return false, Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//IsWinFilePath checks both relative & absolute paths in Windows
|
||||||
|
func IsWinFilePath(str string) bool {
|
||||||
|
if rxARWinPath.MatchString(str) {
|
||||||
|
//check windows path limit see:
|
||||||
|
// http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
|
||||||
|
if len(str[3:]) > 32767 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//IsUnixFilePath checks both relative & absolute paths in Unix
|
||||||
|
func IsUnixFilePath(str string) bool {
|
||||||
|
if rxARUnixPath.MatchString(str) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// IsDataURI checks if a string is base64 encoded data URI such as an image
|
// IsDataURI checks if a string is base64 encoded data URI such as an image
|
||||||
func IsDataURI(str string) bool {
|
func IsDataURI(str string) bool {
|
||||||
dataURI := strings.Split(str, ",")
|
dataURI := strings.Split(str, ",")
|
||||||
|
@ -586,11 +694,13 @@ func IsHash(str string, algorithm string) bool {
|
||||||
len = "40"
|
len = "40"
|
||||||
} else if algo == "tiger192" {
|
} else if algo == "tiger192" {
|
||||||
len = "48"
|
len = "48"
|
||||||
} else if algo == "sha256" {
|
} else if algo == "sha3-224" {
|
||||||
|
len = "56"
|
||||||
|
} else if algo == "sha256" || algo == "sha3-256" {
|
||||||
len = "64"
|
len = "64"
|
||||||
} else if algo == "sha384" {
|
} else if algo == "sha384" || algo == "sha3-384" {
|
||||||
len = "96"
|
len = "96"
|
||||||
} else if algo == "sha512" {
|
} else if algo == "sha512" || algo == "sha3-512" {
|
||||||
len = "128"
|
len = "128"
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
@ -599,6 +709,26 @@ func IsHash(str string, algorithm string) bool {
|
||||||
return Matches(str, "^[a-f0-9]{"+len+"}$")
|
return Matches(str, "^[a-f0-9]{"+len+"}$")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSHA3224 checks is a string is a SHA3-224 hash. Alias for `IsHash(str, "sha3-224")`
|
||||||
|
func IsSHA3224(str string) bool {
|
||||||
|
return IsHash(str, "sha3-224")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSHA3256 checks is a string is a SHA3-256 hash. Alias for `IsHash(str, "sha3-256")`
|
||||||
|
func IsSHA3256(str string) bool {
|
||||||
|
return IsHash(str, "sha3-256")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSHA3384 checks is a string is a SHA3-384 hash. Alias for `IsHash(str, "sha3-384")`
|
||||||
|
func IsSHA3384(str string) bool {
|
||||||
|
return IsHash(str, "sha3-384")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSHA3512 checks is a string is a SHA3-512 hash. Alias for `IsHash(str, "sha3-512")`
|
||||||
|
func IsSHA3512(str string) bool {
|
||||||
|
return IsHash(str, "sha3-512")
|
||||||
|
}
|
||||||
|
|
||||||
// IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")`
|
// IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")`
|
||||||
func IsSHA512(str string) bool {
|
func IsSHA512(str string) bool {
|
||||||
return IsHash(str, "sha512")
|
return IsHash(str, "sha512")
|
||||||
|
@ -819,6 +949,14 @@ func IsRsaPublicKey(str string, keylen int) bool {
|
||||||
return bitlen == int(keylen)
|
return bitlen == int(keylen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsRegex checks if a give string is a valid regex with RE2 syntax or not
|
||||||
|
func IsRegex(str string) bool {
|
||||||
|
if _, err := regexp.Compile(str); err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func toJSONName(tag string) string {
|
func toJSONName(tag string) string {
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
return ""
|
return ""
|
||||||
|
@ -1625,3 +1763,7 @@ func (sv stringValues) Len() int { return len(sv) }
|
||||||
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
|
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
|
||||||
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
|
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
|
||||||
func (sv stringValues) get(i int) string { return sv[i].String() }
|
func (sv stringValues) get(i int) string { return sv[i].String() }
|
||||||
|
|
||||||
|
func IsE164(str string) bool {
|
||||||
|
return rxE164.MatchString(str)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
*.test
|
||||||
|
*.out
|
||||||
|
.devcontainer/
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Salvador Cavadini
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,52 @@
|
||||||
|
# garif
|
||||||
|
|
||||||
|
A GO package to create and manipulate SARIF logs.
|
||||||
|
|
||||||
|
SARIF, from _Static Analysis Results Interchange Format_, is a standard JSON-based format for the output of static analysis tools defined and promoted by [OASIS](https://www.oasis-open.org/).
|
||||||
|
|
||||||
|
Current supported version of the standard is [SARIF-v2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html
|
||||||
|
).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The package provides access to every element of the SARIF model, therefore you are free to manipulate it at every detail.
|
||||||
|
|
||||||
|
The package also provides constructors functions (`New...`) and decorators methods (`With...`) that simplify the creation of SARIF files for common use cases.
|
||||||
|
|
||||||
|
Using these constructors and decorators we can easily create the example SARIF file of the [Microsoft SARIF pages](https://github.com/microsoft/sarif-tutorials/blob/master/docs/1-Introduction.md)
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
import to `github.com/chavacava/garif`
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
rule := garif.NewRule("no-unused-vars").
|
||||||
|
WithHelpUri("https://eslint.org/docs/rules/no-unused-vars").
|
||||||
|
WithShortDescription("disallow unused variables").
|
||||||
|
WithProperties("category", "Variables")
|
||||||
|
|
||||||
|
driver := garif.NewDriver("ESLint").
|
||||||
|
WithInformationUri("https://eslint.org").
|
||||||
|
WithRules(rule)
|
||||||
|
|
||||||
|
run := garif.NewRun(NewTool(driver)).
|
||||||
|
WithArtifactsURIs("file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js")
|
||||||
|
|
||||||
|
run.WithResult(rule.Id, "'x' is assigned a value but never used.", "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js", 1, 5)
|
||||||
|
|
||||||
|
logFile := garif.NewLogFile([]*Run{run}, Version210)
|
||||||
|
|
||||||
|
logFile.Write(os.Stdout)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why this package?
|
||||||
|
This package was initiated during my works on adding to [`revive`](https://github.com/mgechev/revive) a SARIF output formatter.
|
||||||
|
I've tried to use [go-sarif](https://github.com/owenrumney/go-sarif) by [Owen Rumney](https://github.com/owenrumney) but it is too focused in the use case of the static analyzer [tfsec](https://tfsec.dev) so I've decided to create a package flexible enough to generate SARIF files in broader cases.
|
||||||
|
|
||||||
|
## More information about SARIF
|
||||||
|
For more information about SARIF, you can visit the [Oasis Open](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif) site.
|
||||||
|
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
Of course, contributions are welcome!
|
|
@ -0,0 +1,338 @@
|
||||||
|
package garif
|
||||||
|
|
||||||
|
// NewAddress creates a valid Address
|
||||||
|
func NewAddress() *Address {
|
||||||
|
return &Address{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewArtifact creates a valid Artifact
|
||||||
|
func NewArtifact() *Artifact {
|
||||||
|
return &Artifact{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewArtifactChange creates a valid ArtifactChange
|
||||||
|
func NewArtifactChange(location *ArtifactLocation, replacements ...*Replacement) *ArtifactChange {
|
||||||
|
return &ArtifactChange{
|
||||||
|
ArtifactLocation: location,
|
||||||
|
Replacements: replacements,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewArtifactContent creates a valid ArtifactContent
|
||||||
|
func NewArtifactContent() *ArtifactContent {
|
||||||
|
return &ArtifactContent{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewArtifactLocation creates a valid ArtifactLocation
|
||||||
|
func NewArtifactLocation() *ArtifactLocation {
|
||||||
|
return &ArtifactLocation{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAttachment creates a valid Attachment
|
||||||
|
func NewAttachment(location *ArtifactLocation) *Attachment {
|
||||||
|
return &Attachment{ArtifactLocation: location}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCodeFlow creates a valid CodeFlow
|
||||||
|
func NewCodeFlow(threadFlows ...*ThreadFlow) *CodeFlow {
|
||||||
|
return &CodeFlow{ThreadFlows: threadFlows}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConfigurationOverride creates a valid ConfigurationOverride
|
||||||
|
func NewConfigurationOverride(configuration *ReportingConfiguration, descriptor *ReportingDescriptorReference) *ConfigurationOverride {
|
||||||
|
return &ConfigurationOverride{
|
||||||
|
Configuration: configuration,
|
||||||
|
Descriptor: descriptor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConversion creates a valid Conversion
|
||||||
|
func NewConversion(tool *Tool) *Conversion {
|
||||||
|
return &Conversion{Tool: tool}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEdge creates a valid Edge
|
||||||
|
func NewEdge(id, sourceNodeId, targetNodeId string) *Edge {
|
||||||
|
return &Edge{
|
||||||
|
Id: id,
|
||||||
|
SourceNodeId: sourceNodeId,
|
||||||
|
TargetNodeId: targetNodeId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEdgeTraversal creates a valid EdgeTraversal
|
||||||
|
func NewEdgeTraversal(edgeId string) *EdgeTraversal {
|
||||||
|
return &EdgeTraversal{
|
||||||
|
EdgeId: edgeId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewException creates a valid Exception
|
||||||
|
func NewException() *Exception {
|
||||||
|
return &Exception{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewExternalProperties creates a valid ExternalProperties
|
||||||
|
func NewExternalProperties() *ExternalProperties {
|
||||||
|
return &ExternalProperties{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewExternalPropertyFileReference creates a valid ExternalPropertyFileReference
|
||||||
|
func NewExternalPropertyFileReference() *ExternalPropertyFileReference {
|
||||||
|
return &ExternalPropertyFileReference{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewExternalPropertyFileReferences creates a valid ExternalPropertyFileReferences
|
||||||
|
func NewExternalPropertyFileReferences() *ExternalPropertyFileReferences {
|
||||||
|
return &ExternalPropertyFileReferences{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFix creates a valid Fix
|
||||||
|
func NewFix(artifactChanges ...*ArtifactChange) *Fix {
|
||||||
|
return &Fix{
|
||||||
|
ArtifactChanges: artifactChanges,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGraph creates a valid Graph
|
||||||
|
func NewGraph() *Graph {
|
||||||
|
return &Graph{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGraphTraversal creates a valid GraphTraversal
|
||||||
|
func NewGraphTraversal() *GraphTraversal {
|
||||||
|
return &GraphTraversal{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInvocation creates a valid Invocation
|
||||||
|
func NewInvocation(executionSuccessful bool) *Invocation {
|
||||||
|
return &Invocation{
|
||||||
|
ExecutionSuccessful: executionSuccessful,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLocation creates a valid Location
|
||||||
|
func NewLocation() *Location {
|
||||||
|
return &Location{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLocationRelationship creates a valid LocationRelationship
|
||||||
|
func NewLocationRelationship(target int) *LocationRelationship {
|
||||||
|
return &LocationRelationship{
|
||||||
|
Target: target,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type LogFileVersion string
|
||||||
|
|
||||||
|
const Version210 LogFileVersion = "2.1.0"
|
||||||
|
|
||||||
|
// NewLogFile creates a valid LogFile
|
||||||
|
func NewLogFile(runs []*Run, version LogFileVersion) *LogFile {
|
||||||
|
return &LogFile{
|
||||||
|
Runs: runs,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLogicalLocation creates a valid LogicalLocation
|
||||||
|
func NewLogicalLocation() *LogicalLocation {
|
||||||
|
return &LogicalLocation{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessage creates a valid Message
|
||||||
|
func NewMessage() *Message {
|
||||||
|
return &Message{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessageFromText creates a valid Message with the given text
|
||||||
|
func NewMessageFromText(text string) *Message {
|
||||||
|
return &Message{
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMultiformatMessageString creates a valid MultiformatMessageString
|
||||||
|
func NewMultiformatMessageString(text string) *MultiformatMessageString {
|
||||||
|
return &MultiformatMessageString{
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNode creates a valid Node
|
||||||
|
func NewNode(id string) *Node {
|
||||||
|
return &Node{
|
||||||
|
Id: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotification creates a valid Notification
|
||||||
|
func NewNotification(message *Message) *Notification {
|
||||||
|
return &Notification{
|
||||||
|
Message: message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPhysicalLocation creates a valid PhysicalLocation
|
||||||
|
func NewPhysicalLocation() *PhysicalLocation {
|
||||||
|
return &PhysicalLocation{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPropertyBag creates a valid PropertyBag
|
||||||
|
func NewPropertyBag() *PropertyBag {
|
||||||
|
return &PropertyBag{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRectangle creates a valid Rectangle
|
||||||
|
func NewRectangle() *Rectangle {
|
||||||
|
return &Rectangle{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRegion creates a valid Region
|
||||||
|
func NewRegion() *Region {
|
||||||
|
return &Region{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReplacement creates a valid Replacement
|
||||||
|
func NewReplacement(deletedRegion *Region) *Replacement {
|
||||||
|
return &Replacement{
|
||||||
|
DeletedRegion: deletedRegion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReportingConfiguration creates a valid ReportingConfiguration
|
||||||
|
func NewReportingConfiguration() *ReportingConfiguration {
|
||||||
|
return &ReportingConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReportingDescriptor creates a valid ReportingDescriptor
|
||||||
|
func NewReportingDescriptor(id string) *ReportingDescriptor {
|
||||||
|
return &ReportingDescriptor{
|
||||||
|
Id: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRule is an alias for NewReportingDescriptor
|
||||||
|
func NewRule(id string) *ReportingDescriptor {
|
||||||
|
return NewReportingDescriptor(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReportingDescriptorReference creates a valid ReportingDescriptorReference
|
||||||
|
func NewReportingDescriptorReference() *ReportingDescriptorReference {
|
||||||
|
return &ReportingDescriptorReference{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReportingDescriptorRelationship creates a valid ReportingDescriptorRelationship
|
||||||
|
func NewReportingDescriptorRelationship(target *ReportingDescriptorReference) *ReportingDescriptorRelationship {
|
||||||
|
return &ReportingDescriptorRelationship{
|
||||||
|
Target: target,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResult creates a valid Result
|
||||||
|
func NewResult(message *Message) *Result {
|
||||||
|
return &Result{
|
||||||
|
Message: message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResultProvenance creates a valid ResultProvenance
|
||||||
|
func NewResultProvenance() *ResultProvenance {
|
||||||
|
return &ResultProvenance{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRun creates a valid Run
|
||||||
|
func NewRun(tool *Tool) *Run {
|
||||||
|
return &Run{
|
||||||
|
Tool: tool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRunAutomationDetails creates a valid RunAutomationDetails
|
||||||
|
func NewRunAutomationDetails() *RunAutomationDetails {
|
||||||
|
return &RunAutomationDetails{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a valid
|
||||||
|
func NewSpecialLocations() *SpecialLocations {
|
||||||
|
return &SpecialLocations{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStack creates a valid Stack
|
||||||
|
func NewStack(frames ...*StackFrame) *Stack {
|
||||||
|
return &Stack{
|
||||||
|
Frames: frames,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStackFrame creates a valid StackFrame
|
||||||
|
func NewStackFrame() *StackFrame {
|
||||||
|
return &StackFrame{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSuppression creates a valid Suppression
|
||||||
|
func NewSuppression(kind string) *Suppression {
|
||||||
|
return &Suppression{
|
||||||
|
Kind: kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewThreadFlow creates a valid ThreadFlow
|
||||||
|
func NewThreadFlow(locations []*ThreadFlowLocation) *ThreadFlow {
|
||||||
|
return &ThreadFlow{
|
||||||
|
Locations: locations,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewThreadFlowLocation creates a valid ThreadFlowLocation
|
||||||
|
func NewThreadFlowLocation() *ThreadFlowLocation {
|
||||||
|
return &ThreadFlowLocation{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTool creates a valid Tool
|
||||||
|
func NewTool(driver *ToolComponent) *Tool {
|
||||||
|
return &Tool{
|
||||||
|
Driver: driver,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewToolComponent creates a valid ToolComponent
|
||||||
|
func NewToolComponent(name string) *ToolComponent {
|
||||||
|
return &ToolComponent{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDriver is an alias for NewToolComponent
|
||||||
|
func NewDriver(name string) *ToolComponent {
|
||||||
|
return NewToolComponent(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewToolComponentReference creates a valid ToolComponentReference
|
||||||
|
func NewToolComponentReference() *ToolComponentReference {
|
||||||
|
return &ToolComponentReference{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTranslationMetadata creates a valid TranslationMetadata
|
||||||
|
func NewTranslationMetadata(name string) *TranslationMetadata {
|
||||||
|
return &TranslationMetadata{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVersionControlDetails creates a valid VersionControlDetails
|
||||||
|
func NewVersionControlDetails(repositoryUri string) *VersionControlDetails {
|
||||||
|
return &VersionControlDetails{
|
||||||
|
RepositoryUri: repositoryUri,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebRequest creates a valid WebRequest
|
||||||
|
func NewWebRequest() *WebRequest {
|
||||||
|
return &WebRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebResponse creates a valid WebResponse
|
||||||
|
func NewWebResponse() *WebResponse {
|
||||||
|
return &WebResponse{}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package garif
|
||||||
|
|
||||||
|
// WithLineColumn sets a physical location with the given line and column
|
||||||
|
func (l *Location) WithLineColumn(line, column int) *Location {
|
||||||
|
if l.PhysicalLocation == nil {
|
||||||
|
l.PhysicalLocation = NewPhysicalLocation()
|
||||||
|
}
|
||||||
|
|
||||||
|
l.PhysicalLocation.Region = NewRegion()
|
||||||
|
l.PhysicalLocation.Region.StartLine = line
|
||||||
|
l.PhysicalLocation.Region.StartColumn = column
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithURI sets a physical location with the given URI
|
||||||
|
func (l *Location) WithURI(uri string) *Location {
|
||||||
|
if l.PhysicalLocation == nil {
|
||||||
|
l.PhysicalLocation = NewPhysicalLocation()
|
||||||
|
}
|
||||||
|
|
||||||
|
l.PhysicalLocation.ArtifactLocation = NewArtifactLocation()
|
||||||
|
l.PhysicalLocation.ArtifactLocation.Uri = uri
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithKeyValue sets (overwrites) the value of the given key
|
||||||
|
func (b PropertyBag) WithKeyValue(key string, value interface{}) PropertyBag {
|
||||||
|
b[key] = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithHelpUri sets the help URI for this ReportingDescriptor
|
||||||
|
func (r *ReportingDescriptor) WithHelpUri(uri string) *ReportingDescriptor {
|
||||||
|
r.HelpUri = uri
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProperties adds the key & value to the properties of this ReportingDescriptor
|
||||||
|
func (r *ReportingDescriptor) WithProperties(key string, value interface{}) *ReportingDescriptor {
|
||||||
|
if r.Properties == nil {
|
||||||
|
r.Properties = NewPropertyBag()
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Properties.WithKeyValue(key, value)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithArtifactsURIs adds the given URI as artifacts of this Run
|
||||||
|
func (r *Run) WithArtifactsURIs(uris ...string) *Run {
|
||||||
|
if r.Artifacts == nil {
|
||||||
|
r.Artifacts = []*Artifact{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, uri := range uris {
|
||||||
|
a := NewArtifact()
|
||||||
|
a.Location = NewArtifactLocation()
|
||||||
|
a.Location.Uri = uri
|
||||||
|
r.Artifacts = append(r.Artifacts, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithResult adds a result to this Run
|
||||||
|
func (r *Run) WithResult(ruleId string, message string, uri string, line int, column int) *Run {
|
||||||
|
if r.Results == nil {
|
||||||
|
r.Results = []*Result{}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := NewMessage()
|
||||||
|
msg.Text = message
|
||||||
|
result := NewResult(msg)
|
||||||
|
location := NewLocation().WithURI(uri).WithLineColumn(line, column)
|
||||||
|
|
||||||
|
result.Locations = append(result.Locations, location)
|
||||||
|
result.RuleId = ruleId
|
||||||
|
r.Results = append(r.Results, result)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithInformationUri sets the information URI
|
||||||
|
func (t *ToolComponent) WithInformationUri(uri string) *ToolComponent {
|
||||||
|
t.InformationUri = uri
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRules sets (overwrites) the rules
|
||||||
|
func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent {
|
||||||
|
t.Rules = rules
|
||||||
|
return t
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Package garif defines all the GO structures required to model a SARIF log file.
|
||||||
|
// These structures were created using the JSON-schema sarif-schema-2.1.0.json of SARIF logfiles
|
||||||
|
// available at https://github.com/oasis-tcs/sarif-spec/tree/master/Schemata.
|
||||||
|
//
|
||||||
|
// The package provides constructors for all structures (see constructors.go) These constructors
|
||||||
|
// ensure that the returned structure instantiation is valid with respect to the JSON schema and
|
||||||
|
// should be used in place of plain structure instantiation.
|
||||||
|
// The root structure is LogFile.
|
||||||
|
//
|
||||||
|
// The package provides utility decorators for the most commonly used structures (see decorators.go)
|
||||||
|
package garif
|
|
@ -0,0 +1,5 @@
|
||||||
|
module github.com/chavacava/garif
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.7.0
|
|
@ -0,0 +1,11 @@
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,26 @@
|
||||||
|
package garif
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Write writes the JSON
|
||||||
|
func (l *LogFile) Write(w io.Writer) error {
|
||||||
|
marshal, err := json.Marshal(l)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = w.Write(marshal)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrettyWrite writes indented JSON
|
||||||
|
func (l *LogFile) PrettyWrite(w io.Writer) error {
|
||||||
|
marshal, err := json.MarshalIndent(l, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = w.Write(marshal)
|
||||||
|
return err
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
||||||
|
/.idea
|
||||||
|
/.connstr
|
||||||
|
.vscode
|
||||||
|
.terraform
|
||||||
|
*.tfstate*
|
||||||
|
*.log
|
||||||
|
*.swp
|
||||||
|
*~
|
|
@ -0,0 +1,10 @@
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
# basic go linters
|
||||||
|
- gofmt
|
||||||
|
- golint
|
||||||
|
- govet
|
||||||
|
|
||||||
|
# sql related linters
|
||||||
|
- rowserrcheck
|
||||||
|
- sqlclosecheck
|
|
@ -6,19 +6,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ driver.Connector = &accessTokenConnector{}
|
|
||||||
|
|
||||||
// accessTokenConnector wraps Connector and injects a
|
|
||||||
// fresh access token when connecting to the database
|
|
||||||
type accessTokenConnector struct {
|
|
||||||
Connector
|
|
||||||
|
|
||||||
accessTokenProvider func() (string, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAccessTokenConnector creates a new connector from a DSN and a token provider.
|
// NewAccessTokenConnector creates a new connector from a DSN and a token provider.
|
||||||
// The token provider func will be called when a new connection is requested and should return a valid access token.
|
// The token provider func will be called when a new connection is requested and should return a valid access token.
|
||||||
// The returned connector may be used with sql.OpenDB.
|
// The returned connector may be used with sql.OpenDB.
|
||||||
|
@ -32,20 +21,10 @@ func NewAccessTokenConnector(dsn string, tokenProvider func() (string, error)) (
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &accessTokenConnector{
|
conn.params.fedAuthLibrary = fedAuthLibrarySecurityToken
|
||||||
Connector: *conn,
|
conn.securityTokenProvider = func(ctx context.Context) (string, error) {
|
||||||
accessTokenProvider: tokenProvider,
|
return tokenProvider()
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect returns a new database connection
|
|
||||||
func (c *accessTokenConnector) Connect(ctx context.Context) (driver.Conn, error) {
|
|
||||||
var err error
|
|
||||||
c.Connector.params.fedAuthAccessToken, err = c.accessTokenProvider()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("mssql: error retrieving access token: %+v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Connector.Connect(ctx)
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ environment:
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
GOVERSION: 115
|
GOVERSION: 115
|
||||||
SQLINSTANCE: SQL2017
|
SQLINSTANCE: SQL2017
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
|
GOVERSION: 116
|
||||||
|
SQLINSTANCE: SQL2017
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- set GOROOT=c:\go%GOVERSION%
|
- set GOROOT=c:\go%GOVERSION%
|
||||||
|
|
|
@ -48,8 +48,8 @@ type tdsBuffer struct {
|
||||||
func newTdsBuffer(bufsize uint16, transport io.ReadWriteCloser) *tdsBuffer {
|
func newTdsBuffer(bufsize uint16, transport io.ReadWriteCloser) *tdsBuffer {
|
||||||
return &tdsBuffer{
|
return &tdsBuffer{
|
||||||
packetSize: int(bufsize),
|
packetSize: int(bufsize),
|
||||||
wbuf: make([]byte, 1<<16),
|
wbuf: make([]byte, bufsize),
|
||||||
rbuf: make([]byte, 1<<16),
|
rbuf: make([]byte, bufsize),
|
||||||
rpos: 8,
|
rpos: 8,
|
||||||
transport: transport,
|
transport: transport,
|
||||||
}
|
}
|
||||||
|
@ -137,19 +137,28 @@ func (w *tdsBuffer) FinishPacket() error {
|
||||||
var headerSize = binary.Size(header{})
|
var headerSize = binary.Size(header{})
|
||||||
|
|
||||||
func (r *tdsBuffer) readNextPacket() error {
|
func (r *tdsBuffer) readNextPacket() error {
|
||||||
h := header{}
|
buf := r.rbuf[:headerSize]
|
||||||
var err error
|
_, err := io.ReadFull(r.transport, buf)
|
||||||
err = binary.Read(r.transport, binary.BigEndian, &h)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
h := header{
|
||||||
|
PacketType: packetType(buf[0]),
|
||||||
|
Status: buf[1],
|
||||||
|
Size: binary.BigEndian.Uint16(buf[2:4]),
|
||||||
|
Spid: binary.BigEndian.Uint16(buf[4:6]),
|
||||||
|
PacketNo: buf[6],
|
||||||
|
Pad: buf[7],
|
||||||
|
}
|
||||||
if int(h.Size) > r.packetSize {
|
if int(h.Size) > r.packetSize {
|
||||||
return errors.New("Invalid packet size, it is longer than buffer size")
|
return errors.New("invalid packet size, it is longer than buffer size")
|
||||||
}
|
}
|
||||||
if headerSize > int(h.Size) {
|
if headerSize > int(h.Size) {
|
||||||
return errors.New("Invalid packet size, it is shorter than header size")
|
return errors.New("invalid packet size, it is shorter than header size")
|
||||||
}
|
}
|
||||||
_, err = io.ReadFull(r.transport, r.rbuf[headerSize:h.Size])
|
_, err = io.ReadFull(r.transport, r.rbuf[headerSize:h.Size])
|
||||||
|
//s := base64.StdEncoding.EncodeToString(r.rbuf[headerSize:h.Size])
|
||||||
|
//fmt.Print(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,9 @@ type BulkOptions struct {
|
||||||
type DataValue interface{}
|
type DataValue interface{}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sqlDateFormat = "2006-01-02"
|
sqlDateFormat = "2006-01-02"
|
||||||
sqlTimeFormat = "2006-01-02 15:04:05.999999999Z07:00"
|
sqlDateTimeFormat = "2006-01-02 15:04:05.999999999Z07:00"
|
||||||
|
sqlTimeFormat = "15:04:05.9999999"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cn *Conn) CreateBulk(table string, columns []string) (_ *Bulk) {
|
func (cn *Conn) CreateBulk(table string, columns []string) (_ *Bulk) {
|
||||||
|
@ -86,7 +87,7 @@ func (b *Bulk) sendBulkCommand(ctx context.Context) (err error) {
|
||||||
b.bulkColumns = append(b.bulkColumns, *bulkCol)
|
b.bulkColumns = append(b.bulkColumns, *bulkCol)
|
||||||
b.dlogf("Adding column %s %s %#x", colname, bulkCol.ColName, bulkCol.ti.TypeId)
|
b.dlogf("Adding column %s %s %#x", colname, bulkCol.ColName, bulkCol.ti.TypeId)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Column %s does not exist in destination table %s", colname, b.tablename)
|
return fmt.Errorf("column %s does not exist in destination table %s", colname, b.tablename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +167,7 @@ func (b *Bulk) AddRow(row []interface{}) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(row) != len(b.bulkColumns) {
|
if len(row) != len(b.bulkColumns) {
|
||||||
return fmt.Errorf("Row does not have the same number of columns than the destination table %d %d",
|
return fmt.Errorf("row does not have the same number of columns than the destination table %d %d",
|
||||||
len(row), len(b.bulkColumns))
|
len(row), len(b.bulkColumns))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ func (b *Bulk) makeRowData(row []interface{}) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bulk) Done() (rowcount int64, err error) {
|
func (b *Bulk) Done() (rowcount int64, err error) {
|
||||||
if b.headerSent == false {
|
if !b.headerSent {
|
||||||
//no rows had been sent
|
//no rows had been sent
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
@ -233,24 +234,13 @@ func (b *Bulk) Done() (rowcount int64, err error) {
|
||||||
|
|
||||||
buf.FinishPacket()
|
buf.FinishPacket()
|
||||||
|
|
||||||
tokchan := make(chan tokenStruct, 5)
|
reader := startReading(b.cn.sess, b.ctx, nil)
|
||||||
go processResponse(b.ctx, b.cn.sess, tokchan, nil)
|
err = reader.iterateResponse()
|
||||||
|
if err != nil {
|
||||||
var rowCount int64
|
return 0, b.cn.checkBadConn(err)
|
||||||
for token := range tokchan {
|
|
||||||
switch token := token.(type) {
|
|
||||||
case doneStruct:
|
|
||||||
if token.Status&doneCount != 0 {
|
|
||||||
rowCount = int64(token.RowCount)
|
|
||||||
}
|
|
||||||
if token.isError() {
|
|
||||||
return 0, token.getError()
|
|
||||||
}
|
|
||||||
case error:
|
|
||||||
return 0, b.cn.checkBadConn(token)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rowCount, nil
|
|
||||||
|
return reader.rowCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bulk) createColMetadata() []byte {
|
func (b *Bulk) createColMetadata() []byte {
|
||||||
|
@ -421,7 +411,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
||||||
res.ti.Size = len(res.buffer)
|
res.ti.Size = len(res.buffer)
|
||||||
case string:
|
case string:
|
||||||
var t time.Time
|
var t time.Time
|
||||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
|
||||||
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
||||||
}
|
}
|
||||||
res.buffer = encodeDateTime2(t, int(col.ti.Scale))
|
res.buffer = encodeDateTime2(t, int(col.ti.Scale))
|
||||||
|
@ -437,7 +427,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
||||||
res.ti.Size = len(res.buffer)
|
res.ti.Size = len(res.buffer)
|
||||||
case string:
|
case string:
|
||||||
var t time.Time
|
var t time.Time
|
||||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
|
||||||
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
||||||
}
|
}
|
||||||
res.buffer = encodeDateTimeOffset(t, int(col.ti.Scale))
|
res.buffer = encodeDateTimeOffset(t, int(col.ti.Scale))
|
||||||
|
@ -468,7 +458,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
||||||
case time.Time:
|
case time.Time:
|
||||||
t = val
|
t = val
|
||||||
case string:
|
case string:
|
||||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
|
||||||
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -485,7 +475,22 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("mssql: invalid size of column %d", col.ti.Size)
|
err = fmt.Errorf("mssql: invalid size of column %d", col.ti.Size)
|
||||||
}
|
}
|
||||||
|
case typeTimeN:
|
||||||
|
var t time.Time
|
||||||
|
switch val := val.(type) {
|
||||||
|
case time.Time:
|
||||||
|
res.buffer = encodeTime(val.Hour(), val.Minute(), val.Second(), val.Nanosecond(), int(col.ti.Scale))
|
||||||
|
res.ti.Size = len(res.buffer)
|
||||||
|
case string:
|
||||||
|
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
||||||
|
return res, fmt.Errorf("bulk: unable to convert string to time: %v", err)
|
||||||
|
}
|
||||||
|
res.buffer = encodeTime(t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), int(col.ti.Scale))
|
||||||
|
res.ti.Size = len(res.buffer)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("mssql: invalid type for time column: %T %s", val, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
// case typeMoney, typeMoney4, typeMoneyN:
|
// case typeMoney, typeMoney4, typeMoneyN:
|
||||||
case typeDecimal, typeDecimalN, typeNumeric, typeNumericN:
|
case typeDecimal, typeDecimalN, typeNumeric, typeNumericN:
|
||||||
prec := col.ti.Prec
|
prec := col.ti.Prec
|
||||||
|
|
|
@ -37,11 +37,17 @@ type connectParams struct {
|
||||||
failOverPartner string
|
failOverPartner string
|
||||||
failOverPort uint64
|
failOverPort uint64
|
||||||
packetSize uint16
|
packetSize uint16
|
||||||
fedAuthAccessToken string
|
fedAuthLibrary int
|
||||||
|
fedAuthADALWorkflow byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default packet size for TDS buffer
|
||||||
|
const defaultPacketSize = 4096
|
||||||
|
|
||||||
func parseConnectParams(dsn string) (connectParams, error) {
|
func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
var p connectParams
|
p := connectParams{
|
||||||
|
fedAuthLibrary: fedAuthLibraryReserved,
|
||||||
|
}
|
||||||
|
|
||||||
var params map[string]string
|
var params map[string]string
|
||||||
if strings.HasPrefix(dsn, "odbc:") {
|
if strings.HasPrefix(dsn, "odbc:") {
|
||||||
|
@ -65,7 +71,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
var err error
|
var err error
|
||||||
p.logFlags, err = strconv.ParseUint(strlog, 10, 64)
|
p.logFlags, err = strconv.ParseUint(strlog, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p, fmt.Errorf("Invalid log parameter '%s': %s", strlog, err.Error())
|
return p, fmt.Errorf("invalid log parameter '%s': %s", strlog, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server := params["server"]
|
server := params["server"]
|
||||||
|
@ -87,20 +93,19 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
var err error
|
var err error
|
||||||
p.port, err = strconv.ParseUint(strport, 10, 16)
|
p.port, err = strconv.ParseUint(strport, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid tcp port '%v': %v"
|
f := "invalid tcp port '%v': %v"
|
||||||
return p, fmt.Errorf(f, strport, err.Error())
|
return p, fmt.Errorf(f, strport, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-network-packet-size-server-configuration-option
|
// https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-network-packet-size-server-configuration-option
|
||||||
// Default packet size remains at 4096 bytes
|
p.packetSize = defaultPacketSize
|
||||||
p.packetSize = 4096
|
|
||||||
strpsize, ok := params["packet size"]
|
strpsize, ok := params["packet size"]
|
||||||
if ok {
|
if ok {
|
||||||
var err error
|
var err error
|
||||||
psize, err := strconv.ParseUint(strpsize, 0, 16)
|
psize, err := strconv.ParseUint(strpsize, 0, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid packet size '%v': %v"
|
f := "invalid packet size '%v': %v"
|
||||||
return p, fmt.Errorf(f, strpsize, err.Error())
|
return p, fmt.Errorf(f, strpsize, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +128,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
if strconntimeout, ok := params["connection timeout"]; ok {
|
if strconntimeout, ok := params["connection timeout"]; ok {
|
||||||
timeout, err := strconv.ParseUint(strconntimeout, 10, 64)
|
timeout, err := strconv.ParseUint(strconntimeout, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid connection timeout '%v': %v"
|
f := "invalid connection timeout '%v': %v"
|
||||||
return p, fmt.Errorf(f, strconntimeout, err.Error())
|
return p, fmt.Errorf(f, strconntimeout, err.Error())
|
||||||
}
|
}
|
||||||
p.conn_timeout = time.Duration(timeout) * time.Second
|
p.conn_timeout = time.Duration(timeout) * time.Second
|
||||||
|
@ -132,7 +137,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
if strdialtimeout, ok := params["dial timeout"]; ok {
|
if strdialtimeout, ok := params["dial timeout"]; ok {
|
||||||
timeout, err := strconv.ParseUint(strdialtimeout, 10, 64)
|
timeout, err := strconv.ParseUint(strdialtimeout, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid dial timeout '%v': %v"
|
f := "invalid dial timeout '%v': %v"
|
||||||
return p, fmt.Errorf(f, strdialtimeout, err.Error())
|
return p, fmt.Errorf(f, strdialtimeout, err.Error())
|
||||||
}
|
}
|
||||||
p.dial_timeout = time.Duration(timeout) * time.Second
|
p.dial_timeout = time.Duration(timeout) * time.Second
|
||||||
|
@ -144,7 +149,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
if keepAlive, ok := params["keepalive"]; ok {
|
if keepAlive, ok := params["keepalive"]; ok {
|
||||||
timeout, err := strconv.ParseUint(keepAlive, 10, 64)
|
timeout, err := strconv.ParseUint(keepAlive, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid keepAlive value '%s': %s"
|
f := "invalid keepAlive value '%s': %s"
|
||||||
return p, fmt.Errorf(f, keepAlive, err.Error())
|
return p, fmt.Errorf(f, keepAlive, err.Error())
|
||||||
}
|
}
|
||||||
p.keepAlive = time.Duration(timeout) * time.Second
|
p.keepAlive = time.Duration(timeout) * time.Second
|
||||||
|
@ -157,7 +162,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
var err error
|
var err error
|
||||||
p.encrypt, err = strconv.ParseBool(encrypt)
|
p.encrypt, err = strconv.ParseBool(encrypt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid encrypt '%s': %s"
|
f := "invalid encrypt '%s': %s"
|
||||||
return p, fmt.Errorf(f, encrypt, err.Error())
|
return p, fmt.Errorf(f, encrypt, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +174,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
var err error
|
var err error
|
||||||
p.trustServerCertificate, err = strconv.ParseBool(trust)
|
p.trustServerCertificate, err = strconv.ParseBool(trust)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid trust server certificate '%s': %s"
|
f := "invalid trust server certificate '%s': %s"
|
||||||
return p, fmt.Errorf(f, trust, err.Error())
|
return p, fmt.Errorf(f, trust, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +214,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
if ok {
|
if ok {
|
||||||
if appintent == "ReadOnly" {
|
if appintent == "ReadOnly" {
|
||||||
if p.database == "" {
|
if p.database == "" {
|
||||||
return p, fmt.Errorf("Database must be specified when ApplicationIntent is ReadOnly")
|
return p, fmt.Errorf("database must be specified when ApplicationIntent is ReadOnly")
|
||||||
}
|
}
|
||||||
p.typeFlags |= fReadOnlyIntent
|
p.typeFlags |= fReadOnlyIntent
|
||||||
}
|
}
|
||||||
|
@ -225,7 +230,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
var err error
|
var err error
|
||||||
p.failOverPort, err = strconv.ParseUint(failOverPort, 0, 16)
|
p.failOverPort, err = strconv.ParseUint(failOverPort, 0, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid tcp port '%v': %v"
|
f := "invalid tcp port '%v': %v"
|
||||||
return p, fmt.Errorf(f, failOverPort, err.Error())
|
return p, fmt.Errorf(f, failOverPort, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,6 +238,30 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert connectionParams to url style connection string
|
||||||
|
// used mostly for testing
|
||||||
|
func (p connectParams) toUrl() *url.URL {
|
||||||
|
q := url.Values{}
|
||||||
|
if p.database != "" {
|
||||||
|
q.Add("database", p.database)
|
||||||
|
}
|
||||||
|
if p.logFlags != 0 {
|
||||||
|
q.Add("log", strconv.FormatUint(p.logFlags, 10))
|
||||||
|
}
|
||||||
|
res := url.URL{
|
||||||
|
Scheme: "sqlserver",
|
||||||
|
Host: p.host,
|
||||||
|
User: url.UserPassword(p.user, p.password),
|
||||||
|
}
|
||||||
|
if p.instance != "" {
|
||||||
|
res.Path = p.instance
|
||||||
|
}
|
||||||
|
if len(q) > 0 {
|
||||||
|
res.RawQuery = q.Encode()
|
||||||
|
}
|
||||||
|
return &res
|
||||||
|
}
|
||||||
|
|
||||||
func splitConnectionString(dsn string) (res map[string]string) {
|
func splitConnectionString(dsn string) (res map[string]string) {
|
||||||
res = map[string]string{}
|
res = map[string]string{}
|
||||||
parts := strings.Split(dsn, ";")
|
parts := strings.Split(dsn, ";")
|
||||||
|
@ -340,7 +369,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
||||||
case parserStateBeforeKey:
|
case parserStateBeforeKey:
|
||||||
switch {
|
switch {
|
||||||
case c == '=':
|
case c == '=':
|
||||||
return res, fmt.Errorf("Unexpected character = at index %d. Expected start of key or semi-colon or whitespace.", i)
|
return res, fmt.Errorf("unexpected character = at index %d. Expected start of key or semi-colon or whitespace", i)
|
||||||
case !unicode.IsSpace(c) && c != ';':
|
case !unicode.IsSpace(c) && c != ';':
|
||||||
state = parserStateKey
|
state = parserStateKey
|
||||||
key += string(c)
|
key += string(c)
|
||||||
|
@ -419,7 +448,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
||||||
case unicode.IsSpace(c):
|
case unicode.IsSpace(c):
|
||||||
// Ignore whitespace
|
// Ignore whitespace
|
||||||
default:
|
default:
|
||||||
return res, fmt.Errorf("Unexpected character %c at index %d. Expected semi-colon or whitespace.", c, i)
|
return res, fmt.Errorf("unexpected character %c at index %d. Expected semi-colon or whitespace", c, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
case parserStateEndValue:
|
case parserStateEndValue:
|
||||||
|
@ -429,7 +458,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
||||||
case unicode.IsSpace(c):
|
case unicode.IsSpace(c):
|
||||||
// Ignore whitespace
|
// Ignore whitespace
|
||||||
default:
|
default:
|
||||||
return res, fmt.Errorf("Unexpected character %c at index %d. Expected semi-colon or whitespace.", c, i)
|
return res, fmt.Errorf("unexpected character %c at index %d. Expected semi-colon or whitespace", c, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,7 +473,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
||||||
case parserStateBareValue:
|
case parserStateBareValue:
|
||||||
res[key] = strings.TrimRightFunc(value, unicode.IsSpace)
|
res[key] = strings.TrimRightFunc(value, unicode.IsSpace)
|
||||||
case parserStateBracedValue:
|
case parserStateBracedValue:
|
||||||
return res, fmt.Errorf("Unexpected end of braced value at index %d.", len(dsn))
|
return res, fmt.Errorf("unexpected end of braced value at index %d", len(dsn))
|
||||||
case parserStateBracedValueClosingBrace: // End of braced value
|
case parserStateBracedValueClosingBrace: // End of braced value
|
||||||
res[key] = value
|
res[key] = value
|
||||||
case parserStateEndValue: // Okay
|
case parserStateEndValue: // Okay
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package mssql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Federated authentication library affects the login data structure and message sequence.
|
||||||
|
const (
|
||||||
|
// fedAuthLibraryLiveIDCompactToken specifies the Microsoft Live ID Compact Token authentication scheme
|
||||||
|
fedAuthLibraryLiveIDCompactToken = 0x00
|
||||||
|
|
||||||
|
// fedAuthLibrarySecurityToken specifies a token-based authentication where the token is available
|
||||||
|
// without additional information provided during the login sequence.
|
||||||
|
fedAuthLibrarySecurityToken = 0x01
|
||||||
|
|
||||||
|
// fedAuthLibraryADAL specifies a token-based authentication where a token is obtained during the
|
||||||
|
// login sequence using the server SPN and STS URL provided by the server during login.
|
||||||
|
fedAuthLibraryADAL = 0x02
|
||||||
|
|
||||||
|
// fedAuthLibraryReserved is used to indicate that no federated authentication scheme applies.
|
||||||
|
fedAuthLibraryReserved = 0x7F
|
||||||
|
)
|
||||||
|
|
||||||
|
// Federated authentication ADAL workflow affects the mechanism used to authenticate.
|
||||||
|
const (
|
||||||
|
// fedAuthADALWorkflowPassword uses a username/password to obtain a token from Active Directory
|
||||||
|
fedAuthADALWorkflowPassword = 0x01
|
||||||
|
|
||||||
|
// fedAuthADALWorkflowPassword uses the Windows identity to obtain a token from Active Directory
|
||||||
|
fedAuthADALWorkflowIntegrated = 0x02
|
||||||
|
|
||||||
|
// fedAuthADALWorkflowMSI uses the managed identity service to obtain a token
|
||||||
|
fedAuthADALWorkflowMSI = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
|
// newSecurityTokenConnector creates a new connector from a DSN and a token provider.
|
||||||
|
// When invoked, token provider implementations should contact the security token
|
||||||
|
// service specified and obtain the appropriate token, or return an error
|
||||||
|
// to indicate why a token is not available.
|
||||||
|
// The returned connector may be used with sql.OpenDB.
|
||||||
|
func newSecurityTokenConnector(dsn string, tokenProvider func(ctx context.Context) (string, error)) (*Connector, error) {
|
||||||
|
if tokenProvider == nil {
|
||||||
|
return nil, errors.New("mssql: tokenProvider cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := NewConnector(dsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.params.fedAuthLibrary = fedAuthLibrarySecurityToken
|
||||||
|
conn.securityTokenProvider = tokenProvider
|
||||||
|
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newADALTokenConnector creates a new connector from a DSN and a Active Directory token provider.
|
||||||
|
// Token provider implementations are called during federated
|
||||||
|
// authentication login sequences where the server provides a service
|
||||||
|
// principal name and security token service endpoint that should be used
|
||||||
|
// to obtain the token. Implementations should contact the security token
|
||||||
|
// service specified and obtain the appropriate token, or return an error
|
||||||
|
// to indicate why a token is not available.
|
||||||
|
//
|
||||||
|
// The returned connector may be used with sql.OpenDB.
|
||||||
|
func newActiveDirectoryTokenConnector(dsn string, adalWorkflow byte, tokenProvider func(ctx context.Context, serverSPN, stsURL string) (string, error)) (*Connector, error) {
|
||||||
|
if tokenProvider == nil {
|
||||||
|
return nil, errors.New("mssql: tokenProvider cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := NewConnector(dsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.params.fedAuthLibrary = fedAuthLibraryADAL
|
||||||
|
conn.params.fedAuthADALWorkflow = adalWorkflow
|
||||||
|
conn.adalTokenProvider = tokenProvider
|
||||||
|
|
||||||
|
return conn, nil
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ func (d *Driver) OpenConnector(dsn string) (*Connector, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Connector{
|
return &Connector{
|
||||||
params: params,
|
params: params,
|
||||||
driver: d,
|
driver: d,
|
||||||
|
@ -100,6 +101,12 @@ type Connector struct {
|
||||||
params connectParams
|
params connectParams
|
||||||
driver *Driver
|
driver *Driver
|
||||||
|
|
||||||
|
// callback that can provide a security token during login
|
||||||
|
securityTokenProvider func(ctx context.Context) (string, error)
|
||||||
|
|
||||||
|
// callback that can provide a security token during ADAL login
|
||||||
|
adalTokenProvider func(ctx context.Context, serverSPN, stsURL string) (string, error)
|
||||||
|
|
||||||
// SessionInitSQL is executed after marking a given session to be reset.
|
// SessionInitSQL is executed after marking a given session to be reset.
|
||||||
// When not present, the next query will still reset the session to the
|
// When not present, the next query will still reset the session to the
|
||||||
// database defaults.
|
// database defaults.
|
||||||
|
@ -148,15 +155,7 @@ type Conn struct {
|
||||||
processQueryText bool
|
processQueryText bool
|
||||||
connectionGood bool
|
connectionGood bool
|
||||||
|
|
||||||
outs map[string]interface{}
|
outs map[string]interface{}
|
||||||
returnStatus *ReturnStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) setReturnStatus(s ReturnStatus) {
|
|
||||||
if c.returnStatus == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*c.returnStatus = s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) checkBadConn(err error) error {
|
func (c *Conn) checkBadConn(err error) error {
|
||||||
|
@ -201,20 +200,15 @@ func (c *Conn) clearOuts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) simpleProcessResp(ctx context.Context) error {
|
func (c *Conn) simpleProcessResp(ctx context.Context) error {
|
||||||
tokchan := make(chan tokenStruct, 5)
|
reader := startReading(c.sess, ctx, c.outs)
|
||||||
go processResponse(ctx, c.sess, tokchan, c.outs)
|
|
||||||
c.clearOuts()
|
c.clearOuts()
|
||||||
for tok := range tokchan {
|
|
||||||
switch token := tok.(type) {
|
var resultError error
|
||||||
case doneStruct:
|
err := reader.iterateResponse()
|
||||||
if token.isError() {
|
if err != nil {
|
||||||
return c.checkBadConn(token.getError())
|
return c.checkBadConn(err)
|
||||||
}
|
|
||||||
case error:
|
|
||||||
return c.checkBadConn(token)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return resultError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) Commit() error {
|
func (c *Conn) Commit() error {
|
||||||
|
@ -239,7 +233,7 @@ func (c *Conn) sendCommitRequest() error {
|
||||||
c.sess.log.Printf("Failed to send CommitXact with %v", err)
|
c.sess.log.Printf("Failed to send CommitXact with %v", err)
|
||||||
}
|
}
|
||||||
c.connectionGood = false
|
c.connectionGood = false
|
||||||
return fmt.Errorf("Faild to send CommitXact: %v", err)
|
return fmt.Errorf("faild to send CommitXact: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -266,7 +260,7 @@ func (c *Conn) sendRollbackRequest() error {
|
||||||
c.sess.log.Printf("Failed to send RollbackXact with %v", err)
|
c.sess.log.Printf("Failed to send RollbackXact with %v", err)
|
||||||
}
|
}
|
||||||
c.connectionGood = false
|
c.connectionGood = false
|
||||||
return fmt.Errorf("Failed to send RollbackXact: %v", err)
|
return fmt.Errorf("failed to send RollbackXact: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -303,7 +297,7 @@ func (c *Conn) sendBeginRequest(ctx context.Context, tdsIsolation isoLevel) erro
|
||||||
c.sess.log.Printf("Failed to send BeginXact with %v", err)
|
c.sess.log.Printf("Failed to send BeginXact with %v", err)
|
||||||
}
|
}
|
||||||
c.connectionGood = false
|
c.connectionGood = false
|
||||||
return fmt.Errorf("Failed to send BeginXact: %v", err)
|
return fmt.Errorf("failed to send BeginXact: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -478,7 +472,7 @@ func (s *Stmt) sendQuery(args []namedValue) (err error) {
|
||||||
conn.sess.log.Printf("Failed to send Rpc with %v", err)
|
conn.sess.log.Printf("Failed to send Rpc with %v", err)
|
||||||
}
|
}
|
||||||
conn.connectionGood = false
|
conn.connectionGood = false
|
||||||
return fmt.Errorf("Failed to send RPC: %v", err)
|
return fmt.Errorf("failed to send RPC: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -595,38 +589,46 @@ func (s *Stmt) queryContext(ctx context.Context, args []namedValue) (rows driver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stmt) processQueryResponse(ctx context.Context) (res driver.Rows, err error) {
|
func (s *Stmt) processQueryResponse(ctx context.Context) (res driver.Rows, err error) {
|
||||||
tokchan := make(chan tokenStruct, 5)
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
go processResponse(ctx, s.c.sess, tokchan, s.c.outs)
|
reader := startReading(s.c.sess, ctx, s.c.outs)
|
||||||
s.c.clearOuts()
|
s.c.clearOuts()
|
||||||
// process metadata
|
// process metadata
|
||||||
var cols []columnStruct
|
var cols []columnStruct
|
||||||
loop:
|
loop:
|
||||||
for tok := range tokchan {
|
for {
|
||||||
switch token := tok.(type) {
|
tok, err := reader.nextToken()
|
||||||
// By ignoring DONE token we effectively
|
if err == nil {
|
||||||
// skip empty result-sets.
|
if tok == nil {
|
||||||
// This improves results in queries like that:
|
break
|
||||||
// set nocount on; select 1
|
} else {
|
||||||
// see TestIgnoreEmptyResults test
|
switch token := tok.(type) {
|
||||||
//case doneStruct:
|
// By ignoring DONE token we effectively
|
||||||
//break loop
|
// skip empty result-sets.
|
||||||
case []columnStruct:
|
// This improves results in queries like that:
|
||||||
cols = token
|
// set nocount on; select 1
|
||||||
break loop
|
// see TestIgnoreEmptyResults test
|
||||||
case doneStruct:
|
//case doneStruct:
|
||||||
if token.isError() {
|
//break loop
|
||||||
cancel()
|
case []columnStruct:
|
||||||
return nil, s.c.checkBadConn(token.getError())
|
cols = token
|
||||||
|
break loop
|
||||||
|
case doneStruct:
|
||||||
|
if token.isError() {
|
||||||
|
// need to cleanup cancellable context
|
||||||
|
cancel()
|
||||||
|
return nil, s.c.checkBadConn(token.getError())
|
||||||
|
}
|
||||||
|
case ReturnStatus:
|
||||||
|
s.c.sess.setReturnStatus(token)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case ReturnStatus:
|
} else {
|
||||||
s.c.setReturnStatus(token)
|
// need to cleanup cancellable context
|
||||||
case error:
|
|
||||||
cancel()
|
cancel()
|
||||||
return nil, s.c.checkBadConn(token)
|
return nil, s.c.checkBadConn(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = &Rows{stmt: s, tokchan: tokchan, cols: cols, cancel: cancel}
|
res = &Rows{stmt: s, reader: reader, cols: cols, cancel: cancel}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,48 +650,46 @@ func (s *Stmt) exec(ctx context.Context, args []namedValue) (res driver.Result,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stmt) processExec(ctx context.Context) (res driver.Result, err error) {
|
func (s *Stmt) processExec(ctx context.Context) (res driver.Result, err error) {
|
||||||
tokchan := make(chan tokenStruct, 5)
|
reader := startReading(s.c.sess, ctx, s.c.outs)
|
||||||
go processResponse(ctx, s.c.sess, tokchan, s.c.outs)
|
|
||||||
s.c.clearOuts()
|
s.c.clearOuts()
|
||||||
var rowCount int64
|
err = reader.iterateResponse()
|
||||||
for token := range tokchan {
|
if err != nil {
|
||||||
switch token := token.(type) {
|
return nil, s.c.checkBadConn(err)
|
||||||
case doneInProcStruct:
|
|
||||||
if token.Status&doneCount != 0 {
|
|
||||||
rowCount += int64(token.RowCount)
|
|
||||||
}
|
|
||||||
case doneStruct:
|
|
||||||
if token.Status&doneCount != 0 {
|
|
||||||
rowCount += int64(token.RowCount)
|
|
||||||
}
|
|
||||||
if token.isError() {
|
|
||||||
return nil, token.getError()
|
|
||||||
}
|
|
||||||
case ReturnStatus:
|
|
||||||
s.c.setReturnStatus(token)
|
|
||||||
case error:
|
|
||||||
return nil, token
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return &Result{s.c, rowCount}, nil
|
return &Result{s.c, reader.rowCount}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Rows struct {
|
type Rows struct {
|
||||||
stmt *Stmt
|
stmt *Stmt
|
||||||
cols []columnStruct
|
cols []columnStruct
|
||||||
tokchan chan tokenStruct
|
reader *tokenProcessor
|
||||||
|
|
||||||
nextCols []columnStruct
|
nextCols []columnStruct
|
||||||
|
|
||||||
cancel func()
|
cancel func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *Rows) Close() error {
|
func (rc *Rows) Close() error {
|
||||||
|
// need to add a test which returns lots of rows
|
||||||
|
// and check closing after reading only few rows
|
||||||
rc.cancel()
|
rc.cancel()
|
||||||
for _ = range rc.tokchan {
|
|
||||||
|
for {
|
||||||
|
tok, err := rc.reader.nextToken()
|
||||||
|
if err == nil {
|
||||||
|
if tok == nil {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
// continue consuming tokens
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err == rc.reader.ctx.Err() {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rc.tokchan = nil
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *Rows) Columns() (res []string) {
|
func (rc *Rows) Columns() (res []string) {
|
||||||
|
@ -707,27 +707,34 @@ func (rc *Rows) Next(dest []driver.Value) error {
|
||||||
if rc.nextCols != nil {
|
if rc.nextCols != nil {
|
||||||
return io.EOF
|
return io.EOF
|
||||||
}
|
}
|
||||||
for tok := range rc.tokchan {
|
for {
|
||||||
switch tokdata := tok.(type) {
|
tok, err := rc.reader.nextToken()
|
||||||
case []columnStruct:
|
if err == nil {
|
||||||
rc.nextCols = tokdata
|
if tok == nil {
|
||||||
return io.EOF
|
return io.EOF
|
||||||
case []interface{}:
|
} else {
|
||||||
for i := range dest {
|
switch tokdata := tok.(type) {
|
||||||
dest[i] = tokdata[i]
|
case []columnStruct:
|
||||||
|
rc.nextCols = tokdata
|
||||||
|
return io.EOF
|
||||||
|
case []interface{}:
|
||||||
|
for i := range dest {
|
||||||
|
dest[i] = tokdata[i]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case doneStruct:
|
||||||
|
if tokdata.isError() {
|
||||||
|
return rc.stmt.c.checkBadConn(tokdata.getError())
|
||||||
|
}
|
||||||
|
case ReturnStatus:
|
||||||
|
rc.stmt.c.sess.setReturnStatus(tokdata)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
case doneStruct:
|
} else {
|
||||||
if tokdata.isError() {
|
return rc.stmt.c.checkBadConn(err)
|
||||||
return rc.stmt.c.checkBadConn(tokdata.getError())
|
|
||||||
}
|
|
||||||
case ReturnStatus:
|
|
||||||
rc.stmt.c.setReturnStatus(tokdata)
|
|
||||||
case error:
|
|
||||||
return rc.stmt.c.checkBadConn(tokdata)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return io.EOF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *Rows) HasNextResultSet() bool {
|
func (rc *Rows) HasNextResultSet() bool {
|
||||||
|
@ -895,35 +902,41 @@ func (c *Conn) Ping(ctx context.Context) error {
|
||||||
|
|
||||||
var _ driver.ConnBeginTx = &Conn{}
|
var _ driver.ConnBeginTx = &Conn{}
|
||||||
|
|
||||||
|
func convertIsolationLevel(level sql.IsolationLevel) (isoLevel, error) {
|
||||||
|
switch level {
|
||||||
|
case sql.LevelDefault:
|
||||||
|
return isolationUseCurrent, nil
|
||||||
|
case sql.LevelReadUncommitted:
|
||||||
|
return isolationReadUncommited, nil
|
||||||
|
case sql.LevelReadCommitted:
|
||||||
|
return isolationReadCommited, nil
|
||||||
|
case sql.LevelWriteCommitted:
|
||||||
|
return isolationUseCurrent, errors.New("LevelWriteCommitted isolation level is not supported")
|
||||||
|
case sql.LevelRepeatableRead:
|
||||||
|
return isolationRepeatableRead, nil
|
||||||
|
case sql.LevelSnapshot:
|
||||||
|
return isolationSnapshot, nil
|
||||||
|
case sql.LevelSerializable:
|
||||||
|
return isolationSerializable, nil
|
||||||
|
case sql.LevelLinearizable:
|
||||||
|
return isolationUseCurrent, errors.New("LevelLinearizable isolation level is not supported")
|
||||||
|
default:
|
||||||
|
return isolationUseCurrent, errors.New("isolation level is not supported or unknown")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BeginTx satisfies ConnBeginTx.
|
// BeginTx satisfies ConnBeginTx.
|
||||||
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||||
if !c.connectionGood {
|
if !c.connectionGood {
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
if opts.ReadOnly {
|
if opts.ReadOnly {
|
||||||
return nil, errors.New("Read-only transactions are not supported")
|
return nil, errors.New("read-only transactions are not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
var tdsIsolation isoLevel
|
tdsIsolation, err := convertIsolationLevel(sql.IsolationLevel(opts.Isolation))
|
||||||
switch sql.IsolationLevel(opts.Isolation) {
|
if err != nil {
|
||||||
case sql.LevelDefault:
|
return nil, err
|
||||||
tdsIsolation = isolationUseCurrent
|
|
||||||
case sql.LevelReadUncommitted:
|
|
||||||
tdsIsolation = isolationReadUncommited
|
|
||||||
case sql.LevelReadCommitted:
|
|
||||||
tdsIsolation = isolationReadCommited
|
|
||||||
case sql.LevelWriteCommitted:
|
|
||||||
return nil, errors.New("LevelWriteCommitted isolation level is not supported")
|
|
||||||
case sql.LevelRepeatableRead:
|
|
||||||
tdsIsolation = isolationRepeatableRead
|
|
||||||
case sql.LevelSnapshot:
|
|
||||||
tdsIsolation = isolationSnapshot
|
|
||||||
case sql.LevelSerializable:
|
|
||||||
tdsIsolation = isolationSerializable
|
|
||||||
case sql.LevelLinearizable:
|
|
||||||
return nil, errors.New("LevelLinearizable isolation level is not supported")
|
|
||||||
default:
|
|
||||||
return nil, errors.New("Isolation level is not supported or unknown")
|
|
||||||
}
|
}
|
||||||
return c.begin(ctx, tdsIsolation)
|
return c.begin(ctx, tdsIsolation)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,5 +48,5 @@ func (c *Connector) Driver() driver.Driver {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Result) LastInsertId() (int64, error) {
|
func (r *Result) LastInsertId() (int64, error) {
|
||||||
return -1, errors.New("LastInsertId is not supported. Please use the OUTPUT clause or add `select ID = convert(bigint, SCOPE_IDENTITY())` to the end of your query.")
|
return -1, errors.New("LastInsertId is not supported. Please use the OUTPUT clause or add `select ID = convert(bigint, SCOPE_IDENTITY())` to the end of your query")
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error {
|
||||||
return nil
|
return nil
|
||||||
case *ReturnStatus:
|
case *ReturnStatus:
|
||||||
*v = 0 // By default the return value should be zero.
|
*v = 0 // By default the return value should be zero.
|
||||||
c.returnStatus = v
|
c.sess.returnStatus = v
|
||||||
return driver.ErrRemoveArgument
|
return driver.ErrRemoveArgument
|
||||||
case TVP:
|
case TVP:
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type timeoutConn struct {
|
type timeoutConn struct {
|
||||||
c net.Conn
|
c net.Conn
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn {
|
func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn {
|
||||||
|
@ -51,21 +51,21 @@ func (c timeoutConn) RemoteAddr() net.Addr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c timeoutConn) SetDeadline(t time.Time) error {
|
func (c timeoutConn) SetDeadline(t time.Time) error {
|
||||||
panic("Not implemented")
|
return c.c.SetDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c timeoutConn) SetReadDeadline(t time.Time) error {
|
func (c timeoutConn) SetReadDeadline(t time.Time) error {
|
||||||
panic("Not implemented")
|
return c.c.SetReadDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c timeoutConn) SetWriteDeadline(t time.Time) error {
|
func (c timeoutConn) SetWriteDeadline(t time.Time) error {
|
||||||
panic("Not implemented")
|
return c.c.SetWriteDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this connection is used during TLS Handshake
|
// this connection is used during TLS Handshake
|
||||||
// TDS protocol requires TLS handshake messages to be sent inside TDS packets
|
// TDS protocol requires TLS handshake messages to be sent inside TDS packets
|
||||||
type tlsHandshakeConn struct {
|
type tlsHandshakeConn struct {
|
||||||
buf *tdsBuffer
|
buf *tdsBuffer
|
||||||
packetPending bool
|
packetPending bool
|
||||||
continueRead bool
|
continueRead bool
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) {
|
||||||
c.packetPending = false
|
c.packetPending = false
|
||||||
err = c.buf.FinishPacket()
|
err = c.buf.FinishPacket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Cannot send handshake packet: %s", err.Error())
|
err = fmt.Errorf("cannot send handshake packet: %s", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.continueRead = false
|
c.continueRead = false
|
||||||
|
@ -84,7 +84,7 @@ func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) {
|
||||||
var packet packetType
|
var packet packetType
|
||||||
packet, err = c.buf.BeginRead()
|
packet, err = c.buf.BeginRead()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Cannot read handshake packet: %s", err.Error())
|
err = fmt.Errorf("cannot read handshake packet: %s", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if packet != packPrelogin {
|
if packet != packPrelogin {
|
||||||
|
@ -105,27 +105,27 @@ func (c *tlsHandshakeConn) Write(b []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tlsHandshakeConn) Close() error {
|
func (c *tlsHandshakeConn) Close() error {
|
||||||
panic("Not implemented")
|
return c.buf.transport.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tlsHandshakeConn) LocalAddr() net.Addr {
|
func (c *tlsHandshakeConn) LocalAddr() net.Addr {
|
||||||
panic("Not implemented")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tlsHandshakeConn) RemoteAddr() net.Addr {
|
func (c *tlsHandshakeConn) RemoteAddr() net.Addr {
|
||||||
panic("Not implemented")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tlsHandshakeConn) SetDeadline(t time.Time) error {
|
func (c *tlsHandshakeConn) SetDeadline(_ time.Time) error {
|
||||||
panic("Not implemented")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tlsHandshakeConn) SetReadDeadline(t time.Time) error {
|
func (c *tlsHandshakeConn) SetReadDeadline(_ time.Time) error {
|
||||||
panic("Not implemented")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tlsHandshakeConn) SetWriteDeadline(t time.Time) error {
|
func (c *tlsHandshakeConn) SetWriteDeadline(_ time.Time) error {
|
||||||
panic("Not implemented")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// this connection just delegates all methods to it's wrapped connection
|
// this connection just delegates all methods to it's wrapped connection
|
||||||
|
@ -148,21 +148,21 @@ func (c passthroughConn) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c passthroughConn) LocalAddr() net.Addr {
|
func (c passthroughConn) LocalAddr() net.Addr {
|
||||||
panic("Not implemented")
|
return c.c.LocalAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c passthroughConn) RemoteAddr() net.Addr {
|
func (c passthroughConn) RemoteAddr() net.Addr {
|
||||||
panic("Not implemented")
|
return c.c.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c passthroughConn) SetDeadline(t time.Time) error {
|
func (c passthroughConn) SetDeadline(t time.Time) error {
|
||||||
panic("Not implemented")
|
return c.c.SetDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c passthroughConn) SetReadDeadline(t time.Time) error {
|
func (c passthroughConn) SetReadDeadline(t time.Time) error {
|
||||||
panic("Not implemented")
|
return c.c.SetReadDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c passthroughConn) SetWriteDeadline(t time.Time) error {
|
func (c passthroughConn) SetWriteDeadline(t time.Time) error {
|
||||||
panic("Not implemented")
|
return c.c.SetWriteDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
|
|
||||||
|
//lint:ignore SA1019 MD4 is used by legacy NTLM
|
||||||
"golang.org/x/crypto/md4"
|
"golang.org/x/crypto/md4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -126,18 +127,6 @@ func createDesKey(bytes, material []byte) {
|
||||||
material[7] = (byte)(bytes[6] << 1)
|
material[7] = (byte)(bytes[6] << 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func oddParity(bytes []byte) {
|
|
||||||
for i := 0; i < len(bytes); i++ {
|
|
||||||
b := bytes[i]
|
|
||||||
needsParity := (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0
|
|
||||||
if needsParity {
|
|
||||||
bytes[i] = bytes[i] | byte(0x01)
|
|
||||||
} else {
|
|
||||||
bytes[i] = bytes[i] & byte(0xfe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func encryptDes(key []byte, cleartext []byte, ciphertext []byte) {
|
func encryptDes(key []byte, cleartext []byte, ciphertext []byte) {
|
||||||
var desKey [8]byte
|
var desKey [8]byte
|
||||||
createDesKey(key, desKey[:])
|
createDesKey(key, desKey[:])
|
||||||
|
|
|
@ -22,12 +22,6 @@ type param struct {
|
||||||
buffer []byte
|
buffer []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
fWithRecomp = 1
|
|
||||||
fNoMetaData = 2
|
|
||||||
fReuseMetaData = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
sp_Cursor = procId{1, ""}
|
sp_Cursor = procId{1, ""}
|
||||||
sp_CursorOpen = procId{2, ""}
|
sp_CursorOpen = procId{2, ""}
|
||||||
|
|
|
@ -82,19 +82,20 @@ const (
|
||||||
// https://msdn.microsoft.com/en-us/library/dd304214.aspx
|
// https://msdn.microsoft.com/en-us/library/dd304214.aspx
|
||||||
const (
|
const (
|
||||||
packSQLBatch packetType = 1
|
packSQLBatch packetType = 1
|
||||||
packRPCRequest = 3
|
packRPCRequest packetType = 3
|
||||||
packReply = 4
|
packReply packetType = 4
|
||||||
|
|
||||||
// 2.2.1.7 Attention: https://msdn.microsoft.com/en-us/library/dd341449.aspx
|
// 2.2.1.7 Attention: https://msdn.microsoft.com/en-us/library/dd341449.aspx
|
||||||
// 4.19.2 Out-of-Band Attention Signal: https://msdn.microsoft.com/en-us/library/dd305167.aspx
|
// 4.19.2 Out-of-Band Attention Signal: https://msdn.microsoft.com/en-us/library/dd305167.aspx
|
||||||
packAttention = 6
|
packAttention packetType = 6
|
||||||
|
|
||||||
packBulkLoadBCP = 7
|
packBulkLoadBCP packetType = 7
|
||||||
packTransMgrReq = 14
|
packFedAuthToken packetType = 8
|
||||||
packNormal = 15
|
packTransMgrReq packetType = 14
|
||||||
packLogin7 = 16
|
packNormal packetType = 15
|
||||||
packSSPIMessage = 17
|
packLogin7 packetType = 16
|
||||||
packPrelogin = 18
|
packSSPIMessage packetType = 17
|
||||||
|
packPrelogin packetType = 18
|
||||||
)
|
)
|
||||||
|
|
||||||
// prelogin fields
|
// prelogin fields
|
||||||
|
@ -118,6 +119,17 @@ const (
|
||||||
encryptReq = 3 // Encryption is required.
|
encryptReq = 3 // Encryption is required.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
featExtSESSIONRECOVERY byte = 0x01
|
||||||
|
featExtFEDAUTH byte = 0x02
|
||||||
|
featExtCOLUMNENCRYPTION byte = 0x04
|
||||||
|
featExtGLOBALTRANSACTIONS byte = 0x05
|
||||||
|
featExtAZURESQLSUPPORT byte = 0x08
|
||||||
|
featExtDATACLASSIFICATION byte = 0x09
|
||||||
|
featExtUTF8SUPPORT byte = 0x0A
|
||||||
|
featExtTERMINATOR byte = 0xFF
|
||||||
|
)
|
||||||
|
|
||||||
type tdsSession struct {
|
type tdsSession struct {
|
||||||
buf *tdsBuffer
|
buf *tdsBuffer
|
||||||
loginAck loginAckStruct
|
loginAck loginAckStruct
|
||||||
|
@ -129,6 +141,7 @@ type tdsSession struct {
|
||||||
log optionalLogger
|
log optionalLogger
|
||||||
routedServer string
|
routedServer string
|
||||||
routedPort uint16
|
routedPort uint16
|
||||||
|
returnStatus *ReturnStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -155,13 +168,13 @@ func (p keySlice) Less(i, j int) bool { return p[i] < p[j] }
|
||||||
func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/dd357559.aspx
|
// http://msdn.microsoft.com/en-us/library/dd357559.aspx
|
||||||
func writePrelogin(w *tdsBuffer, fields map[uint8][]byte) error {
|
func writePrelogin(packetType packetType, w *tdsBuffer, fields map[uint8][]byte) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
w.BeginPacket(packPrelogin, false)
|
w.BeginPacket(packetType, false)
|
||||||
offset := uint16(5*len(fields) + 1)
|
offset := uint16(5*len(fields) + 1)
|
||||||
keys := make(keySlice, 0, len(fields))
|
keys := make(keySlice, 0, len(fields))
|
||||||
for k, _ := range fields {
|
for k := range fields {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
sort.Sort(keys)
|
sort.Sort(keys)
|
||||||
|
@ -210,12 +223,15 @@ func readPrelogin(r *tdsBuffer) (map[uint8][]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if packet_type != 4 {
|
if packet_type != packReply {
|
||||||
return nil, errors.New("Invalid respones, expected packet type 4, PRELOGIN RESPONSE")
|
return nil, errors.New("invalid respones, expected packet type 4, PRELOGIN RESPONSE")
|
||||||
|
}
|
||||||
|
if len(struct_buf) == 0 {
|
||||||
|
return nil, errors.New("invalid empty PRELOGIN response, it must contain at least one byte")
|
||||||
}
|
}
|
||||||
offset := 0
|
offset := 0
|
||||||
results := map[uint8][]byte{}
|
results := map[uint8][]byte{}
|
||||||
for true {
|
for {
|
||||||
rec_type := struct_buf[offset]
|
rec_type := struct_buf[offset]
|
||||||
if rec_type == preloginTERMINATOR {
|
if rec_type == preloginTERMINATOR {
|
||||||
break
|
break
|
||||||
|
@ -240,6 +256,16 @@ const (
|
||||||
fIntSecurity = 0x80
|
fIntSecurity = 0x80
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OptionFlags3
|
||||||
|
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
|
||||||
|
const (
|
||||||
|
fChangePassword = 1
|
||||||
|
fSendYukonBinaryXML = 2
|
||||||
|
fUserInstance = 4
|
||||||
|
fUnknownCollationHandling = 8
|
||||||
|
fExtension = 0x10
|
||||||
|
)
|
||||||
|
|
||||||
// TypeFlags
|
// TypeFlags
|
||||||
const (
|
const (
|
||||||
// 4 bits for fSQLType
|
// 4 bits for fSQLType
|
||||||
|
@ -247,12 +273,6 @@ const (
|
||||||
fReadOnlyIntent = 32
|
fReadOnlyIntent = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
// OptionFlags3
|
|
||||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
|
|
||||||
const (
|
|
||||||
fExtension = 0x10
|
|
||||||
)
|
|
||||||
|
|
||||||
type login struct {
|
type login struct {
|
||||||
TDSVersion uint32
|
TDSVersion uint32
|
||||||
PacketSize uint32
|
PacketSize uint32
|
||||||
|
@ -295,7 +315,7 @@ func (e *featureExts) Add(f featureExt) error {
|
||||||
}
|
}
|
||||||
id := f.featureID()
|
id := f.featureID()
|
||||||
if _, exists := e.features[id]; exists {
|
if _, exists := e.features[id]; exists {
|
||||||
f := "Login error: Feature with ID '%v' is already present in FeatureExt block."
|
f := "login error: Feature with ID '%v' is already present in FeatureExt block"
|
||||||
return fmt.Errorf(f, id)
|
return fmt.Errorf(f, id)
|
||||||
}
|
}
|
||||||
if e.features == nil {
|
if e.features == nil {
|
||||||
|
@ -326,37 +346,63 @@ func (e featureExts) toBytes() []byte {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
type featureExtFedAuthSTS struct {
|
// featureExtFedAuth tracks federated authentication state before and during login
|
||||||
FedAuthEcho bool
|
type featureExtFedAuth struct {
|
||||||
|
// FedAuthLibrary is populated by the federated authentication provider.
|
||||||
|
FedAuthLibrary int
|
||||||
|
|
||||||
|
// ADALWorkflow is populated by the federated authentication provider.
|
||||||
|
ADALWorkflow byte
|
||||||
|
|
||||||
|
// FedAuthEcho is populated from the prelogin response
|
||||||
|
FedAuthEcho bool
|
||||||
|
|
||||||
|
// FedAuthToken is populated during login with the value from the provider.
|
||||||
FedAuthToken string
|
FedAuthToken string
|
||||||
Nonce []byte
|
|
||||||
|
// Nonce is populated during login with the value from the provider.
|
||||||
|
Nonce []byte
|
||||||
|
|
||||||
|
// Signature is populated during login with the value from the server.
|
||||||
|
Signature []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *featureExtFedAuthSTS) featureID() byte {
|
func (e *featureExtFedAuth) featureID() byte {
|
||||||
return 0x02
|
return featExtFEDAUTH
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *featureExtFedAuthSTS) toBytes() []byte {
|
func (e *featureExtFedAuth) toBytes() []byte {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
options := byte(0x01) << 1 // 0x01 => STS bFedAuthLibrary 7BIT
|
options := byte(e.FedAuthLibrary) << 1
|
||||||
if e.FedAuthEcho {
|
if e.FedAuthEcho {
|
||||||
options |= 1 // fFedAuthEcho
|
options |= 1 // fFedAuthEcho
|
||||||
}
|
}
|
||||||
|
|
||||||
d := make([]byte, 5)
|
// Feature extension format depends on the federated auth library.
|
||||||
d[0] = options
|
// Options are described at
|
||||||
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
|
||||||
|
var d []byte
|
||||||
|
|
||||||
// looks like string in
|
switch e.FedAuthLibrary {
|
||||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/f88b63bb-b479-49e1-a87b-deda521da508
|
case fedAuthLibrarySecurityToken:
|
||||||
tokenBytes := str2ucs2(e.FedAuthToken)
|
d = make([]byte, 5)
|
||||||
binary.LittleEndian.PutUint32(d[1:], uint32(len(tokenBytes))) // Should be a signed int32, but since the length is relatively small, this should work
|
d[0] = options
|
||||||
d = append(d, tokenBytes...)
|
|
||||||
|
|
||||||
if len(e.Nonce) == 32 {
|
// looks like string in
|
||||||
d = append(d, e.Nonce...)
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/f88b63bb-b479-49e1-a87b-deda521da508
|
||||||
|
tokenBytes := str2ucs2(e.FedAuthToken)
|
||||||
|
binary.LittleEndian.PutUint32(d[1:], uint32(len(tokenBytes))) // Should be a signed int32, but since the length is relatively small, this should work
|
||||||
|
d = append(d, tokenBytes...)
|
||||||
|
|
||||||
|
if len(e.Nonce) == 32 {
|
||||||
|
d = append(d, e.Nonce...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case fedAuthLibraryADAL:
|
||||||
|
d = []byte{options, e.ADALWorkflow}
|
||||||
}
|
}
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
@ -418,7 +464,7 @@ func str2ucs2(s string) []byte {
|
||||||
|
|
||||||
func ucs22str(s []byte) (string, error) {
|
func ucs22str(s []byte) (string, error) {
|
||||||
if len(s)%2 != 0 {
|
if len(s)%2 != 0 {
|
||||||
return "", fmt.Errorf("Illegal UCS2 string length: %d", len(s))
|
return "", fmt.Errorf("illegal UCS2 string length: %d", len(s))
|
||||||
}
|
}
|
||||||
buf := make([]uint16, len(s)/2)
|
buf := make([]uint16, len(s)/2)
|
||||||
for i := 0; i < len(s); i += 2 {
|
for i := 0; i < len(s); i += 2 {
|
||||||
|
@ -436,7 +482,7 @@ func manglePassword(password string) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
|
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
|
||||||
func sendLogin(w *tdsBuffer, login login) error {
|
func sendLogin(w *tdsBuffer, login *login) error {
|
||||||
w.BeginPacket(packLogin7, false)
|
w.BeginPacket(packLogin7, false)
|
||||||
hostname := str2ucs2(login.HostName)
|
hostname := str2ucs2(login.HostName)
|
||||||
username := str2ucs2(login.UserName)
|
username := str2ucs2(login.UserName)
|
||||||
|
@ -572,6 +618,36 @@ func sendLogin(w *tdsBuffer, login login) error {
|
||||||
return w.FinishPacket()
|
return w.FinishPacket()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/827d9632-2957-4d54-b9ea-384530ae79d0
|
||||||
|
func sendFedAuthInfo(w *tdsBuffer, fedAuth *featureExtFedAuth) (err error) {
|
||||||
|
fedauthtoken := str2ucs2(fedAuth.FedAuthToken)
|
||||||
|
tokenlen := len(fedauthtoken)
|
||||||
|
datalen := 4 + tokenlen + len(fedAuth.Nonce)
|
||||||
|
|
||||||
|
w.BeginPacket(packFedAuthToken, false)
|
||||||
|
err = binary.Write(w, binary.LittleEndian, uint32(datalen))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = binary.Write(w, binary.LittleEndian, uint32(tokenlen))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(fedauthtoken)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(fedAuth.Nonce)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.FinishPacket()
|
||||||
|
}
|
||||||
|
|
||||||
func readUcs2(r io.Reader, numchars int) (res string, err error) {
|
func readUcs2(r io.Reader, numchars int) (res string, err error) {
|
||||||
buf := make([]byte, numchars*2)
|
buf := make([]byte, numchars*2)
|
||||||
_, err = io.ReadFull(r, buf)
|
_, err = io.ReadFull(r, buf)
|
||||||
|
@ -770,12 +846,13 @@ type auth interface {
|
||||||
// use the first one that allows a connection.
|
// use the first one that allows a connection.
|
||||||
func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) {
|
func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) {
|
||||||
var ips []net.IP
|
var ips []net.IP
|
||||||
ips, err = net.LookupIP(p.host)
|
ip := net.ParseIP(p.host)
|
||||||
if err != nil {
|
if ip == nil {
|
||||||
ip := net.ParseIP(p.host)
|
ips, err = net.LookupIP(p.host)
|
||||||
if ip == nil {
|
if err != nil {
|
||||||
return nil, err
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
ips = []net.IP{ip}
|
ips = []net.IP{ip}
|
||||||
}
|
}
|
||||||
if len(ips) == 1 {
|
if len(ips) == 1 {
|
||||||
|
@ -802,7 +879,7 @@ func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn ne
|
||||||
}
|
}
|
||||||
// Wait for either the *first* successful connection, or all the errors
|
// Wait for either the *first* successful connection, or all the errors
|
||||||
wait_loop:
|
wait_loop:
|
||||||
for i, _ := range ips {
|
for i := range ips {
|
||||||
select {
|
select {
|
||||||
case conn = <-connChan:
|
case conn = <-connChan:
|
||||||
// Got a connection to use, close any others
|
// Got a connection to use, close any others
|
||||||
|
@ -824,12 +901,123 @@ func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn ne
|
||||||
}
|
}
|
||||||
// Can't do the usual err != nil check, as it is possible to have gotten an error before a successful connection
|
// Can't do the usual err != nil check, as it is possible to have gotten an error before a successful connection
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
f := "Unable to open tcp connection with host '%v:%v': %v"
|
f := "unable to open tcp connection with host '%v:%v': %v"
|
||||||
return nil, fmt.Errorf(f, p.host, resolveServerPort(p.port), err.Error())
|
return nil, fmt.Errorf(f, p.host, resolveServerPort(p.port), err.Error())
|
||||||
}
|
}
|
||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func preparePreloginFields(p connectParams, fe *featureExtFedAuth) map[uint8][]byte {
|
||||||
|
instance_buf := []byte(p.instance)
|
||||||
|
instance_buf = append(instance_buf, 0) // zero terminate instance name
|
||||||
|
|
||||||
|
var encrypt byte
|
||||||
|
if p.disableEncryption {
|
||||||
|
encrypt = encryptNotSup
|
||||||
|
} else if p.encrypt {
|
||||||
|
encrypt = encryptOn
|
||||||
|
} else {
|
||||||
|
encrypt = encryptOff
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := map[uint8][]byte{
|
||||||
|
preloginVERSION: {0, 0, 0, 0, 0, 0},
|
||||||
|
preloginENCRYPTION: {encrypt},
|
||||||
|
preloginINSTOPT: instance_buf,
|
||||||
|
preloginTHREADID: {0, 0, 0, 0},
|
||||||
|
preloginMARS: {0}, // MARS disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
if fe.FedAuthLibrary != fedAuthLibraryReserved {
|
||||||
|
fields[preloginFEDAUTHREQUIRED] = []byte{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
|
func interpretPreloginResponse(p connectParams, fe *featureExtFedAuth, fields map[uint8][]byte) (encrypt byte, err error) {
|
||||||
|
// If the server returns the preloginFEDAUTHREQUIRED field, then federated authentication
|
||||||
|
// is supported. The actual value may be 0 or 1, where 0 means either SSPI or federated
|
||||||
|
// authentication is allowed, while 1 means only federated authentication is allowed.
|
||||||
|
if fedAuthSupport, ok := fields[preloginFEDAUTHREQUIRED]; ok {
|
||||||
|
if len(fedAuthSupport) != 1 {
|
||||||
|
return 0, fmt.Errorf("Federated authentication flag length should be 1: is %d", len(fedAuthSupport))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to be able to echo the value back to the server
|
||||||
|
fe.FedAuthEcho = fedAuthSupport[0] != 0
|
||||||
|
} else if fe.FedAuthLibrary != fedAuthLibraryReserved {
|
||||||
|
return 0, fmt.Errorf("Federated authentication is not supported by the server")
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptBytes, ok := fields[preloginENCRYPTION]
|
||||||
|
if !ok {
|
||||||
|
return 0, fmt.Errorf("encrypt negotiation failed")
|
||||||
|
}
|
||||||
|
encrypt = encryptBytes[0]
|
||||||
|
if p.encrypt && (encrypt == encryptNotSup || encrypt == encryptOff) {
|
||||||
|
return 0, fmt.Errorf("server does not support encryption")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareLogin(ctx context.Context, c *Connector, p connectParams, log optionalLogger, auth auth, fe *featureExtFedAuth, packetSize uint32) (l *login, err error) {
|
||||||
|
l = &login{
|
||||||
|
TDSVersion: verTDS74,
|
||||||
|
PacketSize: packetSize,
|
||||||
|
Database: p.database,
|
||||||
|
OptionFlags2: fODBC, // to get unlimited TEXTSIZE
|
||||||
|
HostName: p.workstation,
|
||||||
|
ServerName: p.host,
|
||||||
|
AppName: p.appname,
|
||||||
|
TypeFlags: p.typeFlags,
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case fe.FedAuthLibrary == fedAuthLibrarySecurityToken:
|
||||||
|
if p.logFlags&logDebug != 0 {
|
||||||
|
log.Println("Starting federated authentication using security token")
|
||||||
|
}
|
||||||
|
|
||||||
|
fe.FedAuthToken, err = c.securityTokenProvider(ctx)
|
||||||
|
if err != nil {
|
||||||
|
if p.logFlags&logDebug != 0 {
|
||||||
|
log.Printf("Failed to retrieve service principal token for federated authentication security token library: %v", err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.FeatureExt.Add(fe)
|
||||||
|
|
||||||
|
case fe.FedAuthLibrary == fedAuthLibraryADAL:
|
||||||
|
if p.logFlags&logDebug != 0 {
|
||||||
|
log.Println("Starting federated authentication using ADAL")
|
||||||
|
}
|
||||||
|
|
||||||
|
l.FeatureExt.Add(fe)
|
||||||
|
|
||||||
|
case auth != nil:
|
||||||
|
if p.logFlags&logDebug != 0 {
|
||||||
|
log.Println("Starting SSPI login")
|
||||||
|
}
|
||||||
|
|
||||||
|
l.SSPI, err = auth.InitialBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.OptionFlags2 |= fIntSecurity
|
||||||
|
return l, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Default to SQL server authentication with user and password
|
||||||
|
l.UserName = p.user
|
||||||
|
l.Password = p.password
|
||||||
|
}
|
||||||
|
|
||||||
|
return l, nil
|
||||||
|
}
|
||||||
|
|
||||||
func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) {
|
func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) {
|
||||||
dialCtx := ctx
|
dialCtx := ctx
|
||||||
if p.dial_timeout > 0 {
|
if p.dial_timeout > 0 {
|
||||||
|
@ -842,24 +1030,24 @@ func connect(ctx context.Context, c *Connector, log optionalLogger, p connectPar
|
||||||
// both instance name and port specified
|
// both instance name and port specified
|
||||||
// when port is specified instance name is not used
|
// when port is specified instance name is not used
|
||||||
// you should not provide instance name when you provide port
|
// you should not provide instance name when you provide port
|
||||||
log.Println("WARN: You specified both instance name and port in the connection string, port will be used and instance name will be ignored");
|
log.Println("WARN: You specified both instance name and port in the connection string, port will be used and instance name will be ignored")
|
||||||
}
|
}
|
||||||
if p.instance != "" && p.port == 0 {
|
if p.instance != "" && p.port == 0 {
|
||||||
p.instance = strings.ToUpper(p.instance)
|
p.instance = strings.ToUpper(p.instance)
|
||||||
d := c.getDialer(&p)
|
d := c.getDialer(&p)
|
||||||
instances, err := getInstances(dialCtx, d, p.host)
|
instances, err := getInstances(dialCtx, d, p.host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Unable to get instances from Sql Server Browser on host %v: %v"
|
f := "unable to get instances from Sql Server Browser on host %v: %v"
|
||||||
return nil, fmt.Errorf(f, p.host, err.Error())
|
return nil, fmt.Errorf(f, p.host, err.Error())
|
||||||
}
|
}
|
||||||
strport, ok := instances[p.instance]["tcp"]
|
strport, ok := instances[p.instance]["tcp"]
|
||||||
if !ok {
|
if !ok {
|
||||||
f := "No instance matching '%v' returned from host '%v'"
|
f := "no instance matching '%v' returned from host '%v'"
|
||||||
return nil, fmt.Errorf(f, p.instance, p.host)
|
return nil, fmt.Errorf(f, p.instance, p.host)
|
||||||
}
|
}
|
||||||
port, err := strconv.ParseUint(strport, 0, 16)
|
port, err := strconv.ParseUint(strport, 0, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Invalid tcp port returned from Sql Server Browser '%v': %v"
|
f := "invalid tcp port returned from Sql Server Browser '%v': %v"
|
||||||
return nil, fmt.Errorf(f, strport, err.Error())
|
return nil, fmt.Errorf(f, strport, err.Error())
|
||||||
}
|
}
|
||||||
p.port = port
|
p.port = port
|
||||||
|
@ -880,25 +1068,14 @@ initiate_connection:
|
||||||
logFlags: p.logFlags,
|
logFlags: p.logFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
instance_buf := []byte(p.instance)
|
fedAuth := &featureExtFedAuth{
|
||||||
instance_buf = append(instance_buf, 0) // zero terminate instance name
|
FedAuthLibrary: p.fedAuthLibrary,
|
||||||
var encrypt byte
|
ADALWorkflow: p.fedAuthADALWorkflow,
|
||||||
if p.disableEncryption {
|
|
||||||
encrypt = encryptNotSup
|
|
||||||
} else if p.encrypt {
|
|
||||||
encrypt = encryptOn
|
|
||||||
} else {
|
|
||||||
encrypt = encryptOff
|
|
||||||
}
|
|
||||||
fields := map[uint8][]byte{
|
|
||||||
preloginVERSION: {0, 0, 0, 0, 0, 0},
|
|
||||||
preloginENCRYPTION: {encrypt},
|
|
||||||
preloginINSTOPT: instance_buf,
|
|
||||||
preloginTHREADID: {0, 0, 0, 0},
|
|
||||||
preloginMARS: {0}, // MARS disabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = writePrelogin(outbuf, fields)
|
fields := preparePreloginFields(p, fedAuth)
|
||||||
|
|
||||||
|
err = writePrelogin(packPrelogin, outbuf, fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -908,13 +1085,9 @@ initiate_connection:
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptBytes, ok := fields[preloginENCRYPTION]
|
encrypt, err := interpretPreloginResponse(p, fedAuth, fields)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Encrypt negotiation failed")
|
return nil, err
|
||||||
}
|
|
||||||
encrypt = encryptBytes[0]
|
|
||||||
if p.encrypt && (encrypt == encryptNotSup || encrypt == encryptOff) {
|
|
||||||
return nil, fmt.Errorf("Server does not support encryption")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if encrypt != encryptNotSup {
|
if encrypt != encryptNotSup {
|
||||||
|
@ -922,7 +1095,7 @@ initiate_connection:
|
||||||
if p.certificate != "" {
|
if p.certificate != "" {
|
||||||
pem, err := ioutil.ReadFile(p.certificate)
|
pem, err := ioutil.ReadFile(p.certificate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Cannot read certificate %q: %v", p.certificate, err)
|
return nil, fmt.Errorf("cannot read certificate %q: %v", p.certificate, err)
|
||||||
}
|
}
|
||||||
certs := x509.NewCertPool()
|
certs := x509.NewCertPool()
|
||||||
certs.AppendCertsFromPEM(pem)
|
certs.AppendCertsFromPEM(pem)
|
||||||
|
@ -954,54 +1127,46 @@ initiate_connection:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
login := login{
|
|
||||||
TDSVersion: verTDS74,
|
|
||||||
PacketSize: uint32(outbuf.PackageSize()),
|
|
||||||
Database: p.database,
|
|
||||||
OptionFlags2: fODBC, // to get unlimited TEXTSIZE
|
|
||||||
HostName: p.workstation,
|
|
||||||
ServerName: p.host,
|
|
||||||
AppName: p.appname,
|
|
||||||
TypeFlags: p.typeFlags,
|
|
||||||
}
|
|
||||||
auth, authOk := getAuth(p.user, p.password, p.serverSPN, p.workstation)
|
auth, authOk := getAuth(p.user, p.password, p.serverSPN, p.workstation)
|
||||||
switch {
|
if authOk {
|
||||||
case p.fedAuthAccessToken != "": // accesstoken ignores user/password
|
|
||||||
featurext := &featureExtFedAuthSTS{
|
|
||||||
FedAuthEcho: len(fields[preloginFEDAUTHREQUIRED]) > 0 && fields[preloginFEDAUTHREQUIRED][0] == 1,
|
|
||||||
FedAuthToken: p.fedAuthAccessToken,
|
|
||||||
Nonce: fields[preloginNONCEOPT],
|
|
||||||
}
|
|
||||||
login.FeatureExt.Add(featurext)
|
|
||||||
case authOk:
|
|
||||||
login.SSPI, err = auth.InitialBytes()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
login.OptionFlags2 |= fIntSecurity
|
|
||||||
defer auth.Free()
|
defer auth.Free()
|
||||||
default:
|
} else {
|
||||||
login.UserName = p.user
|
auth = nil
|
||||||
login.Password = p.password
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
login, err := prepareLogin(ctx, c, p, log, auth, fedAuth, uint32(outbuf.PackageSize()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
err = sendLogin(outbuf, login)
|
err = sendLogin(outbuf, login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// processing login response
|
// Loop until a packet containing a login acknowledgement is received.
|
||||||
success := false
|
// SSPI and federated authentication scenarios may require multiple
|
||||||
for {
|
// packet exchanges to complete the login sequence.
|
||||||
tokchan := make(chan tokenStruct, 5)
|
for loginAck := false; !loginAck; {
|
||||||
go processResponse(context.Background(), &sess, tokchan, nil)
|
reader := startReading(&sess, ctx, nil)
|
||||||
for tok := range tokchan {
|
|
||||||
|
for {
|
||||||
|
tok, err := reader.nextToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if tok == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
switch token := tok.(type) {
|
switch token := tok.(type) {
|
||||||
case sspiMsg:
|
case sspiMsg:
|
||||||
sspi_msg, err := auth.NextBytes(token)
|
sspi_msg, err := auth.NextBytes(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if sspi_msg != nil && len(sspi_msg) > 0 {
|
if len(sspi_msg) > 0 {
|
||||||
outbuf.BeginPacket(packSSPIMessage, false)
|
outbuf.BeginPacket(packSSPIMessage, false)
|
||||||
_, err = outbuf.Write(sspi_msg)
|
_, err = outbuf.Write(sspi_msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1013,23 +1178,41 @@ initiate_connection:
|
||||||
}
|
}
|
||||||
sspi_msg = nil
|
sspi_msg = nil
|
||||||
}
|
}
|
||||||
|
// TODO: for Live ID authentication it may be necessary to
|
||||||
|
// compare fedAuth.Nonce == token.Nonce and keep track of signature
|
||||||
|
//case fedAuthAckStruct:
|
||||||
|
//fedAuth.Signature = token.Signature
|
||||||
|
case fedAuthInfoStruct:
|
||||||
|
// For ADAL workflows this contains the STS URL and server SPN.
|
||||||
|
// If received outside of an ADAL workflow, ignore.
|
||||||
|
if c == nil || c.adalTokenProvider == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request the AD token given the server SPN and STS URL
|
||||||
|
fedAuth.FedAuthToken, err = c.adalTokenProvider(ctx, token.ServerSPN, token.STSURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now need to send the token as a FEDINFO packet
|
||||||
|
err = sendFedAuthInfo(outbuf, fedAuth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
case loginAckStruct:
|
case loginAckStruct:
|
||||||
success = true
|
|
||||||
sess.loginAck = token
|
sess.loginAck = token
|
||||||
case error:
|
loginAck = true
|
||||||
return nil, fmt.Errorf("Login error: %s", token.Error())
|
|
||||||
case doneStruct:
|
case doneStruct:
|
||||||
if token.isError() {
|
if token.isError() {
|
||||||
return nil, fmt.Errorf("Login error: %s", token.getError())
|
return nil, fmt.Errorf("login error: %s", token.getError())
|
||||||
}
|
}
|
||||||
goto loginEnd
|
case error:
|
||||||
|
return nil, fmt.Errorf("login error: %s", token.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loginEnd:
|
|
||||||
if !success {
|
|
||||||
return nil, fmt.Errorf("Login failed")
|
|
||||||
}
|
|
||||||
if sess.routedServer != "" {
|
if sess.routedServer != "" {
|
||||||
toconn.Close()
|
toconn.Close()
|
||||||
p.host = sess.routedServer
|
p.host = sess.routedServer
|
||||||
|
@ -1041,3 +1224,9 @@ loginEnd:
|
||||||
}
|
}
|
||||||
return &sess, nil
|
return &sess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sess *tdsSession) setReturnStatus(status ReturnStatus) {
|
||||||
|
if sess.returnStatus != nil {
|
||||||
|
*sess.returnStatus = status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,12 +6,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"io/ioutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate stringer -type token
|
//go:generate go run golang.org/x/tools/cmd/stringer -type token
|
||||||
|
|
||||||
type token byte
|
type token byte
|
||||||
|
|
||||||
|
@ -29,6 +28,7 @@ const (
|
||||||
tokenNbcRow token = 210 // 0xd2
|
tokenNbcRow token = 210 // 0xd2
|
||||||
tokenEnvChange token = 227 // 0xE3
|
tokenEnvChange token = 227 // 0xE3
|
||||||
tokenSSPI token = 237 // 0xED
|
tokenSSPI token = 237 // 0xED
|
||||||
|
tokenFedAuthInfo token = 238 // 0xEE
|
||||||
tokenDone token = 253 // 0xFD
|
tokenDone token = 253 // 0xFD
|
||||||
tokenDoneProc token = 254
|
tokenDoneProc token = 254
|
||||||
tokenDoneInProc token = 255
|
tokenDoneInProc token = 255
|
||||||
|
@ -70,6 +70,11 @@ const (
|
||||||
envRouting = 20
|
envRouting = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
fedAuthInfoSTSURL = 0x01
|
||||||
|
fedAuthInfoSPN = 0x02
|
||||||
|
)
|
||||||
|
|
||||||
// COLMETADATA flags
|
// COLMETADATA flags
|
||||||
// https://msdn.microsoft.com/en-us/library/dd357363.aspx
|
// https://msdn.microsoft.com/en-us/library/dd357363.aspx
|
||||||
const (
|
const (
|
||||||
|
@ -105,26 +110,6 @@ func (d doneStruct) getError() Error {
|
||||||
|
|
||||||
type doneInProcStruct doneStruct
|
type doneInProcStruct doneStruct
|
||||||
|
|
||||||
var doneFlags2str = map[uint16]string{
|
|
||||||
doneFinal: "final",
|
|
||||||
doneMore: "more",
|
|
||||||
doneError: "error",
|
|
||||||
doneInxact: "inxact",
|
|
||||||
doneCount: "count",
|
|
||||||
doneAttn: "attn",
|
|
||||||
doneSrvError: "srverror",
|
|
||||||
}
|
|
||||||
|
|
||||||
func doneFlags2Str(flags uint16) string {
|
|
||||||
strs := make([]string, 0, len(doneFlags2str))
|
|
||||||
for flag, tag := range doneFlags2str {
|
|
||||||
if flags&flag != 0 {
|
|
||||||
strs = append(strs, tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(strs, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ENVCHANGE stream
|
// ENVCHANGE stream
|
||||||
// http://msdn.microsoft.com/en-us/library/dd303449.aspx
|
// http://msdn.microsoft.com/en-us/library/dd303449.aspx
|
||||||
func processEnvChg(sess *tdsSession) {
|
func processEnvChg(sess *tdsSession) {
|
||||||
|
@ -380,9 +365,8 @@ func processEnvChg(sess *tdsSession) {
|
||||||
default:
|
default:
|
||||||
// ignore rest of records because we don't know how to skip those
|
// ignore rest of records because we don't know how to skip those
|
||||||
sess.log.Printf("WARN: Unknown ENVCHANGE record detected with type id = %d\n", envtype)
|
sess.log.Printf("WARN: Unknown ENVCHANGE record detected with type id = %d\n", envtype)
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +409,78 @@ func parseSSPIMsg(r *tdsBuffer) sspiMsg {
|
||||||
return sspiMsg(buf)
|
return sspiMsg(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fedAuthInfoStruct struct {
|
||||||
|
STSURL string
|
||||||
|
ServerSPN string
|
||||||
|
}
|
||||||
|
|
||||||
|
type fedAuthInfoOpt struct {
|
||||||
|
fedAuthInfoID byte
|
||||||
|
dataLength, dataOffset uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFedAuthInfo(r *tdsBuffer) fedAuthInfoStruct {
|
||||||
|
size := r.uint32()
|
||||||
|
|
||||||
|
var STSURL, SPN string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Each fedAuthInfoOpt is one byte to indicate the info ID,
|
||||||
|
// then a four byte offset and a four byte length.
|
||||||
|
count := r.uint32()
|
||||||
|
offset := uint32(4)
|
||||||
|
opts := make([]fedAuthInfoOpt, count)
|
||||||
|
|
||||||
|
for i := uint32(0); i < count; i++ {
|
||||||
|
fedAuthInfoID := r.byte()
|
||||||
|
dataLength := r.uint32()
|
||||||
|
dataOffset := r.uint32()
|
||||||
|
offset += 1 + 4 + 4
|
||||||
|
|
||||||
|
opts[i] = fedAuthInfoOpt{
|
||||||
|
fedAuthInfoID: fedAuthInfoID,
|
||||||
|
dataLength: dataLength,
|
||||||
|
dataOffset: dataOffset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make([]byte, size-offset)
|
||||||
|
r.ReadFull(data)
|
||||||
|
|
||||||
|
for i := uint32(0); i < count; i++ {
|
||||||
|
if opts[i].dataOffset < offset {
|
||||||
|
badStreamPanicf("Fed auth info opt stated data offset %d is before data begins in packet at %d",
|
||||||
|
opts[i].dataOffset, offset)
|
||||||
|
// returns via panic
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts[i].dataOffset+opts[i].dataLength > size {
|
||||||
|
badStreamPanicf("Fed auth info opt stated data length %d added to stated offset exceeds size of packet %d",
|
||||||
|
opts[i].dataOffset+opts[i].dataLength, size)
|
||||||
|
// returns via panic
|
||||||
|
}
|
||||||
|
|
||||||
|
optData := data[opts[i].dataOffset-offset : opts[i].dataOffset-offset+opts[i].dataLength]
|
||||||
|
switch opts[i].fedAuthInfoID {
|
||||||
|
case fedAuthInfoSTSURL:
|
||||||
|
STSURL, err = ucs22str(optData)
|
||||||
|
case fedAuthInfoSPN:
|
||||||
|
SPN, err = ucs22str(optData)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("Unexpected fed auth info opt ID %d", int(opts[i].fedAuthInfoID))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
badStreamPanic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fedAuthInfoStruct{
|
||||||
|
STSURL: STSURL,
|
||||||
|
ServerSPN: SPN,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type loginAckStruct struct {
|
type loginAckStruct struct {
|
||||||
Interface uint8
|
Interface uint8
|
||||||
TDSVersion uint32
|
TDSVersion uint32
|
||||||
|
@ -449,19 +505,43 @@ func parseLoginAck(r *tdsBuffer) loginAckStruct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/2eb82f8e-11f0-46dc-b42d-27302fa4701a
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/2eb82f8e-11f0-46dc-b42d-27302fa4701a
|
||||||
func parseFeatureExtAck(r *tdsBuffer) {
|
type fedAuthAckStruct struct {
|
||||||
// at most 1 featureAck per feature in featureExt
|
Nonce []byte
|
||||||
// go-mssqldb will add at most 1 feature, the spec defines 7 different features
|
Signature []byte
|
||||||
for i := 0; i < 8; i++ {
|
}
|
||||||
featureID := r.byte() // FeatureID
|
|
||||||
if featureID == 0xff {
|
func parseFeatureExtAck(r *tdsBuffer) map[byte]interface{} {
|
||||||
return
|
ack := map[byte]interface{}{}
|
||||||
|
|
||||||
|
for feature := r.byte(); feature != featExtTERMINATOR; feature = r.byte() {
|
||||||
|
length := r.uint32()
|
||||||
|
|
||||||
|
switch feature {
|
||||||
|
case featExtFEDAUTH:
|
||||||
|
// In theory we need to know the federated authentication library to
|
||||||
|
// know how to parse, but the alternatives provide compatible structures.
|
||||||
|
fedAuthAck := fedAuthAckStruct{}
|
||||||
|
if length >= 32 {
|
||||||
|
fedAuthAck.Nonce = make([]byte, 32)
|
||||||
|
r.ReadFull(fedAuthAck.Nonce)
|
||||||
|
length -= 32
|
||||||
|
}
|
||||||
|
if length >= 32 {
|
||||||
|
fedAuthAck.Signature = make([]byte, 32)
|
||||||
|
r.ReadFull(fedAuthAck.Signature)
|
||||||
|
length -= 32
|
||||||
|
}
|
||||||
|
ack[feature] = fedAuthAck
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip unprocessed bytes
|
||||||
|
if length > 0 {
|
||||||
|
io.CopyN(ioutil.Discard, r, int64(length))
|
||||||
}
|
}
|
||||||
size := r.uint32() // FeatureAckDataLen
|
|
||||||
d := make([]byte, size)
|
|
||||||
r.ReadFull(d)
|
|
||||||
}
|
}
|
||||||
panic("parsed more than 7 featureAck's, protocol implementation error?")
|
|
||||||
|
return ack
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/dd357363.aspx
|
// http://msdn.microsoft.com/en-us/library/dd357363.aspx
|
||||||
|
@ -579,7 +659,7 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
||||||
}
|
}
|
||||||
var columns []columnStruct
|
var columns []columnStruct
|
||||||
errs := make([]Error, 0, 5)
|
errs := make([]Error, 0, 5)
|
||||||
for {
|
for tokens := 0; ; tokens += 1 {
|
||||||
token := token(sess.buf.byte())
|
token := token(sess.buf.byte())
|
||||||
if sess.logFlags&logDebug != 0 {
|
if sess.logFlags&logDebug != 0 {
|
||||||
sess.log.Printf("got token %v", token)
|
sess.log.Printf("got token %v", token)
|
||||||
|
@ -588,6 +668,9 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
||||||
case tokenSSPI:
|
case tokenSSPI:
|
||||||
ch <- parseSSPIMsg(sess.buf)
|
ch <- parseSSPIMsg(sess.buf)
|
||||||
return
|
return
|
||||||
|
case tokenFedAuthInfo:
|
||||||
|
ch <- parseFedAuthInfo(sess.buf)
|
||||||
|
return
|
||||||
case tokenReturnStatus:
|
case tokenReturnStatus:
|
||||||
returnStatus := parseReturnStatus(sess.buf)
|
returnStatus := parseReturnStatus(sess.buf)
|
||||||
ch <- returnStatus
|
ch <- returnStatus
|
||||||
|
@ -595,7 +678,8 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
||||||
loginAck := parseLoginAck(sess.buf)
|
loginAck := parseLoginAck(sess.buf)
|
||||||
ch <- loginAck
|
ch <- loginAck
|
||||||
case tokenFeatureExtAck:
|
case tokenFeatureExtAck:
|
||||||
parseFeatureExtAck(sess.buf)
|
featureExtAck := parseFeatureExtAck(sess.buf)
|
||||||
|
ch <- featureExtAck
|
||||||
case tokenOrder:
|
case tokenOrder:
|
||||||
order := parseOrder(sess.buf)
|
order := parseOrder(sess.buf)
|
||||||
ch <- order
|
ch <- order
|
||||||
|
@ -670,158 +754,137 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type parseRespIter byte
|
type tokenProcessor struct {
|
||||||
|
tokChan chan tokenStruct
|
||||||
const (
|
ctx context.Context
|
||||||
parseRespIterContinue parseRespIter = iota // Continue parsing current token.
|
sess *tdsSession
|
||||||
parseRespIterNext // Fetch the next token.
|
outs map[string]interface{}
|
||||||
parseRespIterDone // Done with parsing the response.
|
lastRow []interface{}
|
||||||
)
|
rowCount int64
|
||||||
|
firstError error
|
||||||
type parseRespState byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
parseRespStateNormal parseRespState = iota // Normal response state.
|
|
||||||
parseRespStateCancel // Query is canceled, wait for server to confirm.
|
|
||||||
parseRespStateClosing // Waiting for tokens to come through.
|
|
||||||
)
|
|
||||||
|
|
||||||
type parseResp struct {
|
|
||||||
sess *tdsSession
|
|
||||||
ctxDone <-chan struct{}
|
|
||||||
state parseRespState
|
|
||||||
cancelError error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *parseResp) sendAttention(ch chan tokenStruct) parseRespIter {
|
func startReading(sess *tdsSession, ctx context.Context, outs map[string]interface{}) *tokenProcessor {
|
||||||
if err := sendAttention(ts.sess.buf); err != nil {
|
tokChan := make(chan tokenStruct, 5)
|
||||||
ts.dlogf("failed to send attention signal %v", err)
|
go processSingleResponse(sess, tokChan, outs)
|
||||||
ch <- err
|
return &tokenProcessor{
|
||||||
return parseRespIterDone
|
tokChan: tokChan,
|
||||||
}
|
ctx: ctx,
|
||||||
ts.state = parseRespStateCancel
|
|
||||||
return parseRespIterContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *parseResp) dlog(msg string) {
|
|
||||||
// logging from goroutine is disabled to prevent
|
|
||||||
// data race detection from firing
|
|
||||||
// The race is probably happening when
|
|
||||||
// test logger changes between tests.
|
|
||||||
/*if ts.sess.logFlags&logDebug != 0 {
|
|
||||||
ts.sess.log.Println(msg)
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
func (ts *parseResp) dlogf(f string, v ...interface{}) {
|
|
||||||
/*if ts.sess.logFlags&logDebug != 0 {
|
|
||||||
ts.sess.log.Printf(f, v...)
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *parseResp) iter(ctx context.Context, ch chan tokenStruct, tokChan chan tokenStruct) parseRespIter {
|
|
||||||
switch ts.state {
|
|
||||||
default:
|
|
||||||
panic("unknown state")
|
|
||||||
case parseRespStateNormal:
|
|
||||||
select {
|
|
||||||
case tok, ok := <-tokChan:
|
|
||||||
if !ok {
|
|
||||||
ts.dlog("response finished")
|
|
||||||
return parseRespIterDone
|
|
||||||
}
|
|
||||||
if err, ok := tok.(net.Error); ok && err.Timeout() {
|
|
||||||
ts.cancelError = err
|
|
||||||
ts.dlog("got timeout error, sending attention signal to server")
|
|
||||||
return ts.sendAttention(ch)
|
|
||||||
}
|
|
||||||
// Pass the token along.
|
|
||||||
ch <- tok
|
|
||||||
return parseRespIterContinue
|
|
||||||
|
|
||||||
case <-ts.ctxDone:
|
|
||||||
ts.ctxDone = nil
|
|
||||||
ts.dlog("got cancel message, sending attention signal to server")
|
|
||||||
return ts.sendAttention(ch)
|
|
||||||
}
|
|
||||||
case parseRespStateCancel: // Read all responses until a DONE or error is received.Auth
|
|
||||||
select {
|
|
||||||
case tok, ok := <-tokChan:
|
|
||||||
if !ok {
|
|
||||||
ts.dlog("response finished but waiting for attention ack")
|
|
||||||
return parseRespIterNext
|
|
||||||
}
|
|
||||||
switch tok := tok.(type) {
|
|
||||||
default:
|
|
||||||
// Ignore all other tokens while waiting.
|
|
||||||
// The TDS spec says other tokens may arrive after an attention
|
|
||||||
// signal is sent. Ignore these tokens and continue looking for
|
|
||||||
// a DONE with attention confirm mark.
|
|
||||||
case doneStruct:
|
|
||||||
if tok.Status&doneAttn != 0 {
|
|
||||||
ts.dlog("got cancellation confirmation from server")
|
|
||||||
if ts.cancelError != nil {
|
|
||||||
ch <- ts.cancelError
|
|
||||||
ts.cancelError = nil
|
|
||||||
} else {
|
|
||||||
ch <- ctx.Err()
|
|
||||||
}
|
|
||||||
return parseRespIterDone
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an error happens during cancel, pass it along and just stop.
|
|
||||||
// We are uncertain to receive more tokens.
|
|
||||||
case error:
|
|
||||||
ch <- tok
|
|
||||||
ts.state = parseRespStateClosing
|
|
||||||
}
|
|
||||||
return parseRespIterContinue
|
|
||||||
case <-ts.ctxDone:
|
|
||||||
ts.ctxDone = nil
|
|
||||||
ts.state = parseRespStateClosing
|
|
||||||
return parseRespIterContinue
|
|
||||||
}
|
|
||||||
case parseRespStateClosing: // Wait for current token chan to close.
|
|
||||||
if _, ok := <-tokChan; !ok {
|
|
||||||
ts.dlog("response finished")
|
|
||||||
return parseRespIterDone
|
|
||||||
}
|
|
||||||
return parseRespIterContinue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func processResponse(ctx context.Context, sess *tdsSession, ch chan tokenStruct, outs map[string]interface{}) {
|
|
||||||
ts := &parseResp{
|
|
||||||
sess: sess,
|
sess: sess,
|
||||||
ctxDone: ctx.Done(),
|
outs: outs,
|
||||||
}
|
}
|
||||||
defer func() {
|
}
|
||||||
// Ensure any remaining error is piped through
|
|
||||||
// or the query may look like it executed when it actually failed.
|
|
||||||
if ts.cancelError != nil {
|
|
||||||
ch <- ts.cancelError
|
|
||||||
ts.cancelError = nil
|
|
||||||
}
|
|
||||||
close(ch)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Loop over multiple responses.
|
func (t *tokenProcessor) iterateResponse() error {
|
||||||
for {
|
for {
|
||||||
ts.dlog("initiating response reading")
|
tok, err := t.nextToken()
|
||||||
|
if err == nil {
|
||||||
tokChan := make(chan tokenStruct)
|
if tok == nil {
|
||||||
go processSingleResponse(sess, tokChan, outs)
|
return t.firstError
|
||||||
|
} else {
|
||||||
// Loop over multiple tokens in response.
|
switch token := tok.(type) {
|
||||||
tokensLoop:
|
case []columnStruct:
|
||||||
for {
|
t.sess.columns = token
|
||||||
switch ts.iter(ctx, ch, tokChan) {
|
case []interface{}:
|
||||||
case parseRespIterContinue:
|
t.lastRow = token
|
||||||
// Nothing, continue to next token.
|
case doneInProcStruct:
|
||||||
case parseRespIterNext:
|
if token.Status&doneCount != 0 {
|
||||||
break tokensLoop
|
t.rowCount += int64(token.RowCount)
|
||||||
case parseRespIterDone:
|
}
|
||||||
return
|
case doneStruct:
|
||||||
|
if token.Status&doneCount != 0 {
|
||||||
|
t.rowCount += int64(token.RowCount)
|
||||||
|
}
|
||||||
|
if token.isError() && t.firstError == nil {
|
||||||
|
t.firstError = token.getError()
|
||||||
|
}
|
||||||
|
case ReturnStatus:
|
||||||
|
t.sess.setReturnStatus(token)
|
||||||
|
/*case error:
|
||||||
|
if resultError == nil {
|
||||||
|
resultError = token
|
||||||
|
}*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t tokenProcessor) nextToken() (tokenStruct, error) {
|
||||||
|
// we do this separate non-blocking check on token channel to
|
||||||
|
// prioritize it over cancellation channel
|
||||||
|
select {
|
||||||
|
case tok, more := <-t.tokChan:
|
||||||
|
err, more := tok.(error)
|
||||||
|
if more {
|
||||||
|
// this is an error and not a token
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return tok, nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// there are no tokens on the channel, will need to wait
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case tok, more := <-t.tokChan:
|
||||||
|
if more {
|
||||||
|
err, ok := tok.(error)
|
||||||
|
if ok {
|
||||||
|
// this is an error and not a token
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return tok, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// completed reading response
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
case <-t.ctx.Done():
|
||||||
|
if err := sendAttention(t.sess.buf); err != nil {
|
||||||
|
// unable to send attention, current connection is bad
|
||||||
|
// notify caller and close channel
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// now the server should send cancellation confirmation
|
||||||
|
// it is possible that we already received full response
|
||||||
|
// just before we sent cancellation request
|
||||||
|
// in this case current response would not contain confirmation
|
||||||
|
// and we would need to read one more response
|
||||||
|
|
||||||
|
// first lets finish reading current response and look
|
||||||
|
// for confirmation in it
|
||||||
|
if readCancelConfirmation(t.tokChan) {
|
||||||
|
// we got confirmation in current response
|
||||||
|
return nil, t.ctx.Err()
|
||||||
|
}
|
||||||
|
// we did not get cancellation confirmation in the current response
|
||||||
|
// read one more response, it must be there
|
||||||
|
t.tokChan = make(chan tokenStruct, 5)
|
||||||
|
go processSingleResponse(t.sess, t.tokChan, t.outs)
|
||||||
|
if readCancelConfirmation(t.tokChan) {
|
||||||
|
return nil, t.ctx.Err()
|
||||||
|
}
|
||||||
|
// we did not get cancellation confirmation, something is not
|
||||||
|
// right, this connection is not usable anymore
|
||||||
|
return nil, errors.New("did not get cancellation confirmation from the server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readCancelConfirmation(tokChan chan tokenStruct) bool {
|
||||||
|
for tok := range tokChan {
|
||||||
|
switch tok := tok.(type) {
|
||||||
|
default:
|
||||||
|
// just skip token
|
||||||
|
case doneStruct:
|
||||||
|
if tok.Status&doneAttn != 0 {
|
||||||
|
// got cancellation confirmation, exit
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -1,29 +1,24 @@
|
||||||
// Code generated by "stringer -type token"; DO NOT EDIT
|
// Code generated by "stringer -type token"; DO NOT EDIT.
|
||||||
|
|
||||||
package mssql
|
package mssql
|
||||||
|
|
||||||
import "fmt"
|
import "strconv"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_token_name_0 = "tokenReturnStatus"
|
_token_name_0 = "tokenReturnStatus"
|
||||||
_token_name_1 = "tokenColMetadata"
|
_token_name_1 = "tokenColMetadata"
|
||||||
_token_name_2 = "tokenOrdertokenErrortokenInfo"
|
_token_name_2 = "tokenOrdertokenErrortokenInfotokenReturnValuetokenLoginAcktokenFeatureExtAck"
|
||||||
_token_name_3 = "tokenLoginAck"
|
_token_name_3 = "tokenRowtokenNbcRow"
|
||||||
_token_name_4 = "tokenRowtokenNbcRow"
|
_token_name_4 = "tokenEnvChange"
|
||||||
_token_name_5 = "tokenEnvChange"
|
_token_name_5 = "tokenSSPItokenFedAuthInfo"
|
||||||
_token_name_6 = "tokenSSPI"
|
_token_name_6 = "tokenDonetokenDoneProctokenDoneInProc"
|
||||||
_token_name_7 = "tokenDonetokenDoneProctokenDoneInProc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_token_index_0 = [...]uint8{0, 17}
|
_token_index_2 = [...]uint8{0, 10, 20, 29, 45, 58, 76}
|
||||||
_token_index_1 = [...]uint8{0, 16}
|
_token_index_3 = [...]uint8{0, 8, 19}
|
||||||
_token_index_2 = [...]uint8{0, 10, 20, 29}
|
_token_index_5 = [...]uint8{0, 9, 25}
|
||||||
_token_index_3 = [...]uint8{0, 13}
|
_token_index_6 = [...]uint8{0, 9, 22, 37}
|
||||||
_token_index_4 = [...]uint8{0, 8, 19}
|
|
||||||
_token_index_5 = [...]uint8{0, 14}
|
|
||||||
_token_index_6 = [...]uint8{0, 9}
|
|
||||||
_token_index_7 = [...]uint8{0, 9, 22, 37}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i token) String() string {
|
func (i token) String() string {
|
||||||
|
@ -32,22 +27,21 @@ func (i token) String() string {
|
||||||
return _token_name_0
|
return _token_name_0
|
||||||
case i == 129:
|
case i == 129:
|
||||||
return _token_name_1
|
return _token_name_1
|
||||||
case 169 <= i && i <= 171:
|
case 169 <= i && i <= 174:
|
||||||
i -= 169
|
i -= 169
|
||||||
return _token_name_2[_token_index_2[i]:_token_index_2[i+1]]
|
return _token_name_2[_token_index_2[i]:_token_index_2[i+1]]
|
||||||
case i == 173:
|
|
||||||
return _token_name_3
|
|
||||||
case 209 <= i && i <= 210:
|
case 209 <= i && i <= 210:
|
||||||
i -= 209
|
i -= 209
|
||||||
return _token_name_4[_token_index_4[i]:_token_index_4[i+1]]
|
return _token_name_3[_token_index_3[i]:_token_index_3[i+1]]
|
||||||
case i == 227:
|
case i == 227:
|
||||||
return _token_name_5
|
return _token_name_4
|
||||||
case i == 237:
|
case 237 <= i && i <= 238:
|
||||||
return _token_name_6
|
i -= 237
|
||||||
|
return _token_name_5[_token_index_5[i]:_token_index_5[i+1]]
|
||||||
case 253 <= i && i <= 255:
|
case 253 <= i && i <= 255:
|
||||||
i -= 253
|
i -= 253
|
||||||
return _token_name_7[_token_index_7[i]:_token_index_7[i+1]]
|
return _token_name_6[_token_index_6[i]:_token_index_6[i+1]]
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("token(%d)", i)
|
return "token(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,11 @@ type isoLevel uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
isolationUseCurrent isoLevel = 0
|
isolationUseCurrent isoLevel = 0
|
||||||
isolationReadUncommited = 1
|
isolationReadUncommited isoLevel = 1
|
||||||
isolationReadCommited = 2
|
isolationReadCommited isoLevel = 2
|
||||||
isolationRepeatableRead = 3
|
isolationRepeatableRead isoLevel = 3
|
||||||
isolationSerializable = 4
|
isolationSerializable isoLevel = 4
|
||||||
isolationSnapshot = 5
|
isolationSnapshot isoLevel = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel, name string, resetSession bool) (err error) {
|
func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel, name string, resetSession bool) (err error) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ package mssql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"database/sql"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -97,6 +98,9 @@ func (tvp TVP) encode(schema, name string, columnStr []columnStruct, tvpFieldInd
|
||||||
for columnStrIdx, fieldIdx := range tvpFieldIndexes {
|
for columnStrIdx, fieldIdx := range tvpFieldIndexes {
|
||||||
field := refStr.Field(fieldIdx)
|
field := refStr.Field(fieldIdx)
|
||||||
tvpVal := field.Interface()
|
tvpVal := field.Interface()
|
||||||
|
if tvp.verifyStandardTypeOnNull(buf, tvpVal) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
valOf := reflect.ValueOf(tvpVal)
|
valOf := reflect.ValueOf(tvpVal)
|
||||||
elemKind := field.Kind()
|
elemKind := field.Kind()
|
||||||
if elemKind == reflect.Ptr && valOf.IsNil() {
|
if elemKind == reflect.Ptr && valOf.IsNil() {
|
||||||
|
@ -155,7 +159,7 @@ func (tvp TVP) columnTypes() ([]columnStruct, []int, error) {
|
||||||
defaultValues = append(defaultValues, v.Interface())
|
defaultValues = append(defaultValues, v.Interface())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
defaultValues = append(defaultValues, reflect.Zero(field.Type).Interface())
|
defaultValues = append(defaultValues, tvp.createZeroType(reflect.Zero(field.Type).Interface()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if columnCount-len(tvpFieldIndexes) == columnCount {
|
if columnCount-len(tvpFieldIndexes) == columnCount {
|
||||||
|
@ -209,19 +213,23 @@ func getSchemeAndName(tvpName string) (string, string, error) {
|
||||||
}
|
}
|
||||||
splitVal := strings.Split(tvpName, ".")
|
splitVal := strings.Split(tvpName, ".")
|
||||||
if len(splitVal) > 2 {
|
if len(splitVal) > 2 {
|
||||||
return "", "", errors.New("wrong tvp name")
|
return "", "", ErrorObjectName
|
||||||
}
|
}
|
||||||
|
const (
|
||||||
|
openSquareBrackets = "["
|
||||||
|
closeSquareBrackets = "]"
|
||||||
|
)
|
||||||
if len(splitVal) == 2 {
|
if len(splitVal) == 2 {
|
||||||
res := make([]string, 2)
|
res := make([]string, 2)
|
||||||
for key, value := range splitVal {
|
for key, value := range splitVal {
|
||||||
tmp := strings.Replace(value, "[", "", -1)
|
tmp := strings.Replace(value, openSquareBrackets, "", -1)
|
||||||
tmp = strings.Replace(tmp, "]", "", -1)
|
tmp = strings.Replace(tmp, closeSquareBrackets, "", -1)
|
||||||
res[key] = tmp
|
res[key] = tmp
|
||||||
}
|
}
|
||||||
return res[0], res[1], nil
|
return res[0], res[1], nil
|
||||||
}
|
}
|
||||||
tmp := strings.Replace(splitVal[0], "[", "", -1)
|
tmp := strings.Replace(splitVal[0], openSquareBrackets, "", -1)
|
||||||
tmp = strings.Replace(tmp, "]", "", -1)
|
tmp = strings.Replace(tmp, closeSquareBrackets, "", -1)
|
||||||
|
|
||||||
return "", tmp, nil
|
return "", tmp, nil
|
||||||
}
|
}
|
||||||
|
@ -229,3 +237,56 @@ func getSchemeAndName(tvpName string) (string, string, error) {
|
||||||
func getCountSQLSeparators(str string) int {
|
func getCountSQLSeparators(str string) int {
|
||||||
return strings.Count(str, sqlSeparator)
|
return strings.Count(str, sqlSeparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verify types https://golang.org/pkg/database/sql/
|
||||||
|
func (tvp TVP) createZeroType(fieldVal interface{}) interface{} {
|
||||||
|
const (
|
||||||
|
defaultBool = false
|
||||||
|
defaultFloat64 = float64(0)
|
||||||
|
defaultInt64 = int64(0)
|
||||||
|
defaultString = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
switch fieldVal.(type) {
|
||||||
|
case sql.NullBool:
|
||||||
|
return defaultBool
|
||||||
|
case sql.NullFloat64:
|
||||||
|
return defaultFloat64
|
||||||
|
case sql.NullInt64:
|
||||||
|
return defaultInt64
|
||||||
|
case sql.NullString:
|
||||||
|
return defaultString
|
||||||
|
}
|
||||||
|
return fieldVal
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify types https://golang.org/pkg/database/sql/
|
||||||
|
func (tvp TVP) verifyStandardTypeOnNull(buf *bytes.Buffer, tvpVal interface{}) bool {
|
||||||
|
const (
|
||||||
|
defaultNull = uint8(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
switch val := tvpVal.(type) {
|
||||||
|
case sql.NullBool:
|
||||||
|
if !val.Valid {
|
||||||
|
binary.Write(buf, binary.LittleEndian, defaultNull)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case sql.NullFloat64:
|
||||||
|
if !val.Valid {
|
||||||
|
binary.Write(buf, binary.LittleEndian, defaultNull)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case sql.NullInt64:
|
||||||
|
if !val.Valid {
|
||||||
|
binary.Write(buf, binary.LittleEndian, defaultNull)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case sql.NullString:
|
||||||
|
if !val.Valid {
|
||||||
|
binary.Write(buf, binary.LittleEndian, uint64(_PLP_NULL))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -665,7 +665,7 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
|
||||||
default:
|
default:
|
||||||
buf = bytes.NewBuffer(make([]byte, 0, size))
|
buf = bytes.NewBuffer(make([]byte, 0, size))
|
||||||
}
|
}
|
||||||
for true {
|
for {
|
||||||
chunksize := r.uint32()
|
chunksize := r.uint32()
|
||||||
if chunksize == 0 {
|
if chunksize == 0 {
|
||||||
break
|
break
|
||||||
|
@ -690,6 +690,10 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
|
func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
|
||||||
|
if buf == nil {
|
||||||
|
err = binary.Write(w, binary.LittleEndian, uint64(_PLP_NULL))
|
||||||
|
return
|
||||||
|
}
|
||||||
if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil {
|
if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -807,7 +811,6 @@ func readVarLen(ti *typeInfo, r *tdsBuffer) {
|
||||||
default:
|
default:
|
||||||
badStreamPanicf("Invalid type %d", ti.TypeId)
|
badStreamPanicf("Invalid type %d", ti.TypeId)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeMoney(buf []byte) []byte {
|
func decodeMoney(buf []byte) []byte {
|
||||||
|
@ -834,8 +837,7 @@ func decodeGuid(buf []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
|
func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
|
||||||
var sign uint8
|
sign := buf[0]
|
||||||
sign = buf[0]
|
|
||||||
var dec decimal.Decimal
|
var dec decimal.Decimal
|
||||||
dec.SetPositive(sign != 0)
|
dec.SetPositive(sign != 0)
|
||||||
dec.SetPrec(prec)
|
dec.SetPrec(prec)
|
||||||
|
@ -1187,7 +1189,7 @@ func makeDecl(ti typeInfo) string {
|
||||||
return fmt.Sprintf("char(%d)", ti.Size)
|
return fmt.Sprintf("char(%d)", ti.Size)
|
||||||
case typeBigVarChar, typeVarChar:
|
case typeBigVarChar, typeVarChar:
|
||||||
if ti.Size > 8000 || ti.Size == 0 {
|
if ti.Size > 8000 || ti.Size == 0 {
|
||||||
return fmt.Sprintf("varchar(max)")
|
return "varchar(max)"
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("varchar(%d)", ti.Size)
|
return fmt.Sprintf("varchar(%d)", ti.Size)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
linters-settings:
|
linters-settings:
|
||||||
golint:
|
golint:
|
||||||
min-confidence: 0.3
|
min-confidence: 0.3
|
||||||
|
cyclop:
|
||||||
|
max-complexity: 15
|
||||||
|
package-average: 10
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable:
|
disable:
|
||||||
- exhaustivestruct
|
- exhaustivestruct
|
||||||
- gomnd
|
- gomnd
|
||||||
|
- interfacer
|
||||||
|
- maligned
|
||||||
presets:
|
presets:
|
||||||
- bugs
|
- bugs
|
||||||
- complexity
|
- complexity
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
# Change log
|
# Change log
|
||||||
|
|
||||||
|
## v2.4.2 - 2021-03-21
|
||||||
|
|
||||||
|
- Upgrade google/go-cmp v0.5.5
|
||||||
|
([#105](https://github.com/editorconfig/editorconfig-core-go/pull/105));
|
||||||
|
- Upgrade x/mod v0.4.2
|
||||||
|
([#106](https://github.com/editorconfig/editorconfig-core-go/pull/106)).
|
||||||
|
|
||||||
## v2.4.1 - 2021-02-25
|
## v2.4.1 - 2021-02-25
|
||||||
|
|
||||||
- Fix for Go 1.16 os.IsNotExist wrapping
|
- Fix for Go 1.16 os.IsNotExist wrapping
|
||||||
|
|
|
@ -121,7 +121,7 @@ func (d *Definition) merge(md *Definition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertToIniFile writes the definition into a ini file.
|
// InsertToIniFile writes the definition into a ini file.
|
||||||
func (d *Definition) InsertToIniFile(iniFile *ini.File) { // nolint: funlen,gocognit
|
func (d *Definition) InsertToIniFile(iniFile *ini.File) { // nolint: funlen,gocognit,cyclop
|
||||||
iniSec := iniFile.Section(d.Selector)
|
iniSec := iniFile.Section(d.Selector)
|
||||||
|
|
||||||
for k, v := range d.Raw {
|
for k, v := range d.Raw {
|
||||||
|
|
|
@ -33,7 +33,7 @@ func FnmatchCase(pattern, name string) (bool, error) {
|
||||||
return r.MatchString(name), nil
|
return r.MatchString(name), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func translate(pattern string) string { // nolint: funlen,gocognit,gocyclo
|
func translate(pattern string) string { // nolint: funlen,gocognit,gocyclo,cyclop
|
||||||
index := 0
|
index := 0
|
||||||
pat := []rune(pattern)
|
pat := []rune(pattern)
|
||||||
length := len(pat)
|
length := len(pat)
|
||||||
|
|
|
@ -3,8 +3,8 @@ module github.com/editorconfig/editorconfig-core-go/v2
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/go-cmp v0.5.4
|
github.com/google/go-cmp v0.5.5
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
golang.org/x/mod v0.4.1
|
golang.org/x/mod v0.4.2
|
||||||
gopkg.in/ini.v1 v1.62.0
|
gopkg.in/ini.v1 v1.62.0
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
@ -10,8 +10,8 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||||
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/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
The MIT license.
|
|
||||||
|
|
||||||
Copyright (c) 2014 the go-unsnap-stream authors.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
go-unsnap-stream
|
|
||||||
================
|
|
||||||
|
|
||||||
This is a small golang library for decoding and encoding the snappy *streaming* format, specified here: https://github.com/google/snappy/blob/master/framing_format.txt
|
|
||||||
|
|
||||||
Note that the *streaming or framing format* for snappy is different from snappy itself. Think of it as a train of boxcars: the streaming format breaks your data in chunks, applies snappy to each chunk alone, then puts a thin wrapper around the chunk, and sends it along in turn. You can begin decoding before receiving everything. And memory requirements for decoding are sane.
|
|
||||||
|
|
||||||
Strangely, though the streaming format was first proposed in Go[1][2], it was never upated, and I could not locate any other library for Go that would handle the streaming/framed snappy format. Hence this implementation of the spec. There is a command line tool[3] that has a C implementation, but this is the only Go implementation that I am aware of. The reference for the framing/streaming spec seems to be the python implementation[4].
|
|
||||||
|
|
||||||
Update to the previous paragraph: Horray! Good news: Thanks to @nigeltao, we have since learned that the [github.com/golang/snappy](https://github.com/golang/snappy) package now provides the snappy streaming format too. Even though the type level descriptions are a little misleading because they don't mention that they are for the stream format, the [snappy package header documentation](https://godoc.org/github.com/golang/snappy) points out that the [snappy.Reader](https://godoc.org/github.com/golang/snappy#Reader) and [snappy.Writer](https://godoc.org/github.com/golang/snappy#Writer) types do indeed provide stream (vs block) handling. Although I have not benchmarked, you should probably prefer that package as it will likely be maintained more than I have time to devote, and also perhaps better integrated with the underlying snappy as they share the same repo.
|
|
||||||
|
|
||||||
For binary compatibility with the [python implementation](https://pypi.python.org/pypi/python-snappy) in [4], one could use the C-snappy compressor/decompressor code directly; using github.com/dgryski/go-csnappy. In fact we did this for a while to verify byte-for-byte compatiblity, as the native Go implementation produces slightly different binary compression (still conformant with the standard of course), which made test-diffs harder, and some have complained about it being slower than the C.
|
|
||||||
|
|
||||||
However, while the c-snappy was useful for checking compatibility, it introduced dependencies on external C libraries (both the c-snappy library and the C standard library). Our go binary executable that used the go-unsnap-stream library was no longer standalone, and deployment was painful if not impossible if the target had a different C standard library. So we've gone back to using the snappy-go implementation (entirely in Go) for ease of deployment. See the comments at the top of unsnap.go if you wish to use c-snappy instead.
|
|
||||||
|
|
||||||
[1] https://groups.google.com/forum/#!msg/snappy-compression/qvLNe2cSH9s/R19oBC-p7g4J
|
|
||||||
|
|
||||||
[2] https://codereview.appspot.com/5167058
|
|
||||||
|
|
||||||
[3] https://github.com/kubo/snzip
|
|
||||||
|
|
||||||
[4] https://pypi.python.org/pypi/python-snappy
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,375 +0,0 @@
|
||||||
package unsnap
|
|
||||||
|
|
||||||
// copyright (c) 2014, Jason E. Aten
|
|
||||||
// license: MIT
|
|
||||||
|
|
||||||
// Some text from the Golang standard library doc is adapted and
|
|
||||||
// reproduced in fragments below to document the expected behaviors
|
|
||||||
// of the interface functions Read()/Write()/ReadFrom()/WriteTo() that
|
|
||||||
// are implemented here. Those descriptions (see
|
|
||||||
// http://golang.org/pkg/io/#Reader for example) are
|
|
||||||
// copyright 2010 The Go Authors.
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// FixedSizeRingBuf:
|
|
||||||
//
|
|
||||||
// a fixed-size circular ring buffer. Yes, just what is says.
|
|
||||||
//
|
|
||||||
// We keep a pair of ping/pong buffers so that we can linearize
|
|
||||||
// the circular buffer into a contiguous slice if need be.
|
|
||||||
//
|
|
||||||
// For efficiency, a FixedSizeRingBuf may be vastly preferred to
|
|
||||||
// a bytes.Buffer. The ReadWithoutAdvance(), Advance(), and Adopt()
|
|
||||||
// methods are all non-standard methods written for speed.
|
|
||||||
//
|
|
||||||
// For an I/O heavy application, I have replaced bytes.Buffer with
|
|
||||||
// FixedSizeRingBuf and seen memory consumption go from 8GB to 25MB.
|
|
||||||
// Yes, that is a 300x reduction in memory footprint. Everything ran
|
|
||||||
// faster too.
|
|
||||||
//
|
|
||||||
// Note that Bytes(), while inescapable at times, is expensive: avoid
|
|
||||||
// it if possible. Instead it is better to use the FixedSizeRingBuf.Readable
|
|
||||||
// member to get the number of bytes available. Bytes() is expensive because
|
|
||||||
// it may copy the back and then the front of a wrapped buffer A[Use]
|
|
||||||
// into A[1-Use] in order to get a contiguous slice. If possible use ContigLen()
|
|
||||||
// first to get the size that can be read without copying, Read() that
|
|
||||||
// amount, and then Read() a second time -- to avoid the copy.
|
|
||||||
|
|
||||||
type FixedSizeRingBuf struct {
|
|
||||||
A [2][]byte // a pair of ping/pong buffers. Only one is active.
|
|
||||||
Use int // which A buffer is in active use, 0 or 1
|
|
||||||
N int // MaxViewInBytes, the size of A[0] and A[1] in bytes.
|
|
||||||
Beg int // start of data in A[Use]
|
|
||||||
Readable int // number of bytes available to read in A[Use]
|
|
||||||
|
|
||||||
OneMade bool // lazily instantiate the [1] buffer. If we never call Bytes(),
|
|
||||||
// we may never need it. If OneMade is false, the Use must be = 0.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *FixedSizeRingBuf) Make2ndBuffer() {
|
|
||||||
if b.OneMade {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.A[1] = make([]byte, b.N, b.N)
|
|
||||||
b.OneMade = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the length of the largest read that we can provide to a contiguous slice
|
|
||||||
// without an extra linearizing copy of all bytes internally.
|
|
||||||
func (b *FixedSizeRingBuf) ContigLen() int {
|
|
||||||
extent := b.Beg + b.Readable
|
|
||||||
firstContigLen := intMin(extent, b.N) - b.Beg
|
|
||||||
return firstContigLen
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFixedSizeRingBuf(maxViewInBytes int) *FixedSizeRingBuf {
|
|
||||||
n := maxViewInBytes
|
|
||||||
r := &FixedSizeRingBuf{
|
|
||||||
Use: 0, // 0 or 1, whichever is actually in use at the moment.
|
|
||||||
// If we are asked for Bytes() and we wrap, linearize into the other.
|
|
||||||
|
|
||||||
N: n,
|
|
||||||
Beg: 0,
|
|
||||||
Readable: 0,
|
|
||||||
OneMade: false,
|
|
||||||
}
|
|
||||||
r.A[0] = make([]byte, n, n)
|
|
||||||
|
|
||||||
// r.A[1] initialized lazily now.
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// from the standard library description of Bytes():
|
|
||||||
// Bytes() returns a slice of the contents of the unread portion of the buffer.
|
|
||||||
// If the caller changes the contents of the
|
|
||||||
// returned slice, the contents of the buffer will change provided there
|
|
||||||
// are no intervening method calls on the Buffer.
|
|
||||||
//
|
|
||||||
func (b *FixedSizeRingBuf) Bytes() []byte {
|
|
||||||
|
|
||||||
extent := b.Beg + b.Readable
|
|
||||||
if extent <= b.N {
|
|
||||||
// we fit contiguously in this buffer without wrapping to the other
|
|
||||||
return b.A[b.Use][b.Beg:(b.Beg + b.Readable)]
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrap into the other buffer
|
|
||||||
b.Make2ndBuffer()
|
|
||||||
|
|
||||||
src := b.Use
|
|
||||||
dest := 1 - b.Use
|
|
||||||
|
|
||||||
n := copy(b.A[dest], b.A[src][b.Beg:])
|
|
||||||
n += copy(b.A[dest][n:], b.A[src][0:(extent%b.N)])
|
|
||||||
|
|
||||||
b.Use = dest
|
|
||||||
b.Beg = 0
|
|
||||||
|
|
||||||
return b.A[b.Use][:n]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read():
|
|
||||||
//
|
|
||||||
// from bytes.Buffer.Read(): Read reads the next len(p) bytes
|
|
||||||
// from the buffer or until the buffer is drained. The return
|
|
||||||
// value n is the number of bytes read. If the buffer has no data
|
|
||||||
// to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
|
|
||||||
//
|
|
||||||
// from the description of the Reader interface,
|
|
||||||
// http://golang.org/pkg/io/#Reader
|
|
||||||
//
|
|
||||||
/*
|
|
||||||
Reader is the interface that wraps the basic Read method.
|
|
||||||
|
|
||||||
Read reads up to len(p) bytes into p. It returns the number
|
|
||||||
of bytes read (0 <= n <= len(p)) and any error encountered.
|
|
||||||
Even if Read returns n < len(p), it may use all of p as scratch
|
|
||||||
space during the call. If some data is available but not
|
|
||||||
len(p) bytes, Read conventionally returns what is available
|
|
||||||
instead of waiting for more.
|
|
||||||
|
|
||||||
When Read encounters an error or end-of-file condition after
|
|
||||||
successfully reading n > 0 bytes, it returns the number of bytes
|
|
||||||
read. It may return the (non-nil) error from the same call or
|
|
||||||
return the error (and n == 0) from a subsequent call. An instance
|
|
||||||
of this general case is that a Reader returning a non-zero number
|
|
||||||
of bytes at the end of the input stream may return
|
|
||||||
either err == EOF or err == nil. The next Read should
|
|
||||||
return 0, EOF regardless.
|
|
||||||
|
|
||||||
Callers should always process the n > 0 bytes returned before
|
|
||||||
considering the error err. Doing so correctly handles I/O errors
|
|
||||||
that happen after reading some bytes and also both of the
|
|
||||||
allowed EOF behaviors.
|
|
||||||
|
|
||||||
Implementations of Read are discouraged from returning a zero
|
|
||||||
byte count with a nil error, and callers should treat that
|
|
||||||
situation as a no-op.
|
|
||||||
*/
|
|
||||||
//
|
|
||||||
|
|
||||||
func (b *FixedSizeRingBuf) Read(p []byte) (n int, err error) {
|
|
||||||
return b.ReadAndMaybeAdvance(p, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// if you want to Read the data and leave it in the buffer, so as
|
|
||||||
// to peek ahead for example.
|
|
||||||
func (b *FixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error) {
|
|
||||||
return b.ReadAndMaybeAdvance(p, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *FixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error) {
|
|
||||||
if len(p) == 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
if b.Readable == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
extent := b.Beg + b.Readable
|
|
||||||
if extent <= b.N {
|
|
||||||
n += copy(p, b.A[b.Use][b.Beg:extent])
|
|
||||||
} else {
|
|
||||||
n += copy(p, b.A[b.Use][b.Beg:b.N])
|
|
||||||
if n < len(p) {
|
|
||||||
n += copy(p[n:], b.A[b.Use][0:(extent%b.N)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if doAdvance {
|
|
||||||
b.Advance(n)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write writes len(p) bytes from p to the underlying data stream.
|
|
||||||
// It returns the number of bytes written from p (0 <= n <= len(p))
|
|
||||||
// and any error encountered that caused the write to stop early.
|
|
||||||
// Write must return a non-nil error if it returns n < len(p).
|
|
||||||
//
|
|
||||||
func (b *FixedSizeRingBuf) Write(p []byte) (n int, err error) {
|
|
||||||
for {
|
|
||||||
if len(p) == 0 {
|
|
||||||
// nothing (left) to copy in; notice we shorten our
|
|
||||||
// local copy p (below) as we read from it.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
writeCapacity := b.N - b.Readable
|
|
||||||
if writeCapacity <= 0 {
|
|
||||||
// we are all full up already.
|
|
||||||
return n, io.ErrShortWrite
|
|
||||||
}
|
|
||||||
if len(p) > writeCapacity {
|
|
||||||
err = io.ErrShortWrite
|
|
||||||
// leave err set and
|
|
||||||
// keep going, write what we can.
|
|
||||||
}
|
|
||||||
|
|
||||||
writeStart := (b.Beg + b.Readable) % b.N
|
|
||||||
|
|
||||||
upperLim := intMin(writeStart+writeCapacity, b.N)
|
|
||||||
|
|
||||||
k := copy(b.A[b.Use][writeStart:upperLim], p)
|
|
||||||
|
|
||||||
n += k
|
|
||||||
b.Readable += k
|
|
||||||
p = p[k:]
|
|
||||||
|
|
||||||
// we can fill from b.A[b.Use][0:something] from
|
|
||||||
// p's remainder, so loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo and ReadFrom avoid intermediate allocation and copies.
|
|
||||||
|
|
||||||
// WriteTo writes data to w until there's no more data to write
|
|
||||||
// or when an error occurs. The return value n is the number of
|
|
||||||
// bytes written. Any error encountered during the write is also returned.
|
|
||||||
func (b *FixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error) {
|
|
||||||
|
|
||||||
if b.Readable == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
extent := b.Beg + b.Readable
|
|
||||||
firstWriteLen := intMin(extent, b.N) - b.Beg
|
|
||||||
secondWriteLen := b.Readable - firstWriteLen
|
|
||||||
if firstWriteLen > 0 {
|
|
||||||
m, e := w.Write(b.A[b.Use][b.Beg:(b.Beg + firstWriteLen)])
|
|
||||||
n += int64(m)
|
|
||||||
b.Advance(m)
|
|
||||||
|
|
||||||
if e != nil {
|
|
||||||
return n, e
|
|
||||||
}
|
|
||||||
// all bytes should have been written, by definition of
|
|
||||||
// Write method in io.Writer
|
|
||||||
if m != firstWriteLen {
|
|
||||||
return n, io.ErrShortWrite
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if secondWriteLen > 0 {
|
|
||||||
m, e := w.Write(b.A[b.Use][0:secondWriteLen])
|
|
||||||
n += int64(m)
|
|
||||||
b.Advance(m)
|
|
||||||
|
|
||||||
if e != nil {
|
|
||||||
return n, e
|
|
||||||
}
|
|
||||||
// all bytes should have been written, by definition of
|
|
||||||
// Write method in io.Writer
|
|
||||||
if m != secondWriteLen {
|
|
||||||
return n, io.ErrShortWrite
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFrom() reads data from r until EOF or error. The return value n
|
|
||||||
// is the number of bytes read. Any error except io.EOF encountered
|
|
||||||
// during the read is also returned.
|
|
||||||
func (b *FixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error) {
|
|
||||||
for {
|
|
||||||
writeCapacity := b.N - b.Readable
|
|
||||||
if writeCapacity <= 0 {
|
|
||||||
// we are all full
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
writeStart := (b.Beg + b.Readable) % b.N
|
|
||||||
upperLim := intMin(writeStart+writeCapacity, b.N)
|
|
||||||
|
|
||||||
m, e := r.Read(b.A[b.Use][writeStart:upperLim])
|
|
||||||
n += int64(m)
|
|
||||||
b.Readable += m
|
|
||||||
if e == io.EOF {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
return n, e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *FixedSizeRingBuf) Reset() {
|
|
||||||
b.Beg = 0
|
|
||||||
b.Readable = 0
|
|
||||||
b.Use = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance(): non-standard, but better than Next(),
|
|
||||||
// because we don't have to unwrap our buffer and pay the cpu time
|
|
||||||
// for the copy that unwrapping may need.
|
|
||||||
// Useful in conjuction/after ReadWithoutAdvance() above.
|
|
||||||
func (b *FixedSizeRingBuf) Advance(n int) {
|
|
||||||
if n <= 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n > b.Readable {
|
|
||||||
n = b.Readable
|
|
||||||
}
|
|
||||||
b.Readable -= n
|
|
||||||
b.Beg = (b.Beg + n) % b.N
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adopt(): non-standard.
|
|
||||||
//
|
|
||||||
// For efficiency's sake, (possibly) take ownership of
|
|
||||||
// already allocated slice offered in me.
|
|
||||||
//
|
|
||||||
// If me is large we will adopt it, and we will potentially then
|
|
||||||
// write to the me buffer.
|
|
||||||
// If we already have a bigger buffer, copy me into the existing
|
|
||||||
// buffer instead.
|
|
||||||
func (b *FixedSizeRingBuf) Adopt(me []byte) {
|
|
||||||
n := len(me)
|
|
||||||
if n > b.N {
|
|
||||||
b.A[0] = me
|
|
||||||
b.OneMade = false
|
|
||||||
b.N = n
|
|
||||||
b.Use = 0
|
|
||||||
b.Beg = 0
|
|
||||||
b.Readable = n
|
|
||||||
} else {
|
|
||||||
// we already have a larger buffer, reuse it.
|
|
||||||
copy(b.A[0], me)
|
|
||||||
b.Use = 0
|
|
||||||
b.Beg = 0
|
|
||||||
b.Readable = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func intMax(a, b int) int {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
} else {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func intMin(a, b int) int {
|
|
||||||
if a < b {
|
|
||||||
return a
|
|
||||||
} else {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the (beg, end] indices of the tailing empty buffer of bytes slice that from that is free for writing.
|
|
||||||
// Note: not guaranteed to be zeroed. At all.
|
|
||||||
func (b *FixedSizeRingBuf) GetEndmostWritable() (beg int, end int) {
|
|
||||||
extent := b.Beg + b.Readable
|
|
||||||
if extent < b.N {
|
|
||||||
return extent, b.N
|
|
||||||
}
|
|
||||||
|
|
||||||
return extent % b.N, b.Beg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: not guaranteed to be zeroed.
|
|
||||||
func (b *FixedSizeRingBuf) GetEndmostWritableSlice() []byte {
|
|
||||||
beg, e := b.GetEndmostWritable()
|
|
||||||
return b.A[b.Use][beg:e]
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
package unsnap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
// no c lib dependency
|
|
||||||
snappy "github.com/golang/snappy"
|
|
||||||
// or, use the C wrapper for speed
|
|
||||||
//snappy "github.com/dgryski/go-csnappy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// add Write() method for SnappyFile (see unsnap.go)
|
|
||||||
|
|
||||||
// reference for snappy framing/streaming format:
|
|
||||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
|
||||||
// ?spec=svn68&r=71
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write writes len(p) bytes from p to the underlying data stream.
|
|
||||||
// It returns the number of bytes written from p (0 <= n <= len(p)) and
|
|
||||||
// any error encountered that caused the write to stop early. Write
|
|
||||||
// must return a non-nil error if it returns n < len(p).
|
|
||||||
//
|
|
||||||
func (sf *SnappyFile) Write(p []byte) (n int, err error) {
|
|
||||||
|
|
||||||
if sf.SnappyEncodeDecodeOff {
|
|
||||||
return sf.Writer.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !sf.Writing {
|
|
||||||
panic("Writing on a read-only SnappyFile")
|
|
||||||
}
|
|
||||||
|
|
||||||
// encoding in snappy can apparently go beyond the original size, beware.
|
|
||||||
// so our buffers must be sized 2*max snappy chunk => 2 * CHUNK_MAX(65536)
|
|
||||||
|
|
||||||
sf.DecBuf.Reset()
|
|
||||||
sf.EncBuf.Reset()
|
|
||||||
|
|
||||||
if !sf.HeaderChunkWritten {
|
|
||||||
sf.HeaderChunkWritten = true
|
|
||||||
_, err = sf.Writer.Write(SnappyStreamHeaderMagic)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var chunk []byte
|
|
||||||
var chunk_type byte
|
|
||||||
var crc uint32
|
|
||||||
|
|
||||||
for len(p) > 0 {
|
|
||||||
|
|
||||||
// chunk points to input p by default, unencoded input.
|
|
||||||
chunk = p[:IntMin(len(p), CHUNK_MAX)]
|
|
||||||
crc = masked_crc32c(chunk)
|
|
||||||
|
|
||||||
writeme := chunk[:]
|
|
||||||
|
|
||||||
// first write to EncBuf, as a temp, in case we want
|
|
||||||
// to discard and send uncompressed instead.
|
|
||||||
compressed_chunk := snappy.Encode(sf.EncBuf.GetEndmostWritableSlice(), chunk)
|
|
||||||
|
|
||||||
if len(compressed_chunk) <= int((1-_COMPRESSION_THRESHOLD)*float64(len(chunk))) {
|
|
||||||
writeme = compressed_chunk
|
|
||||||
chunk_type = _COMPRESSED_CHUNK
|
|
||||||
} else {
|
|
||||||
// keep writeme pointing at original chunk (uncompressed)
|
|
||||||
chunk_type = _UNCOMPRESSED_CHUNK
|
|
||||||
}
|
|
||||||
|
|
||||||
const crc32Sz = 4
|
|
||||||
var tag32 uint32 = uint32(chunk_type) + (uint32(len(writeme)+crc32Sz) << 8)
|
|
||||||
|
|
||||||
err = binary.Write(sf.Writer, binary.LittleEndian, tag32)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = binary.Write(sf.Writer, binary.LittleEndian, crc)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = sf.Writer.Write(writeme)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n += len(chunk)
|
|
||||||
p = p[len(chunk):]
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func IntMin(a int, b int) int {
|
|
||||||
if a < b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
hello_snappy
|
|
Binary file not shown.
|
@ -1,520 +0,0 @@
|
||||||
package unsnap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"hash/crc32"
|
|
||||||
|
|
||||||
snappy "github.com/golang/snappy"
|
|
||||||
// The C library can be used, but this makes the binary dependent
|
|
||||||
// lots of extraneous c-libraries; it is no longer stand-alone. Yuck.
|
|
||||||
//
|
|
||||||
// Therefore we comment out the "dgryski/go-csnappy" path and use the
|
|
||||||
// "github.com/golang/snappy/snappy" above instead. If you are
|
|
||||||
// performance limited and can deal with distributing more libraries,
|
|
||||||
// then this is easy to swap.
|
|
||||||
//
|
|
||||||
// If you swap, note that some of the tests won't pass
|
|
||||||
// because snappy-go produces slightly different (but still
|
|
||||||
// conformant) encodings on some data. Here are bindings
|
|
||||||
// to the C-snappy:
|
|
||||||
// snappy "github.com/dgryski/go-csnappy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SnappyFile: create a drop-in-replacement/wrapper for an *os.File that handles doing the unsnappification online as more is read from it
|
|
||||||
|
|
||||||
type SnappyFile struct {
|
|
||||||
Fname string
|
|
||||||
|
|
||||||
Reader io.Reader
|
|
||||||
Writer io.Writer
|
|
||||||
|
|
||||||
// allow clients to substitute us for an os.File and just switch
|
|
||||||
// off compression if they don't want it.
|
|
||||||
SnappyEncodeDecodeOff bool // if true, we bypass straight to Filep
|
|
||||||
|
|
||||||
EncBuf FixedSizeRingBuf // holds any extra that isn't yet returned, encoded
|
|
||||||
DecBuf FixedSizeRingBuf // holds any extra that isn't yet returned, decoded
|
|
||||||
|
|
||||||
// for writing to stream-framed snappy
|
|
||||||
HeaderChunkWritten bool
|
|
||||||
|
|
||||||
// Sanity check: we can only read, or only write, to one SnappyFile.
|
|
||||||
// EncBuf and DecBuf are used differently in each mode. Verify
|
|
||||||
// that we are consistent with this flag.
|
|
||||||
Writing bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var total int
|
|
||||||
|
|
||||||
// for debugging, show state of buffers
|
|
||||||
func (f *SnappyFile) Dump() {
|
|
||||||
fmt.Printf("EncBuf has length %d and contents:\n%s\n", len(f.EncBuf.Bytes()), string(f.EncBuf.Bytes()))
|
|
||||||
fmt.Printf("DecBuf has length %d and contents:\n%s\n", len(f.DecBuf.Bytes()), string(f.DecBuf.Bytes()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *SnappyFile) Read(p []byte) (n int, err error) {
|
|
||||||
|
|
||||||
if f.SnappyEncodeDecodeOff {
|
|
||||||
return f.Reader.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
if f.Writing {
|
|
||||||
panic("Reading on a write-only SnappyFile")
|
|
||||||
}
|
|
||||||
|
|
||||||
// before we unencrypt more, try to drain the DecBuf first
|
|
||||||
n, _ = f.DecBuf.Read(p)
|
|
||||||
if n > 0 {
|
|
||||||
total += n
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//nEncRead, nDecAdded, err := UnsnapOneFrame(f.Filep, &f.EncBuf, &f.DecBuf, f.Fname)
|
|
||||||
_, _, err = UnsnapOneFrame(f.Reader, &f.EncBuf, &f.DecBuf, f.Fname)
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n, _ = f.DecBuf.Read(p)
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
total += n
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
if f.DecBuf.Readable == 0 {
|
|
||||||
if f.DecBuf.Readable == 0 && f.EncBuf.Readable == 0 {
|
|
||||||
// only now (when EncBuf is empty) can we give io.EOF.
|
|
||||||
// Any earlier, and we leave stuff un-decoded!
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Open(name string) (file *SnappyFile, err error) {
|
|
||||||
fp, err := os.Open(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// encoding in snappy can apparently go beyond the original size, so
|
|
||||||
// we make our buffers big enough, 2*max snappy chunk => 2 * CHUNK_MAX(65536)
|
|
||||||
|
|
||||||
snap := NewReader(fp)
|
|
||||||
snap.Fname = name
|
|
||||||
return snap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReader(r io.Reader) *SnappyFile {
|
|
||||||
return &SnappyFile{
|
|
||||||
Reader: r,
|
|
||||||
EncBuf: *NewFixedSizeRingBuf(CHUNK_MAX * 2), // buffer of snappy encoded bytes
|
|
||||||
DecBuf: *NewFixedSizeRingBuf(CHUNK_MAX * 2), // buffer of snapppy decoded bytes
|
|
||||||
Writing: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWriter(w io.Writer) *SnappyFile {
|
|
||||||
return &SnappyFile{
|
|
||||||
Writer: w,
|
|
||||||
EncBuf: *NewFixedSizeRingBuf(65536), // on writing: temp for testing compression
|
|
||||||
DecBuf: *NewFixedSizeRingBuf(65536 * 2), // on writing: final buffer of snappy framed and encoded bytes
|
|
||||||
Writing: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Create(name string) (file *SnappyFile, err error) {
|
|
||||||
fp, err := os.Create(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
snap := NewWriter(fp)
|
|
||||||
snap.Fname = name
|
|
||||||
return snap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *SnappyFile) Close() error {
|
|
||||||
if f.Writing {
|
|
||||||
wc, ok := f.Writer.(io.WriteCloser)
|
|
||||||
if ok {
|
|
||||||
return wc.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
rc, ok := f.Reader.(io.ReadCloser)
|
|
||||||
if ok {
|
|
||||||
return rc.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *SnappyFile) Sync() error {
|
|
||||||
file, ok := f.Writer.(*os.File)
|
|
||||||
if ok {
|
|
||||||
return file.Sync()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// for an increment of a frame at a time:
|
|
||||||
// read from r into encBuf (encBuf is still encoded, thus the name), and write unsnappified frames into outDecodedBuf
|
|
||||||
// the returned n: number of bytes read from the encrypted encBuf
|
|
||||||
func UnsnapOneFrame(r io.Reader, encBuf *FixedSizeRingBuf, outDecodedBuf *FixedSizeRingBuf, fname string) (nEnc int64, nDec int64, err error) {
|
|
||||||
// b, err := ioutil.ReadAll(r)
|
|
||||||
// if err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
nEnc = 0
|
|
||||||
nDec = 0
|
|
||||||
|
|
||||||
// read up to 65536 bytes from r into encBuf, at least a snappy frame
|
|
||||||
nread, err := io.CopyN(encBuf, r, 65536) // returns nwrotebytes, err
|
|
||||||
nEnc += nread
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
if nread == 0 {
|
|
||||||
if encBuf.Readable == 0 {
|
|
||||||
return nEnc, nDec, io.EOF
|
|
||||||
}
|
|
||||||
// else we have bytes in encBuf, so decode them!
|
|
||||||
err = nil
|
|
||||||
} else {
|
|
||||||
// continue below, processing the nread bytes
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// may be an odd already closed... don't panic on that
|
|
||||||
if strings.Contains(err.Error(), "file already closed") {
|
|
||||||
err = nil
|
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// flag for printing chunk size alignment messages
|
|
||||||
verbose := false
|
|
||||||
|
|
||||||
const snappyStreamHeaderSz = 10
|
|
||||||
const headerSz = 4
|
|
||||||
const crc32Sz = 4
|
|
||||||
// the magic 18 bytes accounts for the snappy streaming header and the first chunks size and checksum
|
|
||||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
|
||||||
|
|
||||||
chunk := (*encBuf).Bytes()
|
|
||||||
|
|
||||||
// however we exit, advance as
|
|
||||||
// defer func() { (*encBuf).Next(N) }()
|
|
||||||
|
|
||||||
// 65536 is the max size of a snappy framed chunk. See
|
|
||||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt:91
|
|
||||||
// buf := make([]byte, 65536)
|
|
||||||
|
|
||||||
// fmt.Printf("read from file, b is len:%d with value: %#v\n", len(b), b)
|
|
||||||
// fmt.Printf("read from file, bcut is len:%d with value: %#v\n", len(bcut), bcut)
|
|
||||||
|
|
||||||
//fmt.Printf("raw bytes of chunksz are: %v\n", b[11:14])
|
|
||||||
|
|
||||||
fourbytes := make([]byte, 4)
|
|
||||||
chunkCount := 0
|
|
||||||
|
|
||||||
for nDec < 65536 {
|
|
||||||
if len(chunk) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
chunkCount++
|
|
||||||
fourbytes[3] = 0
|
|
||||||
copy(fourbytes, chunk[1:4])
|
|
||||||
chunksz := binary.LittleEndian.Uint32(fourbytes)
|
|
||||||
chunk_type := chunk[0]
|
|
||||||
|
|
||||||
switch true {
|
|
||||||
case chunk_type == 0xff:
|
|
||||||
{ // stream identifier
|
|
||||||
|
|
||||||
streamHeader := chunk[:snappyStreamHeaderSz]
|
|
||||||
if 0 != bytes.Compare(streamHeader, []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}) {
|
|
||||||
panic("file had chunk starting with 0xff but then no magic snappy streaming protocol bytes, aborting.")
|
|
||||||
} else {
|
|
||||||
//fmt.Printf("got streaming snappy magic header just fine.\n")
|
|
||||||
}
|
|
||||||
chunk = chunk[snappyStreamHeaderSz:]
|
|
||||||
(*encBuf).Advance(snappyStreamHeaderSz)
|
|
||||||
nEnc += snappyStreamHeaderSz
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case chunk_type == 0x00:
|
|
||||||
{ // compressed data
|
|
||||||
if verbose {
|
|
||||||
fmt.Fprintf(os.Stderr, "chunksz is %d while total bytes avail are: %d\n", int(chunksz), len(chunk)-4)
|
|
||||||
}
|
|
||||||
|
|
||||||
crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
|
|
||||||
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
|
|
||||||
|
|
||||||
dec, ok := snappy.Decode(nil, section)
|
|
||||||
if ok != nil {
|
|
||||||
// we've probably truncated a snappy frame at this point
|
|
||||||
// ok=snappy: corrupt input
|
|
||||||
// len(dec) == 0
|
|
||||||
//
|
|
||||||
err = fmt.Errorf("could not decode snappy stream: '%s' and len dec=%d and error='%v'\n", fname, len(dec), ok)
|
|
||||||
|
|
||||||
// get back to caller with what we've got so far
|
|
||||||
return nEnc, nDec, err
|
|
||||||
}
|
|
||||||
// fmt.Printf("ok, b is %#v , %#v\n", ok, dec)
|
|
||||||
|
|
||||||
// spit out decoded text
|
|
||||||
// n, err := w.Write(dec)
|
|
||||||
//fmt.Printf("len(dec) = %d, outDecodedBuf.Readable=%d\n", len(dec), outDecodedBuf.Readable)
|
|
||||||
bnb := bytes.NewBuffer(dec)
|
|
||||||
n, err := io.Copy(outDecodedBuf, bnb)
|
|
||||||
if err != nil {
|
|
||||||
//fmt.Printf("got n=%d, err= %s ; when trying to io.Copy(outDecodedBuf: N=%d, Readable=%d)\n", n, err, outDecodedBuf.N, outDecodedBuf.Readable)
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if n != int64(len(dec)) {
|
|
||||||
panic("could not write all bytes to outDecodedBuf")
|
|
||||||
}
|
|
||||||
nDec += n
|
|
||||||
|
|
||||||
// verify the crc32 rotated checksum
|
|
||||||
m32 := masked_crc32c(dec)
|
|
||||||
if m32 != crc {
|
|
||||||
panic(fmt.Sprintf("crc32 masked failiure. expected: %v but got: %v", crc, m32))
|
|
||||||
} else {
|
|
||||||
//fmt.Printf("\nchecksums match: %v == %v\n", crc, m32)
|
|
||||||
}
|
|
||||||
|
|
||||||
// move to next header
|
|
||||||
inc := (headerSz + int(chunksz))
|
|
||||||
chunk = chunk[inc:]
|
|
||||||
(*encBuf).Advance(inc)
|
|
||||||
nEnc += int64(inc)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case chunk_type == 0x01:
|
|
||||||
{ // uncompressed data
|
|
||||||
|
|
||||||
//n, err := w.Write(chunk[(headerSz+crc32Sz):(headerSz + int(chunksz))])
|
|
||||||
n, err := io.Copy(outDecodedBuf, bytes.NewBuffer(chunk[(headerSz+crc32Sz):(headerSz+int(chunksz))]))
|
|
||||||
if verbose {
|
|
||||||
//fmt.Printf("debug: n=%d err=%v chunksz=%d outDecodedBuf='%v'\n", n, err, chunksz, outDecodedBuf)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if n != int64(chunksz-crc32Sz) {
|
|
||||||
panic("could not write all bytes to stdout")
|
|
||||||
}
|
|
||||||
nDec += n
|
|
||||||
|
|
||||||
inc := (headerSz + int(chunksz))
|
|
||||||
chunk = chunk[inc:]
|
|
||||||
(*encBuf).Advance(inc)
|
|
||||||
nEnc += int64(inc)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case chunk_type == 0xfe:
|
|
||||||
fallthrough // padding, just skip it
|
|
||||||
case chunk_type >= 0x80 && chunk_type <= 0xfd:
|
|
||||||
{ // Reserved skippable chunks
|
|
||||||
//fmt.Printf("\nin reserved skippable chunks, at nEnc=%v\n", nEnc)
|
|
||||||
inc := (headerSz + int(chunksz))
|
|
||||||
chunk = chunk[inc:]
|
|
||||||
nEnc += int64(inc)
|
|
||||||
(*encBuf).Advance(inc)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("unrecognized/unsupported chunk type %#v; on fname='%v'", chunk_type, fname)
|
|
||||||
return nEnc, nDec, err
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end for{}
|
|
||||||
|
|
||||||
return nEnc, nDec, err
|
|
||||||
//return int64(N), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// for whole file at once:
|
|
||||||
//
|
|
||||||
// receive on stdin a stream of bytes in the snappy-streaming framed
|
|
||||||
// format, defined here: http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
|
||||||
// Grab each frame, run it through the snappy decoder, and spit out
|
|
||||||
// each frame all joined back-to-back on stdout.
|
|
||||||
//
|
|
||||||
func Unsnappy(r io.Reader, w io.Writer) (err error) {
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// flag for printing chunk size alignment messages
|
|
||||||
verbose := false
|
|
||||||
|
|
||||||
const snappyStreamHeaderSz = 10
|
|
||||||
const headerSz = 4
|
|
||||||
const crc32Sz = 4
|
|
||||||
// the magic 18 bytes accounts for the snappy streaming header and the first chunks size and checksum
|
|
||||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
|
||||||
|
|
||||||
chunk := b[:]
|
|
||||||
|
|
||||||
// 65536 is the max size of a snappy framed chunk. See
|
|
||||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt:91
|
|
||||||
//buf := make([]byte, 65536)
|
|
||||||
|
|
||||||
// fmt.Printf("read from file, b is len:%d with value: %#v\n", len(b), b)
|
|
||||||
// fmt.Printf("read from file, bcut is len:%d with value: %#v\n", len(bcut), bcut)
|
|
||||||
|
|
||||||
//fmt.Printf("raw bytes of chunksz are: %v\n", b[11:14])
|
|
||||||
|
|
||||||
fourbytes := make([]byte, 4)
|
|
||||||
chunkCount := 0
|
|
||||||
|
|
||||||
for {
|
|
||||||
if len(chunk) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
chunkCount++
|
|
||||||
fourbytes[3] = 0
|
|
||||||
copy(fourbytes, chunk[1:4])
|
|
||||||
chunksz := binary.LittleEndian.Uint32(fourbytes)
|
|
||||||
chunk_type := chunk[0]
|
|
||||||
|
|
||||||
switch true {
|
|
||||||
case chunk_type == 0xff:
|
|
||||||
{ // stream identifier
|
|
||||||
|
|
||||||
streamHeader := chunk[:snappyStreamHeaderSz]
|
|
||||||
if 0 != bytes.Compare(streamHeader, []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}) {
|
|
||||||
panic("file had chunk starting with 0xff but then no magic snappy streaming protocol bytes, aborting.")
|
|
||||||
} else {
|
|
||||||
//fmt.Printf("got streaming snappy magic header just fine.\n")
|
|
||||||
}
|
|
||||||
chunk = chunk[snappyStreamHeaderSz:]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case chunk_type == 0x00:
|
|
||||||
{ // compressed data
|
|
||||||
if verbose {
|
|
||||||
fmt.Fprintf(os.Stderr, "chunksz is %d while total bytes avail are: %d\n", int(chunksz), len(chunk)-4)
|
|
||||||
}
|
|
||||||
|
|
||||||
//crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
|
|
||||||
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
|
|
||||||
|
|
||||||
dec, ok := snappy.Decode(nil, section)
|
|
||||||
if ok != nil {
|
|
||||||
panic("could not decode snappy stream")
|
|
||||||
}
|
|
||||||
// fmt.Printf("ok, b is %#v , %#v\n", ok, dec)
|
|
||||||
|
|
||||||
// spit out decoded text
|
|
||||||
n, err := w.Write(dec)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if n != len(dec) {
|
|
||||||
panic("could not write all bytes to stdout")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: verify the crc32 rotated checksum?
|
|
||||||
|
|
||||||
// move to next header
|
|
||||||
chunk = chunk[(headerSz + int(chunksz)):]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case chunk_type == 0x01:
|
|
||||||
{ // uncompressed data
|
|
||||||
|
|
||||||
//crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
|
|
||||||
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
|
|
||||||
|
|
||||||
n, err := w.Write(section)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if n != int(chunksz-crc32Sz) {
|
|
||||||
panic("could not write all bytes to stdout")
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk = chunk[(headerSz + int(chunksz)):]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case chunk_type == 0xfe:
|
|
||||||
fallthrough // padding, just skip it
|
|
||||||
case chunk_type >= 0x80 && chunk_type <= 0xfd:
|
|
||||||
{ // Reserved skippable chunks
|
|
||||||
chunk = chunk[(headerSz + int(chunksz)):]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unrecognized/unsupported chunk type %#v", chunk_type))
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end for{}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0xff 0x06 0x00 0x00 sNaPpY
|
|
||||||
var SnappyStreamHeaderMagic = []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}
|
|
||||||
|
|
||||||
const CHUNK_MAX = 65536
|
|
||||||
const _STREAM_TO_STREAM_BLOCK_SIZE = CHUNK_MAX
|
|
||||||
const _STREAM_IDENTIFIER = `sNaPpY`
|
|
||||||
const _COMPRESSED_CHUNK = 0x00
|
|
||||||
const _UNCOMPRESSED_CHUNK = 0x01
|
|
||||||
const _IDENTIFIER_CHUNK = 0xff
|
|
||||||
const _RESERVED_UNSKIPPABLE0 = 0x02 // chunk ranges are [inclusive, exclusive)
|
|
||||||
const _RESERVED_UNSKIPPABLE1 = 0x80
|
|
||||||
const _RESERVED_SKIPPABLE0 = 0x80
|
|
||||||
const _RESERVED_SKIPPABLE1 = 0xff
|
|
||||||
|
|
||||||
// the minimum percent of bytes compression must save to be enabled in automatic
|
|
||||||
// mode
|
|
||||||
const _COMPRESSION_THRESHOLD = .125
|
|
||||||
|
|
||||||
var crctab *crc32.Table
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
crctab = crc32.MakeTable(crc32.Castagnoli) // this is correct table, matches the crc32c.c code used by python
|
|
||||||
}
|
|
||||||
|
|
||||||
func masked_crc32c(data []byte) uint32 {
|
|
||||||
|
|
||||||
// see the framing format specification, http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
|
||||||
var crc uint32 = crc32.Checksum(data, crctab)
|
|
||||||
return (uint32((crc>>15)|(crc<<17)) + 0xa282ead8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReadSnappyStreamCompressedFile(filename string) ([]byte, error) {
|
|
||||||
|
|
||||||
snappyFile, err := Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return []byte{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var bb bytes.Buffer
|
|
||||||
_, err = bb.ReadFrom(snappyFile)
|
|
||||||
if err == io.EOF {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return bb.Bytes(), err
|
|
||||||
}
|
|
|
@ -16,8 +16,8 @@ func main() {
|
||||||
// Basic CORS
|
// Basic CORS
|
||||||
// for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing
|
// for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing
|
||||||
r.Use(cors.Handler(cors.Options{
|
r.Use(cors.Handler(cors.Options{
|
||||||
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
|
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"https://*", "http://*"},
|
||||||
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
|
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
|
||||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||||
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
|
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module github.com/go-chi/cors
|
||||||
|
|
||||||
|
go 1.14
|
|
@ -1,4 +1,4 @@
|
||||||
# go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest)
|
# go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy/v5) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest)
|
||||||
|
|
||||||
The missing interface filesystem abstraction for Go.
|
The missing interface filesystem abstraction for Go.
|
||||||
Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations.
|
Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations.
|
||||||
|
|
|
@ -89,6 +89,13 @@ type Config struct {
|
||||||
Window uint
|
Window uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Init struct {
|
||||||
|
// DefaultBranch Allows overriding the default branch name
|
||||||
|
// e.g. when initializing a new repository or when cloning
|
||||||
|
// an empty repository.
|
||||||
|
DefaultBranch string
|
||||||
|
}
|
||||||
|
|
||||||
// Remotes list of repository remotes, the key of the map is the name
|
// Remotes list of repository remotes, the key of the map is the name
|
||||||
// of the remote, should equal to RemoteConfig.Name.
|
// of the remote, should equal to RemoteConfig.Name.
|
||||||
Remotes map[string]*RemoteConfig
|
Remotes map[string]*RemoteConfig
|
||||||
|
@ -98,6 +105,9 @@ type Config struct {
|
||||||
// Branches list of branches, the key is the branch name and should
|
// Branches list of branches, the key is the branch name and should
|
||||||
// equal Branch.Name
|
// equal Branch.Name
|
||||||
Branches map[string]*Branch
|
Branches map[string]*Branch
|
||||||
|
// URLs list of url rewrite rules, if repo url starts with URL.InsteadOf value, it will be replaced with the
|
||||||
|
// key instead.
|
||||||
|
URLs map[string]*URL
|
||||||
// Raw contains the raw information of a config file. The main goal is
|
// Raw contains the raw information of a config file. The main goal is
|
||||||
// preserve the parsed information from the original format, to avoid
|
// preserve the parsed information from the original format, to avoid
|
||||||
// dropping unsupported fields.
|
// dropping unsupported fields.
|
||||||
|
@ -110,6 +120,7 @@ func NewConfig() *Config {
|
||||||
Remotes: make(map[string]*RemoteConfig),
|
Remotes: make(map[string]*RemoteConfig),
|
||||||
Submodules: make(map[string]*Submodule),
|
Submodules: make(map[string]*Submodule),
|
||||||
Branches: make(map[string]*Branch),
|
Branches: make(map[string]*Branch),
|
||||||
|
URLs: make(map[string]*URL),
|
||||||
Raw: format.New(),
|
Raw: format.New(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +234,8 @@ const (
|
||||||
userSection = "user"
|
userSection = "user"
|
||||||
authorSection = "author"
|
authorSection = "author"
|
||||||
committerSection = "committer"
|
committerSection = "committer"
|
||||||
|
initSection = "init"
|
||||||
|
urlSection = "url"
|
||||||
fetchKey = "fetch"
|
fetchKey = "fetch"
|
||||||
urlKey = "url"
|
urlKey = "url"
|
||||||
bareKey = "bare"
|
bareKey = "bare"
|
||||||
|
@ -233,6 +246,7 @@ const (
|
||||||
rebaseKey = "rebase"
|
rebaseKey = "rebase"
|
||||||
nameKey = "name"
|
nameKey = "name"
|
||||||
emailKey = "email"
|
emailKey = "email"
|
||||||
|
defaultBranchKey = "defaultBranch"
|
||||||
|
|
||||||
// DefaultPackWindow holds the number of previous objects used to
|
// DefaultPackWindow holds the number of previous objects used to
|
||||||
// generate deltas. The value 10 is the same used by git command.
|
// generate deltas. The value 10 is the same used by git command.
|
||||||
|
@ -251,6 +265,7 @@ func (c *Config) Unmarshal(b []byte) error {
|
||||||
|
|
||||||
c.unmarshalCore()
|
c.unmarshalCore()
|
||||||
c.unmarshalUser()
|
c.unmarshalUser()
|
||||||
|
c.unmarshalInit()
|
||||||
if err := c.unmarshalPack(); err != nil {
|
if err := c.unmarshalPack(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -260,6 +275,10 @@ func (c *Config) Unmarshal(b []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.unmarshalURLs(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return c.unmarshalRemotes()
|
return c.unmarshalRemotes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +332,25 @@ func (c *Config) unmarshalRemotes() error {
|
||||||
c.Remotes[r.Name] = r
|
c.Remotes[r.Name] = r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply insteadOf url rules
|
||||||
|
for _, r := range c.Remotes {
|
||||||
|
r.applyURLRules(c.URLs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) unmarshalURLs() error {
|
||||||
|
s := c.Raw.Section(urlSection)
|
||||||
|
for _, sub := range s.Subsections {
|
||||||
|
r := &URL{}
|
||||||
|
if err := r.unmarshal(sub); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.URLs[r.Name] = r
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,6 +382,11 @@ func (c *Config) unmarshalBranches() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) unmarshalInit() {
|
||||||
|
s := c.Raw.Section(initSection)
|
||||||
|
c.Init.DefaultBranch = s.Options.Get(defaultBranchKey)
|
||||||
|
}
|
||||||
|
|
||||||
// Marshal returns Config encoded as a git-config file.
|
// Marshal returns Config encoded as a git-config file.
|
||||||
func (c *Config) Marshal() ([]byte, error) {
|
func (c *Config) Marshal() ([]byte, error) {
|
||||||
c.marshalCore()
|
c.marshalCore()
|
||||||
|
@ -352,6 +395,8 @@ func (c *Config) Marshal() ([]byte, error) {
|
||||||
c.marshalRemotes()
|
c.marshalRemotes()
|
||||||
c.marshalSubmodules()
|
c.marshalSubmodules()
|
||||||
c.marshalBranches()
|
c.marshalBranches()
|
||||||
|
c.marshalURLs()
|
||||||
|
c.marshalInit()
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
if err := format.NewEncoder(buf).Encode(c.Raw); err != nil {
|
if err := format.NewEncoder(buf).Encode(c.Raw); err != nil {
|
||||||
|
@ -475,6 +520,27 @@ func (c *Config) marshalBranches() {
|
||||||
s.Subsections = newSubsections
|
s.Subsections = newSubsections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) marshalURLs() {
|
||||||
|
s := c.Raw.Section(urlSection)
|
||||||
|
s.Subsections = make(format.Subsections, len(c.URLs))
|
||||||
|
|
||||||
|
var i int
|
||||||
|
for _, r := range c.URLs {
|
||||||
|
section := r.marshal()
|
||||||
|
// the submodule section at config is a subset of the .gitmodule file
|
||||||
|
// we should remove the non-valid options for the config file.
|
||||||
|
s.Subsections[i] = section
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) marshalInit() {
|
||||||
|
s := c.Raw.Section(initSection)
|
||||||
|
if c.Init.DefaultBranch != "" {
|
||||||
|
s.SetOption(defaultBranchKey, c.Init.DefaultBranch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RemoteConfig contains the configuration for a given remote repository.
|
// RemoteConfig contains the configuration for a given remote repository.
|
||||||
type RemoteConfig struct {
|
type RemoteConfig struct {
|
||||||
// Name of the remote
|
// Name of the remote
|
||||||
|
@ -482,6 +548,12 @@ type RemoteConfig struct {
|
||||||
// URLs the URLs of a remote repository. It must be non-empty. Fetch will
|
// URLs the URLs of a remote repository. It must be non-empty. Fetch will
|
||||||
// always use the first URL, while push will use all of them.
|
// always use the first URL, while push will use all of them.
|
||||||
URLs []string
|
URLs []string
|
||||||
|
|
||||||
|
// insteadOfRulesApplied have urls been modified
|
||||||
|
insteadOfRulesApplied bool
|
||||||
|
// originalURLs are the urls before applying insteadOf rules
|
||||||
|
originalURLs []string
|
||||||
|
|
||||||
// Fetch the default set of "refspec" for fetch operation
|
// Fetch the default set of "refspec" for fetch operation
|
||||||
Fetch []RefSpec
|
Fetch []RefSpec
|
||||||
|
|
||||||
|
@ -542,7 +614,12 @@ func (c *RemoteConfig) marshal() *format.Subsection {
|
||||||
if len(c.URLs) == 0 {
|
if len(c.URLs) == 0 {
|
||||||
c.raw.RemoveOption(urlKey)
|
c.raw.RemoveOption(urlKey)
|
||||||
} else {
|
} else {
|
||||||
c.raw.SetOption(urlKey, c.URLs...)
|
urls := c.URLs
|
||||||
|
if c.insteadOfRulesApplied {
|
||||||
|
urls = c.originalURLs
|
||||||
|
}
|
||||||
|
|
||||||
|
c.raw.SetOption(urlKey, urls...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.Fetch) == 0 {
|
if len(c.Fetch) == 0 {
|
||||||
|
@ -562,3 +639,20 @@ func (c *RemoteConfig) marshal() *format.Subsection {
|
||||||
func (c *RemoteConfig) IsFirstURLLocal() bool {
|
func (c *RemoteConfig) IsFirstURLLocal() bool {
|
||||||
return url.IsLocalEndpoint(c.URLs[0])
|
return url.IsLocalEndpoint(c.URLs[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *RemoteConfig) applyURLRules(urlRules map[string]*URL) {
|
||||||
|
// save original urls
|
||||||
|
originalURLs := make([]string, len(c.URLs))
|
||||||
|
copy(originalURLs, c.URLs)
|
||||||
|
|
||||||
|
for i, url := range c.URLs {
|
||||||
|
if matchingURLRule := findLongestInsteadOfMatch(url, urlRules); matchingURLRule != nil {
|
||||||
|
c.URLs[i] = matchingURLRule.ApplyInsteadOf(c.URLs[i])
|
||||||
|
c.insteadOfRulesApplied = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.insteadOfRulesApplied {
|
||||||
|
c.originalURLs = originalURLs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
format "github.com/go-git/go-git/v5/plumbing/format/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errURLEmptyInsteadOf = errors.New("url config: empty insteadOf")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Url defines Url rewrite rules
|
||||||
|
type URL struct {
|
||||||
|
// Name new base url
|
||||||
|
Name string
|
||||||
|
// Any URL that starts with this value will be rewritten to start, instead, with <base>.
|
||||||
|
// When more than one insteadOf strings match a given URL, the longest match is used.
|
||||||
|
InsteadOf string
|
||||||
|
|
||||||
|
// raw representation of the subsection, filled by marshal or unmarshal are
|
||||||
|
// called.
|
||||||
|
raw *format.Subsection
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates fields of branch
|
||||||
|
func (b *URL) Validate() error {
|
||||||
|
if b.InsteadOf == "" {
|
||||||
|
return errURLEmptyInsteadOf
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
insteadOfKey = "insteadOf"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (u *URL) unmarshal(s *format.Subsection) error {
|
||||||
|
u.raw = s
|
||||||
|
|
||||||
|
u.Name = s.Name
|
||||||
|
u.InsteadOf = u.raw.Option(insteadOfKey)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URL) marshal() *format.Subsection {
|
||||||
|
if u.raw == nil {
|
||||||
|
u.raw = &format.Subsection{}
|
||||||
|
}
|
||||||
|
|
||||||
|
u.raw.Name = u.Name
|
||||||
|
u.raw.SetOption(insteadOfKey, u.InsteadOf)
|
||||||
|
|
||||||
|
return u.raw
|
||||||
|
}
|
||||||
|
|
||||||
|
func findLongestInsteadOfMatch(remoteURL string, urls map[string]*URL) *URL {
|
||||||
|
var longestMatch *URL
|
||||||
|
for _, u := range urls {
|
||||||
|
if !strings.HasPrefix(remoteURL, u.InsteadOf) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// according to spec if there is more than one match, take the logest
|
||||||
|
if longestMatch == nil || len(longestMatch.InsteadOf) < len(u.InsteadOf) {
|
||||||
|
longestMatch = u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return longestMatch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URL) ApplyInsteadOf(url string) string {
|
||||||
|
if !strings.HasPrefix(url, u.InsteadOf) {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.Name + url[len(u.InsteadOf):]
|
||||||
|
}
|
|
@ -1,27 +1,27 @@
|
||||||
module github.com/go-git/go-git/v5
|
module github.com/go-git/go-git/v5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||||
github.com/emirpasic/gods v1.12.0
|
github.com/emirpasic/gods v1.12.0
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
|
||||||
github.com/gliderlabs/ssh v0.2.2
|
github.com/gliderlabs/ssh v0.2.2
|
||||||
github.com/go-git/gcfg v1.5.0
|
github.com/go-git/gcfg v1.5.0
|
||||||
github.com/go-git/go-billy/v5 v5.0.0
|
github.com/go-git/go-billy/v5 v5.1.0
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12
|
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12
|
||||||
github.com/google/go-cmp v0.3.0
|
github.com/google/go-cmp v0.3.0
|
||||||
github.com/imdario/mergo v0.3.9
|
github.com/imdario/mergo v0.3.12
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||||
github.com/jessevdk/go-flags v1.4.0
|
github.com/jessevdk/go-flags v1.5.0
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
|
||||||
github.com/sergi/go-diff v1.1.0
|
github.com/sergi/go-diff v1.1.0
|
||||||
github.com/xanzy/ssh-agent v0.2.1
|
github.com/xanzy/ssh-agent v0.3.0
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
golang.org/x/net v0.0.0-20210326060303-6b1517762897
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/text v0.3.3
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
|
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||||
|
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||||
|
@ -18,6 +21,8 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
|
github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk=
|
||||||
|
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
||||||
|
@ -26,14 +31,23 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||||
|
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
|
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||||
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
@ -45,38 +59,62 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
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=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||||
|
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||||
|
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
|
||||||
|
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -60,6 +60,10 @@ type CloneOptions struct {
|
||||||
// Tags describe how the tags will be fetched from the remote repository,
|
// Tags describe how the tags will be fetched from the remote repository,
|
||||||
// by default is AllTags.
|
// by default is AllTags.
|
||||||
Tags TagMode
|
Tags TagMode
|
||||||
|
// InsecureSkipTLS skips ssl verify if protocol is https
|
||||||
|
InsecureSkipTLS bool
|
||||||
|
// CABundle specify additional ca bundle with system cert pool
|
||||||
|
CABundle []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the fields and sets the default values.
|
// Validate validates the fields and sets the default values.
|
||||||
|
@ -105,6 +109,10 @@ type PullOptions struct {
|
||||||
// Force allows the pull to update a local branch even when the remote
|
// Force allows the pull to update a local branch even when the remote
|
||||||
// branch does not descend from it.
|
// branch does not descend from it.
|
||||||
Force bool
|
Force bool
|
||||||
|
// InsecureSkipTLS skips ssl verify if protocol is https
|
||||||
|
InsecureSkipTLS bool
|
||||||
|
// CABundle specify additional ca bundle with system cert pool
|
||||||
|
CABundle []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the fields and sets the default values.
|
// Validate validates the fields and sets the default values.
|
||||||
|
@ -155,6 +163,10 @@ type FetchOptions struct {
|
||||||
// Force allows the fetch to update a local branch even when the remote
|
// Force allows the fetch to update a local branch even when the remote
|
||||||
// branch does not descend from it.
|
// branch does not descend from it.
|
||||||
Force bool
|
Force bool
|
||||||
|
// InsecureSkipTLS skips ssl verify if protocol is https
|
||||||
|
InsecureSkipTLS bool
|
||||||
|
// CABundle specify additional ca bundle with system cert pool
|
||||||
|
CABundle []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the fields and sets the default values.
|
// Validate validates the fields and sets the default values.
|
||||||
|
@ -194,6 +206,13 @@ type PushOptions struct {
|
||||||
// Force allows the push to update a remote branch even when the local
|
// Force allows the push to update a remote branch even when the local
|
||||||
// branch does not descend from it.
|
// branch does not descend from it.
|
||||||
Force bool
|
Force bool
|
||||||
|
// InsecureSkipTLS skips ssl verify if protocal is https
|
||||||
|
InsecureSkipTLS bool
|
||||||
|
// CABundle specify additional ca bundle with system cert pool
|
||||||
|
CABundle []byte
|
||||||
|
// RequireRemoteRefs only allows a remote ref to be updated if its current
|
||||||
|
// value is the one specified here.
|
||||||
|
RequireRemoteRefs []config.RefSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the fields and sets the default values.
|
// Validate validates the fields and sets the default values.
|
||||||
|
@ -552,6 +571,10 @@ func (o *CreateTagOptions) loadConfigTagger(r *Repository) error {
|
||||||
type ListOptions struct {
|
type ListOptions struct {
|
||||||
// Auth credentials, if required, to use with the remote repository.
|
// Auth credentials, if required, to use with the remote repository.
|
||||||
Auth transport.AuthMethod
|
Auth transport.AuthMethod
|
||||||
|
// InsecureSkipTLS skips ssl verify if protocal is https
|
||||||
|
InsecureSkipTLS bool
|
||||||
|
// CABundle specify additional ca bundle with system cert pool
|
||||||
|
CABundle []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanOptions describes how a clean should be performed.
|
// CleanOptions describes how a clean should be performed.
|
||||||
|
|
|
@ -38,6 +38,10 @@ type UnifiedEncoder struct {
|
||||||
// a change.
|
// a change.
|
||||||
contextLines int
|
contextLines int
|
||||||
|
|
||||||
|
// srcPrefix and dstPrefix are prepended to file paths when encoding a diff.
|
||||||
|
srcPrefix string
|
||||||
|
dstPrefix string
|
||||||
|
|
||||||
// colorConfig is the color configuration. The default is no color.
|
// colorConfig is the color configuration. The default is no color.
|
||||||
color ColorConfig
|
color ColorConfig
|
||||||
}
|
}
|
||||||
|
@ -46,6 +50,8 @@ type UnifiedEncoder struct {
|
||||||
func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder {
|
func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder {
|
||||||
return &UnifiedEncoder{
|
return &UnifiedEncoder{
|
||||||
Writer: w,
|
Writer: w,
|
||||||
|
srcPrefix: "a/",
|
||||||
|
dstPrefix: "b/",
|
||||||
contextLines: contextLines,
|
contextLines: contextLines,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +62,18 @@ func (e *UnifiedEncoder) SetColor(colorConfig ColorConfig) *UnifiedEncoder {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSrcPrefix sets e's srcPrefix and returns e.
|
||||||
|
func (e *UnifiedEncoder) SetSrcPrefix(prefix string) *UnifiedEncoder {
|
||||||
|
e.srcPrefix = prefix
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDstPrefix sets e's dstPrefix and returns e.
|
||||||
|
func (e *UnifiedEncoder) SetDstPrefix(prefix string) *UnifiedEncoder {
|
||||||
|
e.dstPrefix = prefix
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// Encode encodes patch.
|
// Encode encodes patch.
|
||||||
func (e *UnifiedEncoder) Encode(patch Patch) error {
|
func (e *UnifiedEncoder) Encode(patch Patch) error {
|
||||||
sb := &strings.Builder{}
|
sb := &strings.Builder{}
|
||||||
|
@ -91,7 +109,8 @@ func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch Fil
|
||||||
case from != nil && to != nil:
|
case from != nil && to != nil:
|
||||||
hashEquals := from.Hash() == to.Hash()
|
hashEquals := from.Hash() == to.Hash()
|
||||||
lines = append(lines,
|
lines = append(lines,
|
||||||
fmt.Sprintf("diff --git a/%s b/%s", from.Path(), to.Path()),
|
fmt.Sprintf("diff --git %s%s %s%s",
|
||||||
|
e.srcPrefix, from.Path(), e.dstPrefix, to.Path()),
|
||||||
)
|
)
|
||||||
if from.Mode() != to.Mode() {
|
if from.Mode() != to.Mode() {
|
||||||
lines = append(lines,
|
lines = append(lines,
|
||||||
|
@ -115,22 +134,22 @@ func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch Fil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if !hashEquals {
|
if !hashEquals {
|
||||||
lines = e.appendPathLines(lines, "a/"+from.Path(), "b/"+to.Path(), isBinary)
|
lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), e.dstPrefix+to.Path(), isBinary)
|
||||||
}
|
}
|
||||||
case from == nil:
|
case from == nil:
|
||||||
lines = append(lines,
|
lines = append(lines,
|
||||||
fmt.Sprintf("diff --git a/%s b/%s", to.Path(), to.Path()),
|
fmt.Sprintf("diff --git %s %s", e.srcPrefix+to.Path(), e.dstPrefix+to.Path()),
|
||||||
fmt.Sprintf("new file mode %o", to.Mode()),
|
fmt.Sprintf("new file mode %o", to.Mode()),
|
||||||
fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()),
|
fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()),
|
||||||
)
|
)
|
||||||
lines = e.appendPathLines(lines, "/dev/null", "b/"+to.Path(), isBinary)
|
lines = e.appendPathLines(lines, "/dev/null", e.dstPrefix+to.Path(), isBinary)
|
||||||
case to == nil:
|
case to == nil:
|
||||||
lines = append(lines,
|
lines = append(lines,
|
||||||
fmt.Sprintf("diff --git a/%s b/%s", from.Path(), from.Path()),
|
fmt.Sprintf("diff --git %s %s", e.srcPrefix+from.Path(), e.dstPrefix+from.Path()),
|
||||||
fmt.Sprintf("deleted file mode %o", from.Mode()),
|
fmt.Sprintf("deleted file mode %o", from.Mode()),
|
||||||
fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash),
|
fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash),
|
||||||
)
|
)
|
||||||
lines = e.appendPathLines(lines, "a/"+from.Path(), "/dev/null", isBinary)
|
lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), "/dev/null", isBinary)
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.WriteString(e.color[Meta])
|
sb.WriteString(e.color[Meta])
|
||||||
|
|
|
@ -125,7 +125,7 @@ func LoadGlobalPatterns(fs billy.Filesystem) (ps []Pattern, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadSystemPatterns loads gitignore patterns from from the gitignore file
|
// LoadSystemPatterns loads gitignore patterns from from the gitignore file
|
||||||
// declared in a system's /etc/gitconfig file. If the ~/.gitconfig file does
|
// declared in a system's /etc/gitconfig file. If the /etc/gitconfig file does
|
||||||
// not exist the function will return nil. If the core.excludesfile property
|
// not exist the function will return nil. If the core.excludesfile property
|
||||||
// is not declared, the function will return nil. If the file pointed to by
|
// is not declared, the function will return nil. If the file pointed to by
|
||||||
// the core.excludesfile property does not exist, the function will return nil.
|
// the core.excludesfile property does not exist, the function will return nil.
|
||||||
|
|
9
vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go
generated
vendored
9
vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go
generated
vendored
|
@ -230,6 +230,12 @@ const (
|
||||||
PushCert Capability = "push-cert"
|
PushCert Capability = "push-cert"
|
||||||
// SymRef symbolic reference support for better negotiation.
|
// SymRef symbolic reference support for better negotiation.
|
||||||
SymRef Capability = "symref"
|
SymRef Capability = "symref"
|
||||||
|
// ObjectFormat takes a hash algorithm as an argument, indicates that the
|
||||||
|
// server supports the given hash algorithms.
|
||||||
|
ObjectFormat Capability = "object-format"
|
||||||
|
// Filter if present, fetch-pack may send "filter" commands to request a
|
||||||
|
// partial clone or partial fetch and request that the server omit various objects from the packfile
|
||||||
|
Filter Capability = "filter"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultAgent = "go-git/4.x"
|
const DefaultAgent = "go-git/4.x"
|
||||||
|
@ -241,10 +247,11 @@ var known = map[Capability]bool{
|
||||||
NoProgress: true, IncludeTag: true, ReportStatus: true, DeleteRefs: true,
|
NoProgress: true, IncludeTag: true, ReportStatus: true, DeleteRefs: true,
|
||||||
Quiet: true, Atomic: true, PushOptions: true, AllowTipSHA1InWant: true,
|
Quiet: true, Atomic: true, PushOptions: true, AllowTipSHA1InWant: true,
|
||||||
AllowReachableSHA1InWant: true, PushCert: true, SymRef: true,
|
AllowReachableSHA1InWant: true, PushCert: true, SymRef: true,
|
||||||
|
ObjectFormat: true, Filter: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var requiresArgument = map[Capability]bool{
|
var requiresArgument = map[Capability]bool{
|
||||||
Agent: true, PushCert: true, SymRef: true,
|
Agent: true, PushCert: true, SymRef: true, ObjectFormat: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var multipleArgument = map[Capability]bool{
|
var multipleArgument = map[Capability]bool{
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
gohttp "net/http"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport/file"
|
"github.com/go-git/go-git/v5/plumbing/transport/file"
|
||||||
|
@ -21,6 +24,14 @@ var Protocols = map[string]transport.Transport{
|
||||||
"file": file.DefaultClient,
|
"file": file.DefaultClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var insecureClient = http.NewClient(&gohttp.Client{
|
||||||
|
Transport: &gohttp.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// InstallProtocol adds or modifies an existing protocol.
|
// InstallProtocol adds or modifies an existing protocol.
|
||||||
func InstallProtocol(scheme string, c transport.Transport) {
|
func InstallProtocol(scheme string, c transport.Transport) {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
|
@ -35,6 +46,31 @@ func InstallProtocol(scheme string, c transport.Transport) {
|
||||||
// http://, https://, ssh:// and file://.
|
// http://, https://, ssh:// and file://.
|
||||||
// See `InstallProtocol` to add or modify protocols.
|
// See `InstallProtocol` to add or modify protocols.
|
||||||
func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
|
func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
|
||||||
|
return getTransport(endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTransport(endpoint *transport.Endpoint) (transport.Transport, error) {
|
||||||
|
if endpoint.Protocol == "https" {
|
||||||
|
if endpoint.InsecureSkipTLS {
|
||||||
|
return insecureClient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(endpoint.CaBundle) != 0 {
|
||||||
|
rootCAs, _ := x509.SystemCertPool()
|
||||||
|
if rootCAs == nil {
|
||||||
|
rootCAs = x509.NewCertPool()
|
||||||
|
}
|
||||||
|
rootCAs.AppendCertsFromPEM(endpoint.CaBundle)
|
||||||
|
return http.NewClient(&gohttp.Client{
|
||||||
|
Transport: &gohttp.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
RootCAs: rootCAs,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f, ok := Protocols[endpoint.Protocol]
|
f, ok := Protocols[endpoint.Protocol]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unsupported scheme %q", endpoint.Protocol)
|
return nil, fmt.Errorf("unsupported scheme %q", endpoint.Protocol)
|
||||||
|
@ -43,6 +79,5 @@ func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return nil, fmt.Errorf("malformed client for scheme %q, client is defined as nil", endpoint.Protocol)
|
return nil, fmt.Errorf("malformed client for scheme %q, client is defined as nil", endpoint.Protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,11 @@ type Session interface {
|
||||||
// If the repository does not exist, returns ErrRepositoryNotFound.
|
// If the repository does not exist, returns ErrRepositoryNotFound.
|
||||||
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
|
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
|
||||||
AdvertisedReferences() (*packp.AdvRefs, error)
|
AdvertisedReferences() (*packp.AdvRefs, error)
|
||||||
|
// AdvertisedReferencesContext retrieves the advertised references for a
|
||||||
|
// repository.
|
||||||
|
// If the repository does not exist, returns ErrRepositoryNotFound.
|
||||||
|
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
|
||||||
|
AdvertisedReferencesContext(context.Context) (*packp.AdvRefs, error)
|
||||||
io.Closer
|
io.Closer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +112,10 @@ type Endpoint struct {
|
||||||
Port int
|
Port int
|
||||||
// Path is the repository path.
|
// Path is the repository path.
|
||||||
Path string
|
Path string
|
||||||
|
// InsecureSkipTLS skips ssl verify if protocal is https
|
||||||
|
InsecureSkipTLS bool
|
||||||
|
// CaBundle specify additional ca bundle with system cert pool
|
||||||
|
CaBundle []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultPorts = map[string]int{
|
var defaultPorts = map[string]int{
|
||||||
|
|
|
@ -3,6 +3,7 @@ package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -32,7 +33,7 @@ func applyHeadersToRequest(req *http.Request, content *bytes.Buffer, host string
|
||||||
|
|
||||||
const infoRefsPath = "/info/refs"
|
const infoRefsPath = "/info/refs"
|
||||||
|
|
||||||
func advertisedReferences(s *session, serviceName string) (ref *packp.AdvRefs, err error) {
|
func advertisedReferences(ctx context.Context, s *session, serviceName string) (ref *packp.AdvRefs, err error) {
|
||||||
url := fmt.Sprintf(
|
url := fmt.Sprintf(
|
||||||
"%s%s?service=%s",
|
"%s%s?service=%s",
|
||||||
s.endpoint.String(), infoRefsPath, serviceName,
|
s.endpoint.String(), infoRefsPath, serviceName,
|
||||||
|
@ -45,7 +46,7 @@ func advertisedReferences(s *session, serviceName string) (ref *packp.AdvRefs, e
|
||||||
|
|
||||||
s.ApplyAuthToRequest(req)
|
s.ApplyAuthToRequest(req)
|
||||||
applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName)
|
applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName)
|
||||||
res, err := s.client.Do(req)
|
res, err := s.client.Do(req.WithContext(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,11 @@ func newReceivePackSession(c *http.Client, ep *transport.Endpoint, auth transpor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||||
return advertisedReferences(s.session, transport.ReceivePackServiceName)
|
return advertisedReferences(context.TODO(), s.session, transport.ReceivePackServiceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||||
|
return advertisedReferences(ctx, s.session, transport.ReceivePackServiceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (
|
func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (
|
||||||
|
|
|
@ -25,7 +25,11 @@ func newUploadPackSession(c *http.Client, ep *transport.Endpoint, auth transport
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||||
return advertisedReferences(s.session, transport.UploadPackServiceName)
|
return advertisedReferences(context.TODO(), s.session, transport.UploadPackServiceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||||
|
return advertisedReferences(ctx, s.session, transport.UploadPackServiceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *upSession) UploadPack(
|
func (s *upSession) UploadPack(
|
||||||
|
|
10
vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go
generated
vendored
10
vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go
generated
vendored
|
@ -162,14 +162,18 @@ func (c *client) listenFirstError(r io.Reader) chan string {
|
||||||
return errLine
|
return errLine
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdvertisedReferences retrieves the advertised references from the server.
|
|
||||||
func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) {
|
func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||||
|
return s.AdvertisedReferencesContext(context.TODO())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdvertisedReferences retrieves the advertised references from the server.
|
||||||
|
func (s *session) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||||
if s.advRefs != nil {
|
if s.advRefs != nil {
|
||||||
return s.advRefs, nil
|
return s.advRefs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ar := packp.NewAdvRefs()
|
ar := packp.NewAdvRefs()
|
||||||
if err := ar.Decode(s.Stdout); err != nil {
|
if err := ar.Decode(s.StdoutContext(ctx)); err != nil {
|
||||||
if err := s.handleAdvRefDecodeError(err); err != nil {
|
if err := s.handleAdvRefDecodeError(err); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -237,7 +241,7 @@ func (s *session) UploadPack(ctx context.Context, req *packp.UploadPackRequest)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.AdvertisedReferences(); err != nil {
|
if _, err := s.AdvertisedReferencesContext(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,10 @@ type upSession struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||||
|
return s.AdvertisedReferencesContext(context.TODO())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||||
ar := packp.NewAdvRefs()
|
ar := packp.NewAdvRefs()
|
||||||
|
|
||||||
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
|
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
|
||||||
|
@ -204,6 +208,10 @@ type rpSession struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||||
|
return s.AdvertisedReferencesContext(context.TODO())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||||
ar := packp.NewAdvRefs()
|
ar := packp.NewAdvRefs()
|
||||||
|
|
||||||
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
|
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport/internal/common"
|
"github.com/go-git/go-git/v5/plumbing/transport/internal/common"
|
||||||
|
@ -90,8 +91,14 @@ func (c *command) Close() error {
|
||||||
//XXX: If did read the full packfile, then the session might be already
|
//XXX: If did read the full packfile, then the session might be already
|
||||||
// closed.
|
// closed.
|
||||||
_ = c.Session.Close()
|
_ = c.Session.Close()
|
||||||
|
err := c.client.Close()
|
||||||
|
|
||||||
return c.client.Close()
|
//XXX: in go1.16+ we can use errors.Is(err, net.ErrClosed)
|
||||||
|
if err != nil && strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect connects to the SSH server, unless a AuthMethod was set with
|
// connect connects to the SSH server, unless a AuthMethod was set with
|
||||||
|
|
|
@ -102,14 +102,14 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
|
||||||
return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name)
|
return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := newSendPackSession(r.c.URLs[0], o.Auth)
|
s, err := newSendPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer ioutil.CheckClose(s, &err)
|
defer ioutil.CheckClose(s, &err)
|
||||||
|
|
||||||
ar, err := s.AdvertisedReferences()
|
ar, err := s.AdvertisedReferencesContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,10 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := r.checkRequireRemoteRefs(o.RequireRemoteRefs, remoteRefs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
isDelete := false
|
isDelete := false
|
||||||
allDelete := true
|
allDelete := true
|
||||||
for _, rs := range o.RefSpecs {
|
for _, rs := range o.RefSpecs {
|
||||||
|
@ -309,14 +313,14 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
|
||||||
o.RefSpecs = r.c.Fetch
|
o.RefSpecs = r.c.Fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := newUploadPackSession(r.c.URLs[0], o.Auth)
|
s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer ioutil.CheckClose(s, &err)
|
defer ioutil.CheckClose(s, &err)
|
||||||
|
|
||||||
ar, err := s.AdvertisedReferences()
|
ar, err := s.AdvertisedReferencesContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -369,8 +373,8 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
|
||||||
return remoteRefs, nil
|
return remoteRefs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUploadPackSession(url string, auth transport.AuthMethod) (transport.UploadPackSession, error) {
|
func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.UploadPackSession, error) {
|
||||||
c, ep, err := newClient(url)
|
c, ep, err := newClient(url, auth, insecure, cabundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -378,8 +382,8 @@ func newUploadPackSession(url string, auth transport.AuthMethod) (transport.Uplo
|
||||||
return c.NewUploadPackSession(ep, auth)
|
return c.NewUploadPackSession(ep, auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSendPackSession(url string, auth transport.AuthMethod) (transport.ReceivePackSession, error) {
|
func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.ReceivePackSession, error) {
|
||||||
c, ep, err := newClient(url)
|
c, ep, err := newClient(url, auth, insecure, cabundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -387,11 +391,13 @@ func newSendPackSession(url string, auth transport.AuthMethod) (transport.Receiv
|
||||||
return c.NewReceivePackSession(ep, auth)
|
return c.NewReceivePackSession(ep, auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClient(url string) (transport.Transport, *transport.Endpoint, error) {
|
func newClient(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.Transport, *transport.Endpoint, error) {
|
||||||
ep, err := transport.NewEndpoint(url)
|
ep, err := transport.NewEndpoint(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
ep.InsecureSkipTLS = insecure
|
||||||
|
ep.CaBundle = cabundle
|
||||||
|
|
||||||
c, err := client.NewClient(ep)
|
c, err := client.NewClient(ep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1025,14 +1031,14 @@ func (r *Remote) buildFetchedTags(refs memory.ReferenceStorage) (updated bool, e
|
||||||
|
|
||||||
// List the references on the remote repository.
|
// List the references on the remote repository.
|
||||||
func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) {
|
func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) {
|
||||||
s, err := newUploadPackSession(r.c.URLs[0], o.Auth)
|
s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer ioutil.CheckClose(s, &err)
|
defer ioutil.CheckClose(s, &err)
|
||||||
|
|
||||||
ar, err := s.AdvertisedReferences()
|
ar, err := s.AdvertisedReferencesContext(context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1164,3 +1170,33 @@ outer:
|
||||||
|
|
||||||
return r.s.SetShallow(shallows)
|
return r.s.SetShallow(shallows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Remote) checkRequireRemoteRefs(requires []config.RefSpec, remoteRefs storer.ReferenceStorer) error {
|
||||||
|
for _, require := range requires {
|
||||||
|
if require.IsWildcard() {
|
||||||
|
return fmt.Errorf("wildcards not supported in RequireRemoteRefs, got %s", require.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
name := require.Dst("")
|
||||||
|
remote, err := remoteRefs.Reference(name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("remote ref %s required to be %s but is absent", name.String(), require.Src())
|
||||||
|
}
|
||||||
|
|
||||||
|
var requireHash string
|
||||||
|
if require.IsExactSHA1() {
|
||||||
|
requireHash = require.Src()
|
||||||
|
} else {
|
||||||
|
target, err := storer.ResolveReference(remoteRefs, plumbing.ReferenceName(require.Src()))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not resolve ref %s in RequireRemoteRefs", require.Src())
|
||||||
|
}
|
||||||
|
requireHash = target.Hash().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if remote.Hash().String() != requireHash {
|
||||||
|
return fmt.Errorf("remote ref %s required to be %s but is %s", name.String(), requireHash, remote.Hash().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -841,12 +841,14 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
|
ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
|
||||||
RefSpecs: c.Fetch,
|
RefSpecs: c.Fetch,
|
||||||
Depth: o.Depth,
|
Depth: o.Depth,
|
||||||
Auth: o.Auth,
|
Auth: o.Auth,
|
||||||
Progress: o.Progress,
|
Progress: o.Progress,
|
||||||
Tags: o.Tags,
|
Tags: o.Tags,
|
||||||
RemoteName: o.RemoteName,
|
RemoteName: o.RemoteName,
|
||||||
|
InsecureSkipTLS: o.InsecureSkipTLS,
|
||||||
|
CABundle: o.CABundle,
|
||||||
}, o.ReferenceName)
|
}, o.ReferenceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue