mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
Merge branch 'public-single-node' into pmm-6401-read-prometheus-data-files
This commit is contained in:
commit
1b389674c0
1807 changed files with 87 additions and 643021 deletions
|
@ -1,6 +1,8 @@
|
||||||
# tip
|
# tip
|
||||||
|
|
||||||
|
|
||||||
|
# [v1.45.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.45.0)
|
||||||
|
|
||||||
* FEATURE: allow setting `-retentionPeriod` smaller than one month. I.e. `-retentionPeriod=3d`, `-retentionPeriod=2w`, etc. is supported now.
|
* FEATURE: allow setting `-retentionPeriod` smaller than one month. I.e. `-retentionPeriod=3d`, `-retentionPeriod=2w`, etc. is supported now.
|
||||||
See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/173
|
See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/173
|
||||||
* FEATURE: optimize more cases according to https://utcc.utoronto.ca/~cks/space/blog/sysadmin/PrometheusLabelNonOptimization . Now the following cases are optimized too:
|
* FEATURE: optimize more cases according to https://utcc.utoronto.ca/~cks/space/blog/sysadmin/PrometheusLabelNonOptimization . Now the following cases are optimized too:
|
||||||
|
@ -12,7 +14,7 @@
|
||||||
* FEATURE: vmagent: add `stream parse` mode. This mode allows reducing memory usage when individual scrape targets expose tens of millions of metrics.
|
* FEATURE: vmagent: add `stream parse` mode. This mode allows reducing memory usage when individual scrape targets expose tens of millions of metrics.
|
||||||
For example, during scraping Prometheus in [federation](https://prometheus.io/docs/prometheus/latest/federation/) mode.
|
For example, during scraping Prometheus in [federation](https://prometheus.io/docs/prometheus/latest/federation/) mode.
|
||||||
See `-promscrape.streamParse` command-line option and `stream_parse: true` config option for `scrape_config` section in `-promscrape.config`.
|
See `-promscrape.streamParse` command-line option and `stream_parse: true` config option for `scrape_config` section in `-promscrape.config`.
|
||||||
See also [troubleshooting docs for vmagent](https://victoriametrics.github.io/vmagent.html#troubleshooting).
|
See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/825 and [troubleshooting docs for vmagent](https://victoriametrics.github.io/vmagent.html#troubleshooting).
|
||||||
* FEATURE: vmalert: add `-dryRun` command-line option for validating the provided config files without the need to start `vmalert` service.
|
* FEATURE: vmalert: add `-dryRun` command-line option for validating the provided config files without the need to start `vmalert` service.
|
||||||
* FEATURE: accept optional third argument of string type at `topk_*` and `bottomk_*` functions. This is label name for additional time series to return with the sum of time series outside top/bottom K. See [MetricsQL docs](https://victoriametrics.github.io/MetricsQL.html) for more details.
|
* FEATURE: accept optional third argument of string type at `topk_*` and `bottomk_*` functions. This is label name for additional time series to return with the sum of time series outside top/bottom K. See [MetricsQL docs](https://victoriametrics.github.io/MetricsQL.html) for more details.
|
||||||
* FEATURE: vmagent: expose `/api/v1/targets` page according to [the corresponding Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/#targets).
|
* FEATURE: vmagent: expose `/api/v1/targets` page according to [the corresponding Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/#targets).
|
||||||
|
|
|
@ -93,8 +93,7 @@ func InitWithoutMetrics() {
|
||||||
logger.Infof("successfully opened storage %q in %.3f seconds; partsCount: %d; blocksCount: %d; rowsCount: %d; sizeBytes: %d",
|
logger.Infof("successfully opened storage %q in %.3f seconds; partsCount: %d; blocksCount: %d; rowsCount: %d; sizeBytes: %d",
|
||||||
*DataPath, time.Since(startTime).Seconds(), partsCount, blocksCount, rowsCount, sizeBytes)
|
*DataPath, time.Since(startTime).Seconds(), partsCount, blocksCount, rowsCount, sizeBytes)
|
||||||
|
|
||||||
retentionMsecs := (int64(*retentionPeriod) * 3600 * 24 * 30) * 1000
|
promdb.Init(retentionPeriod.Msecs)
|
||||||
promdb.Init(retentionMsecs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Storage is a storage.
|
// Storage is a storage.
|
||||||
|
|
19
go.mod
19
go.mod
|
@ -1,7 +1,7 @@
|
||||||
module github.com/VictoriaMetrics/VictoriaMetrics
|
module github.com/VictoriaMetrics/VictoriaMetrics
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.69.1 // indirect
|
cloud.google.com/go v0.71.0 // indirect
|
||||||
cloud.google.com/go/storage v1.12.0
|
cloud.google.com/go/storage v1.12.0
|
||||||
github.com/VictoriaMetrics/fastcache v1.5.7
|
github.com/VictoriaMetrics/fastcache v1.5.7
|
||||||
|
|
||||||
|
@ -10,13 +10,12 @@ require (
|
||||||
github.com/VictoriaMetrics/fasthttp v1.0.7
|
github.com/VictoriaMetrics/fasthttp v1.0.7
|
||||||
github.com/VictoriaMetrics/metrics v1.12.3
|
github.com/VictoriaMetrics/metrics v1.12.3
|
||||||
github.com/VictoriaMetrics/metricsql v0.7.2
|
github.com/VictoriaMetrics/metricsql v0.7.2
|
||||||
github.com/aws/aws-sdk-go v1.35.8
|
github.com/aws/aws-sdk-go v1.35.20
|
||||||
github.com/cespare/xxhash/v2 v2.1.1
|
github.com/cespare/xxhash/v2 v2.1.1
|
||||||
github.com/go-kit/kit v0.10.0
|
github.com/go-kit/kit v0.10.0
|
||||||
github.com/golang/snappy v0.0.2
|
github.com/golang/snappy v0.0.2
|
||||||
github.com/klauspost/compress v1.11.1
|
github.com/klauspost/compress v1.11.2
|
||||||
github.com/prometheus/common v0.14.0 // indirect
|
github.com/prometheus/client_golang v1.8.0 // indirect
|
||||||
github.com/prometheus/procfs v0.2.0 // indirect
|
|
||||||
github.com/prometheus/prometheus v1.8.2-0.20200911110723-e83ef207b6c2
|
github.com/prometheus/prometheus v1.8.2-0.20200911110723-e83ef207b6c2
|
||||||
github.com/valyala/fastjson v1.6.1
|
github.com/valyala/fastjson v1.6.1
|
||||||
github.com/valyala/fastrand v1.0.0
|
github.com/valyala/fastrand v1.0.0
|
||||||
|
@ -24,9 +23,15 @@ require (
|
||||||
github.com/valyala/gozstd v1.8.3
|
github.com/valyala/gozstd v1.8.3
|
||||||
github.com/valyala/histogram v1.1.2
|
github.com/valyala/histogram v1.1.2
|
||||||
github.com/valyala/quicktemplate v1.6.3
|
github.com/valyala/quicktemplate v1.6.3
|
||||||
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
|
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
|
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1
|
||||||
google.golang.org/api v0.33.0
|
golang.org/x/text v0.3.4 // indirect
|
||||||
|
golang.org/x/tools v0.0.0-20201102192140-3288bc1ea189 // indirect
|
||||||
|
google.golang.org/api v0.34.0
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.3.0
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
63
go.sum
63
go.sum
|
@ -16,8 +16,8 @@ cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZ
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||||
cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
|
cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
|
||||||
cloud.google.com/go v0.69.1 h1:01WAtK12Fes1PhlpkgDf6iifgXbrdczf+6Cec2S+Aa8=
|
cloud.google.com/go v0.71.0 h1:2ha722Z08cmRa0orJrzBaszYQcLbLFcsZHsGSj/kIF4=
|
||||||
cloud.google.com/go v0.69.1/go.mod h1:nBQK+D2Y4slKAj03c6wkILB3imWdzebeEZgWHEmGREE=
|
cloud.google.com/go v0.71.0/go.mod h1:qZfY4Y7AEIQwG/fQYD3xrxLNkQZ0Xzf3HGeqCkA6LVM=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||||
|
@ -114,8 +114,8 @@ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:o
|
||||||
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.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||||
github.com/aws/aws-sdk-go v1.35.8 h1:+S3BTWePYImKLh7DUJxMVm+/FQUnmHADsMzo/psHFr4=
|
github.com/aws/aws-sdk-go v1.35.20 h1:Hs7x9Czh+MMPnZLQqHhsuZKeNFA3Vuf7pdy2r5QlVb0=
|
||||||
github.com/aws/aws-sdk-go v1.35.8/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
github.com/aws/aws-sdk-go v1.35.20/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||||
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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
@ -323,8 +323,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||||
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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
|
||||||
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/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 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
|
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
|
||||||
|
@ -346,8 +347,9 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||||
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 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
|
||||||
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=
|
||||||
|
github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60=
|
||||||
|
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
|
@ -356,10 +358,11 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
|
@ -461,8 +464,8 @@ github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||||
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.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE=
|
github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
|
||||||
github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
||||||
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
|
@ -594,8 +597,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
|
||||||
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.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
||||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
|
||||||
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.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
|
||||||
|
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
|
||||||
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=
|
||||||
|
@ -728,8 +732,9 @@ go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
|
||||||
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.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.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
@ -835,8 +840,10 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
|
||||||
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -852,8 +859,9 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
|
||||||
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 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-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=
|
||||||
|
@ -914,15 +922,18 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200821140526-fda516888d29/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200821140526-fda516888d29/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
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 h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
|
||||||
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-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
|
||||||
|
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
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=
|
||||||
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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.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/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||||
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -996,8 +1007,9 @@ golang.org/x/tools v0.0.0-20200828161849-5deb26317202/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-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752 h1:2ntEwh02rqo2jSsrYmp4yKHHjh0CbXP3ZtSUetSB+q8=
|
golang.org/x/tools v0.0.0-20201030143252-cf7a54d06671/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20201102192140-3288bc1ea189 h1:kGUouAJ2swN6lr5GMIBsG7SxclipIMTt/INfuVCSKIY=
|
||||||
|
golang.org/x/tools v0.0.0-20201102192140-3288bc1ea189/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -1028,16 +1040,17 @@ google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSr
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||||
google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
|
google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
|
||||||
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||||
google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw=
|
google.golang.org/api v0.34.0 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A=
|
||||||
google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
@ -1076,8 +1089,9 @@ google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6D
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9 h1:fG84H9C3EXfuDlzkG+VEPDYHHExklP6scH1QZ5gQTqU=
|
google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0 h1:d0rYPqjQfVuFe+tZgv4PHt2hNxK79MRXX7PaD/A5ynA=
|
||||||
|
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||||
|
@ -1096,8 +1110,9 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
|
|
||||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
|
google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc=
|
||||||
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
|
|
|
@ -103,9 +103,6 @@ type indexDB struct {
|
||||||
|
|
||||||
mustDrop uint64
|
mustDrop uint64
|
||||||
|
|
||||||
// Start date fully covered by per-day inverted index.
|
|
||||||
startDateForPerDayInvertedIndex uint64
|
|
||||||
|
|
||||||
name string
|
name string
|
||||||
tb *mergeset.Table
|
tb *mergeset.Table
|
||||||
|
|
||||||
|
@ -186,15 +183,6 @@ func openIndexDB(path string, metricIDCache, metricNameCache, tsidCache *working
|
||||||
return nil, fmt.Errorf("cannot load deleted metricIDs: %w", err)
|
return nil, fmt.Errorf("cannot load deleted metricIDs: %w", err)
|
||||||
}
|
}
|
||||||
db.setDeletedMetricIDs(dmis)
|
db.setDeletedMetricIDs(dmis)
|
||||||
|
|
||||||
is = db.getIndexSearch(noDeadline)
|
|
||||||
date, err := is.getStartDateForPerDayInvertedIndex()
|
|
||||||
db.putIndexSearch(is)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot obtain start date for per-day inverted index: %w", err)
|
|
||||||
}
|
|
||||||
db.startDateForPerDayInvertedIndex = date
|
|
||||||
|
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1406,36 +1394,6 @@ func (db *indexDB) updateDeletedMetricIDs(metricIDs *uint64set.Set) {
|
||||||
db.deletedMetricIDsUpdateLock.Unlock()
|
db.deletedMetricIDsUpdateLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *indexSearch) getStartDateForPerDayInvertedIndex() (uint64, error) {
|
|
||||||
kb := &is.kb
|
|
||||||
ts := &is.ts
|
|
||||||
kb.B = append(kb.B[:0], nsPrefixDateTagToMetricIDs)
|
|
||||||
prefix := kb.B
|
|
||||||
ts.Seek(kb.B)
|
|
||||||
if ts.NextItem() {
|
|
||||||
item := ts.Item
|
|
||||||
if !bytes.HasPrefix(item, prefix) {
|
|
||||||
// The databse doesn't contain per-day inverted index yet.
|
|
||||||
// Return the minimum possible date, i.e. 0.
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
suffix := item[len(prefix):]
|
|
||||||
|
|
||||||
// Suffix must contain encoded 64-bit date.
|
|
||||||
if len(suffix) < 8 {
|
|
||||||
return 0, fmt.Errorf("unexpected (date, tag)->metricIDs row len; must be at least 8 bytes; got %d bytes", len(suffix))
|
|
||||||
}
|
|
||||||
minDate := encoding.UnmarshalUint64(suffix)
|
|
||||||
return minDate, nil
|
|
||||||
}
|
|
||||||
if err := ts.Error(); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
// There are no (date,tag)->metricIDs entries in the database yet.
|
|
||||||
// Return the minimum possible date, i.e. 0.
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (is *indexSearch) loadDeletedMetricIDs() (*uint64set.Set, error) {
|
func (is *indexSearch) loadDeletedMetricIDs() (*uint64set.Set, error) {
|
||||||
dmis := &uint64set.Set{}
|
dmis := &uint64set.Set{}
|
||||||
ts := &is.ts
|
ts := &is.ts
|
||||||
|
@ -1780,14 +1738,6 @@ func (is *indexSearch) getTagFilterWithMinMetricIDsCountOptimized(tfs *TagFilter
|
||||||
maxTimeRangeMetrics := 20 * maxMetrics
|
maxTimeRangeMetrics := 20 * maxMetrics
|
||||||
metricIDsForTimeRange, err := is.getMetricIDsForTimeRange(tr, maxTimeRangeMetrics+1)
|
metricIDsForTimeRange, err := is.getMetricIDsForTimeRange(tr, maxTimeRangeMetrics+1)
|
||||||
if err == errMissingMetricIDsForDate {
|
if err == errMissingMetricIDsForDate {
|
||||||
// Slow path: try to find the tag filter without maxMetrics adjustement.
|
|
||||||
minTf, minMetricIDs, err = is.getTagFilterWithMinMetricIDsCountAdaptive(tfs, maxMetrics)
|
|
||||||
if err == nil {
|
|
||||||
return minTf, minMetricIDs, nil
|
|
||||||
}
|
|
||||||
if err != errTooManyMetrics {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return nil, nil, fmt.Errorf("cannot find tag filter matching less than %d time series; "+
|
return nil, nil, fmt.Errorf("cannot find tag filter matching less than %d time series; "+
|
||||||
"either increase -search.maxUniqueTimeseries or use more specific tag filters", maxMetrics)
|
"either increase -search.maxUniqueTimeseries or use more specific tag filters", maxMetrics)
|
||||||
}
|
}
|
||||||
|
@ -1797,15 +1747,6 @@ func (is *indexSearch) getTagFilterWithMinMetricIDsCountOptimized(tfs *TagFilter
|
||||||
if metricIDsForTimeRange.Len() <= maxTimeRangeMetrics {
|
if metricIDsForTimeRange.Len() <= maxTimeRangeMetrics {
|
||||||
return nil, metricIDsForTimeRange, nil
|
return nil, metricIDsForTimeRange, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slow path: try to select the tag filter without maxMetrics adjustement.
|
|
||||||
minTf, minMetricIDs, err = is.getTagFilterWithMinMetricIDsCountAdaptive(tfs, maxMetrics)
|
|
||||||
if err == nil {
|
|
||||||
return minTf, minMetricIDs, nil
|
|
||||||
}
|
|
||||||
if err != errTooManyMetrics {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return nil, nil, fmt.Errorf("more than %d time series found on the time range %s; either increase -search.maxUniqueTimeseries or shrink the time range",
|
return nil, nil, fmt.Errorf("more than %d time series found on the time range %s; either increase -search.maxUniqueTimeseries or shrink the time range",
|
||||||
maxMetrics, tr.String())
|
maxMetrics, tr.String())
|
||||||
}
|
}
|
||||||
|
@ -2498,7 +2439,7 @@ func (is *indexSearch) tryUpdatingMetricIDsForDateRange(metricIDs *uint64set.Set
|
||||||
atomic.AddUint64(&is.db.dateRangeSearchCalls, 1)
|
atomic.AddUint64(&is.db.dateRangeSearchCalls, 1)
|
||||||
minDate := uint64(tr.MinTimestamp) / msecPerDay
|
minDate := uint64(tr.MinTimestamp) / msecPerDay
|
||||||
maxDate := uint64(tr.MaxTimestamp) / msecPerDay
|
maxDate := uint64(tr.MaxTimestamp) / msecPerDay
|
||||||
if minDate < is.db.startDateForPerDayInvertedIndex || maxDate < minDate {
|
if maxDate < minDate {
|
||||||
// Per-day inverted index doesn't cover the selected date range.
|
// Per-day inverted index doesn't cover the selected date range.
|
||||||
return errFallbackToMetricNameMatch
|
return errFallbackToMetricNameMatch
|
||||||
}
|
}
|
||||||
|
@ -2627,8 +2568,6 @@ func (is *indexSearch) getMetricIDsForDateAndFilters(date uint64, tfs *TagFilter
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == errMissingMetricIDsForDate {
|
if err == errMissingMetricIDsForDate {
|
||||||
// Zero time series were written on the given date.
|
// Zero time series were written on the given date.
|
||||||
// It is OK, since (date, metricID) entries must exist for the given date
|
|
||||||
// according to startDateForPerDayInvertedIndex.
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("cannot obtain all the metricIDs: %w", err)
|
return nil, fmt.Errorf("cannot obtain all the metricIDs: %w", err)
|
||||||
|
@ -2848,11 +2787,6 @@ func (is *indexSearch) getMetricIDsForDate(date uint64, maxMetrics int) (*uint64
|
||||||
if err := is.updateMetricIDsForPrefix(kb.B, &metricIDs, maxMetrics); err != nil {
|
if err := is.updateMetricIDsForPrefix(kb.B, &metricIDs, maxMetrics); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if metricIDs.Len() == 0 {
|
|
||||||
// There are no metricIDs for the given date.
|
|
||||||
// This may be the case for old data where (data, __name__=value)->metricIDs entries weren't available.
|
|
||||||
return nil, errMissingMetricIDsForDate
|
|
||||||
}
|
|
||||||
return &metricIDs, nil
|
return &metricIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/uint64set"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/workingsetcache"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/workingsetcache"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1484,6 +1485,8 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
|
||||||
now := uint64(timestampFromTime(theDay))
|
now := uint64(timestampFromTime(theDay))
|
||||||
baseDate := now / msecPerDay
|
baseDate := now / msecPerDay
|
||||||
var metricNameBuf []byte
|
var metricNameBuf []byte
|
||||||
|
perDayMetricIDs := make(map[uint64]*uint64set.Set)
|
||||||
|
var allMetricIDs uint64set.Set
|
||||||
for day := 0; day < days; day++ {
|
for day := 0; day < days; day++ {
|
||||||
var tsids []TSID
|
var tsids []TSID
|
||||||
for metric := 0; metric < metricsPerDay; metric++ {
|
for metric := 0; metric < metricsPerDay; metric++ {
|
||||||
|
@ -1513,17 +1516,44 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
|
||||||
|
|
||||||
// Add the metrics to the per-day stores
|
// Add the metrics to the per-day stores
|
||||||
date := baseDate - uint64(day)
|
date := baseDate - uint64(day)
|
||||||
|
var metricIDs uint64set.Set
|
||||||
for i := range tsids {
|
for i := range tsids {
|
||||||
tsid := &tsids[i]
|
tsid := &tsids[i]
|
||||||
|
metricIDs.Add(tsid.MetricID)
|
||||||
if err := is.storeDateMetricID(date, tsid.MetricID); err != nil {
|
if err := is.storeDateMetricID(date, tsid.MetricID); err != nil {
|
||||||
t.Fatalf("error in storeDateMetricID(%d, %d): %s", date, tsid.MetricID, err)
|
t.Fatalf("error in storeDateMetricID(%d, %d): %s", date, tsid.MetricID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
allMetricIDs.Union(&metricIDs)
|
||||||
|
perDayMetricIDs[date] = &metricIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush index to disk, so it becomes visible for search
|
// Flush index to disk, so it becomes visible for search
|
||||||
db.tb.DebugFlush()
|
db.tb.DebugFlush()
|
||||||
|
|
||||||
|
is2 := db.getIndexSearch(noDeadline)
|
||||||
|
defer db.putIndexSearch(is2)
|
||||||
|
|
||||||
|
// Check that all the metrics are found for all the days.
|
||||||
|
for date := baseDate - days + 1; date <= baseDate; date++ {
|
||||||
|
metricIDs, err := is2.getMetricIDsForDate(date, metricsPerDay)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !perDayMetricIDs[date].Equal(metricIDs) {
|
||||||
|
t.Fatalf("unexpected metricIDs found;\ngot\n%d\nwant\n%d", metricIDs.AppendTo(nil), perDayMetricIDs[date].AppendTo(nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all the metrics are found in updateMetricIDsAll
|
||||||
|
var metricIDs uint64set.Set
|
||||||
|
if err := is2.updateMetricIDsAll(&metricIDs, metricsPerDay*days); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !allMetricIDs.Equal(&metricIDs) {
|
||||||
|
t.Fatalf("unexpected metricIDs found;\ngot\n%d\nwant\n%d", metricIDs.AppendTo(nil), allMetricIDs.AppendTo(nil))
|
||||||
|
}
|
||||||
|
|
||||||
// Create a filter that will match series that occur across multiple days
|
// Create a filter that will match series that occur across multiple days
|
||||||
tfs := NewTagFilters()
|
tfs := NewTagFilters()
|
||||||
if err := tfs.Add([]byte("constant"), []byte("const"), false, false); err != nil {
|
if err := tfs.Add([]byte("constant"), []byte("const"), false, false); err != nil {
|
||||||
|
|
|
@ -71,16 +71,7 @@ func TestSearchQueryMarshalUnmarshal(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSearch(t *testing.T) {
|
func TestSearch(t *testing.T) {
|
||||||
t.Run("global_inverted_index", func(t *testing.T) {
|
path := fmt.Sprintf("TestSearch")
|
||||||
testSearchGeneric(t, false)
|
|
||||||
})
|
|
||||||
t.Run("perday_inverted_index", func(t *testing.T) {
|
|
||||||
testSearchGeneric(t, true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testSearchGeneric(t *testing.T, forcePerDayInvertedIndex bool) {
|
|
||||||
path := fmt.Sprintf("TestSearch_%v", forcePerDayInvertedIndex)
|
|
||||||
st, err := OpenStorage(path, 0)
|
st, err := OpenStorage(path, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot open storage %q: %s", path, err)
|
t.Fatalf("cannot open storage %q: %s", path, err)
|
||||||
|
@ -134,13 +125,6 @@ func testSearchGeneric(t *testing.T, forcePerDayInvertedIndex bool) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot re-open storage %q: %s", path, err)
|
t.Fatalf("cannot re-open storage %q: %s", path, err)
|
||||||
}
|
}
|
||||||
if forcePerDayInvertedIndex {
|
|
||||||
idb := st.idb()
|
|
||||||
idb.startDateForPerDayInvertedIndex = 0
|
|
||||||
idb.doExtDB(func(extDB *indexDB) {
|
|
||||||
extDB.startDateForPerDayInvertedIndex = 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run search.
|
// Run search.
|
||||||
tr := TimeRange{
|
tr := TimeRange{
|
||||||
|
|
|
@ -1739,11 +1739,6 @@ func openIndexDBTables(path string, metricIDCache, metricNameCache, tsidCache *w
|
||||||
return nil, nil, fmt.Errorf("cannot open prev indexdb table at %q: %w", prevPath, err)
|
return nil, nil, fmt.Errorf("cannot open prev indexdb table at %q: %w", prevPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust startDateForPerDayInvertedIndex for the previous index.
|
|
||||||
if prev.startDateForPerDayInvertedIndex > curr.startDateForPerDayInvertedIndex {
|
|
||||||
prev.startDateForPerDayInvertedIndex = curr.startDateForPerDayInvertedIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
return curr, prev, nil
|
return curr, prev, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
vendor/cloud.google.com/go/.gitignore
generated
vendored
11
vendor/cloud.google.com/go/.gitignore
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
# Editors
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
*.swp
|
|
||||||
|
|
||||||
# Test files
|
|
||||||
*.test
|
|
||||||
coverage.txt
|
|
||||||
|
|
||||||
# Other
|
|
||||||
.DS_Store
|
|
1719
vendor/cloud.google.com/go/CHANGES.md
generated
vendored
1719
vendor/cloud.google.com/go/CHANGES.md
generated
vendored
File diff suppressed because it is too large
Load diff
44
vendor/cloud.google.com/go/CODE_OF_CONDUCT.md
generated
vendored
44
vendor/cloud.google.com/go/CODE_OF_CONDUCT.md
generated
vendored
|
@ -1,44 +0,0 @@
|
||||||
# Contributor Code of Conduct
|
|
||||||
|
|
||||||
As contributors and maintainers of this project,
|
|
||||||
and in the interest of fostering an open and welcoming community,
|
|
||||||
we pledge to respect all people who contribute through reporting issues,
|
|
||||||
posting feature requests, updating documentation,
|
|
||||||
submitting pull requests or patches, and other activities.
|
|
||||||
|
|
||||||
We are committed to making participation in this project
|
|
||||||
a harassment-free experience for everyone,
|
|
||||||
regardless of level of experience, gender, gender identity and expression,
|
|
||||||
sexual orientation, disability, personal appearance,
|
|
||||||
body size, race, ethnicity, age, religion, or nationality.
|
|
||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery
|
|
||||||
* Personal attacks
|
|
||||||
* Trolling or insulting/derogatory comments
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing other's private information,
|
|
||||||
such as physical or electronic
|
|
||||||
addresses, without explicit permission
|
|
||||||
* Other unethical or unprofessional conduct.
|
|
||||||
|
|
||||||
Project maintainers have the right and responsibility to remove, edit, or reject
|
|
||||||
comments, commits, code, wiki edits, issues, and other contributions
|
|
||||||
that are not aligned to this Code of Conduct.
|
|
||||||
By adopting this Code of Conduct,
|
|
||||||
project maintainers commit themselves to fairly and consistently
|
|
||||||
applying these principles to every aspect of managing this project.
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct
|
|
||||||
may be permanently removed from the project team.
|
|
||||||
|
|
||||||
This code of conduct applies both within project spaces and in public spaces
|
|
||||||
when an individual is representing the project or its community.
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior
|
|
||||||
may be reported by opening an issue
|
|
||||||
or contacting one or more of the project maintainers.
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
|
|
||||||
available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
|
||||||
|
|
260
vendor/cloud.google.com/go/CONTRIBUTING.md
generated
vendored
260
vendor/cloud.google.com/go/CONTRIBUTING.md
generated
vendored
|
@ -1,260 +0,0 @@
|
||||||
# Contributing
|
|
||||||
|
|
||||||
1. [File an issue](https://github.com/googleapis/google-cloud-go/issues/new/choose).
|
|
||||||
The issue will be used to discuss the bug or feature and should be created
|
|
||||||
before sending a CL.
|
|
||||||
|
|
||||||
1. [Install Go](https://golang.org/dl/).
|
|
||||||
1. Ensure that your `GOBIN` directory (by default `$(go env GOPATH)/bin`)
|
|
||||||
is in your `PATH`.
|
|
||||||
1. Check it's working by running `go version`.
|
|
||||||
* If it doesn't work, check the install location, usually
|
|
||||||
`/usr/local/go`, is on your `PATH`.
|
|
||||||
|
|
||||||
1. Sign one of the
|
|
||||||
[contributor license agreements](#contributor-license-agreements) below.
|
|
||||||
|
|
||||||
1. Clone the repo:
|
|
||||||
`git clone https://github.com/googleapis/google-cloud-go`
|
|
||||||
|
|
||||||
1. Change into the checked out source:
|
|
||||||
`cd google-cloud-go`
|
|
||||||
|
|
||||||
1. Fork the repo.
|
|
||||||
|
|
||||||
1. Set your fork as a remote:
|
|
||||||
`git remote add fork git@github.com:GITHUB_USERNAME/google-cloud-go.git`
|
|
||||||
|
|
||||||
1. Make changes, commit to your fork.
|
|
||||||
|
|
||||||
Commit messages should follow the
|
|
||||||
[Conventional Commits Style](https://www.conventionalcommits.org). The scope
|
|
||||||
portion should always be filled with the name of the package affected by the
|
|
||||||
changes being made. For example:
|
|
||||||
```
|
|
||||||
feat(functions): add gophers codelab
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Send a pull request with your changes.
|
|
||||||
|
|
||||||
To minimize friction, consider setting `Allow edits from maintainers` on the
|
|
||||||
PR, which will enable project committers and automation to update your PR.
|
|
||||||
|
|
||||||
1. A maintainer will review the pull request and make comments.
|
|
||||||
|
|
||||||
Prefer adding additional commits over amending and force-pushing since it can
|
|
||||||
be difficult to follow code reviews when the commit history changes.
|
|
||||||
|
|
||||||
Commits will be squashed when they're merged.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
We test code against two versions of Go, the minimum and maximum versions
|
|
||||||
supported by our clients. To see which versions these are checkout our
|
|
||||||
[README](README.md#supported-versions).
|
|
||||||
|
|
||||||
### Integration Tests
|
|
||||||
|
|
||||||
In addition to the unit tests, you may run the integration test suite. These
|
|
||||||
directions describe setting up your environment to run integration tests for
|
|
||||||
_all_ packages: note that many of these instructions may be redundant if you
|
|
||||||
intend only to run integration tests on a single package.
|
|
||||||
|
|
||||||
#### GCP Setup
|
|
||||||
|
|
||||||
To run the integrations tests, creation and configuration of two projects in
|
|
||||||
the Google Developers Console is required: one specifically for Firestore
|
|
||||||
integration tests, and another for all other integration tests. We'll refer to
|
|
||||||
these projects as "general project" and "Firestore project".
|
|
||||||
|
|
||||||
After creating each project, you must [create a service account](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount)
|
|
||||||
for each project. Ensure the project-level **Owner**
|
|
||||||
[IAM role](console.cloud.google.com/iam-admin/iam/project) role is added to
|
|
||||||
each service account. During the creation of the service account, you should
|
|
||||||
download the JSON credential file for use later.
|
|
||||||
|
|
||||||
Next, ensure the following APIs are enabled in the general project:
|
|
||||||
|
|
||||||
- BigQuery API
|
|
||||||
- BigQuery Data Transfer API
|
|
||||||
- Cloud Dataproc API
|
|
||||||
- Cloud Dataproc Control API Private
|
|
||||||
- Cloud Datastore API
|
|
||||||
- Cloud Firestore API
|
|
||||||
- Cloud Key Management Service (KMS) API
|
|
||||||
- Cloud Natural Language API
|
|
||||||
- Cloud OS Login API
|
|
||||||
- Cloud Pub/Sub API
|
|
||||||
- Cloud Resource Manager API
|
|
||||||
- Cloud Spanner API
|
|
||||||
- Cloud Speech API
|
|
||||||
- Cloud Translation API
|
|
||||||
- Cloud Video Intelligence API
|
|
||||||
- Cloud Vision API
|
|
||||||
- Compute Engine API
|
|
||||||
- Compute Engine Instance Group Manager API
|
|
||||||
- Container Registry API
|
|
||||||
- Firebase Rules API
|
|
||||||
- Google Cloud APIs
|
|
||||||
- Google Cloud Deployment Manager V2 API
|
|
||||||
- Google Cloud SQL
|
|
||||||
- Google Cloud Storage
|
|
||||||
- Google Cloud Storage JSON API
|
|
||||||
- Google Compute Engine Instance Group Updater API
|
|
||||||
- Google Compute Engine Instance Groups API
|
|
||||||
- Kubernetes Engine API
|
|
||||||
- Cloud Error Reporting API
|
|
||||||
|
|
||||||
Next, create a Datastore database in the general project, and a Firestore
|
|
||||||
database in the Firestore project.
|
|
||||||
|
|
||||||
Finally, in the general project, create an API key for the translate API:
|
|
||||||
|
|
||||||
- Go to GCP Developer Console.
|
|
||||||
- Navigate to APIs & Services > Credentials.
|
|
||||||
- Click Create Credentials > API Key.
|
|
||||||
- Save this key for use in `GCLOUD_TESTS_API_KEY` as described below.
|
|
||||||
|
|
||||||
#### Local Setup
|
|
||||||
|
|
||||||
Once the two projects are created and configured, set the following environment
|
|
||||||
variables:
|
|
||||||
|
|
||||||
- `GCLOUD_TESTS_GOLANG_PROJECT_ID`: Developers Console project's ID (e.g.
|
|
||||||
bamboo-shift-455) for the general project.
|
|
||||||
- `GCLOUD_TESTS_GOLANG_KEY`: The path to the JSON key file of the general
|
|
||||||
project's service account.
|
|
||||||
- `GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID`: Developers Console project's ID
|
|
||||||
(e.g. doorway-cliff-677) for the Firestore project.
|
|
||||||
- `GCLOUD_TESTS_GOLANG_FIRESTORE_KEY`: The path to the JSON key file of the
|
|
||||||
Firestore project's service account.
|
|
||||||
- `GCLOUD_TESTS_GOLANG_KEYRING`: The full name of the keyring for the tests,
|
|
||||||
in the form
|
|
||||||
"projects/P/locations/L/keyRings/R". The creation of this is described below.
|
|
||||||
- `GCLOUD_TESTS_API_KEY`: API key for using the Translate API.
|
|
||||||
- `GCLOUD_TESTS_GOLANG_ZONE`: Compute Engine zone.
|
|
||||||
|
|
||||||
Install the [gcloud command-line tool][gcloudcli] to your machine and use it to
|
|
||||||
create some resources used in integration tests.
|
|
||||||
|
|
||||||
From the project's root directory:
|
|
||||||
|
|
||||||
``` sh
|
|
||||||
# Sets the default project in your env.
|
|
||||||
$ gcloud config set project $GCLOUD_TESTS_GOLANG_PROJECT_ID
|
|
||||||
|
|
||||||
# Authenticates the gcloud tool with your account.
|
|
||||||
$ gcloud auth login
|
|
||||||
|
|
||||||
# Create the indexes used in the datastore integration tests.
|
|
||||||
$ gcloud datastore indexes create datastore/testdata/index.yaml
|
|
||||||
|
|
||||||
# Creates a Google Cloud storage bucket with the same name as your test project,
|
|
||||||
# and with the Cloud Logging service account as owner, for the sink
|
|
||||||
# integration tests in logging.
|
|
||||||
$ gsutil mb gs://$GCLOUD_TESTS_GOLANG_PROJECT_ID
|
|
||||||
$ gsutil acl ch -g cloud-logs@google.com:O gs://$GCLOUD_TESTS_GOLANG_PROJECT_ID
|
|
||||||
|
|
||||||
# Creates a PubSub topic for integration tests of storage notifications.
|
|
||||||
$ gcloud beta pubsub topics create go-storage-notification-test
|
|
||||||
# Next, go to the Pub/Sub dashboard in GCP console. Authorize the user
|
|
||||||
# "service-<numberic project id>@gs-project-accounts.iam.gserviceaccount.com"
|
|
||||||
# as a publisher to that topic.
|
|
||||||
|
|
||||||
# Creates a Spanner instance for the spanner integration tests.
|
|
||||||
$ gcloud beta spanner instances create go-integration-test --config regional-us-central1 --nodes 10 --description 'Instance for go client test'
|
|
||||||
# NOTE: Spanner instances are priced by the node-hour, so you may want to
|
|
||||||
# delete the instance after testing with 'gcloud beta spanner instances delete'.
|
|
||||||
|
|
||||||
$ export MY_KEYRING=some-keyring-name
|
|
||||||
$ export MY_LOCATION=global
|
|
||||||
# Creates a KMS keyring, in the same location as the default location for your
|
|
||||||
# project's buckets.
|
|
||||||
$ gcloud kms keyrings create $MY_KEYRING --location $MY_LOCATION
|
|
||||||
# Creates two keys in the keyring, named key1 and key2.
|
|
||||||
$ gcloud kms keys create key1 --keyring $MY_KEYRING --location $MY_LOCATION --purpose encryption
|
|
||||||
$ gcloud kms keys create key2 --keyring $MY_KEYRING --location $MY_LOCATION --purpose encryption
|
|
||||||
# Sets the GCLOUD_TESTS_GOLANG_KEYRING environment variable.
|
|
||||||
$ export GCLOUD_TESTS_GOLANG_KEYRING=projects/$GCLOUD_TESTS_GOLANG_PROJECT_ID/locations/$MY_LOCATION/keyRings/$MY_KEYRING
|
|
||||||
# Authorizes Google Cloud Storage to encrypt and decrypt using key1.
|
|
||||||
gsutil kms authorize -p $GCLOUD_TESTS_GOLANG_PROJECT_ID -k $GCLOUD_TESTS_GOLANG_KEYRING/cryptoKeys/key1
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Running
|
|
||||||
|
|
||||||
Once you've done the necessary setup, you can run the integration tests by
|
|
||||||
running:
|
|
||||||
|
|
||||||
``` sh
|
|
||||||
$ go test -v cloud.google.com/go/...
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Replay
|
|
||||||
|
|
||||||
Some packages can record the RPCs during integration tests to a file for
|
|
||||||
subsequent replay. To record, pass the `-record` flag to `go test`. The
|
|
||||||
recording will be saved to the _package_`.replay` file. To replay integration
|
|
||||||
tests from a saved recording, the replay file must be present, the `-short`
|
|
||||||
flag must be passed to `go test`, and the `GCLOUD_TESTS_GOLANG_ENABLE_REPLAY`
|
|
||||||
environment variable must have a non-empty value.
|
|
||||||
|
|
||||||
## Contributor License Agreements
|
|
||||||
|
|
||||||
Before we can accept your pull requests you'll need to sign a Contributor
|
|
||||||
License Agreement (CLA):
|
|
||||||
|
|
||||||
- **If you are an individual writing original source code** and **you own the
|
|
||||||
intellectual property**, then you'll need to sign an [individual CLA][indvcla].
|
|
||||||
- **If you work for a company that wants to allow you to contribute your
|
|
||||||
work**, then you'll need to sign a [corporate CLA][corpcla].
|
|
||||||
|
|
||||||
You can sign these electronically (just scroll to the bottom). After that,
|
|
||||||
we'll be able to accept your pull requests.
|
|
||||||
|
|
||||||
## Contributor Code of Conduct
|
|
||||||
|
|
||||||
As contributors and maintainers of this project,
|
|
||||||
and in the interest of fostering an open and welcoming community,
|
|
||||||
we pledge to respect all people who contribute through reporting issues,
|
|
||||||
posting feature requests, updating documentation,
|
|
||||||
submitting pull requests or patches, and other activities.
|
|
||||||
|
|
||||||
We are committed to making participation in this project
|
|
||||||
a harassment-free experience for everyone,
|
|
||||||
regardless of level of experience, gender, gender identity and expression,
|
|
||||||
sexual orientation, disability, personal appearance,
|
|
||||||
body size, race, ethnicity, age, religion, or nationality.
|
|
||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery
|
|
||||||
* Personal attacks
|
|
||||||
* Trolling or insulting/derogatory comments
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing other's private information,
|
|
||||||
such as physical or electronic
|
|
||||||
addresses, without explicit permission
|
|
||||||
* Other unethical or unprofessional conduct.
|
|
||||||
|
|
||||||
Project maintainers have the right and responsibility to remove, edit, or reject
|
|
||||||
comments, commits, code, wiki edits, issues, and other contributions
|
|
||||||
that are not aligned to this Code of Conduct.
|
|
||||||
By adopting this Code of Conduct,
|
|
||||||
project maintainers commit themselves to fairly and consistently
|
|
||||||
applying these principles to every aspect of managing this project.
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct
|
|
||||||
may be permanently removed from the project team.
|
|
||||||
|
|
||||||
This code of conduct applies both within project spaces and in public spaces
|
|
||||||
when an individual is representing the project or its community.
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior
|
|
||||||
may be reported by opening an issue
|
|
||||||
or contacting one or more of the project maintainers.
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
|
|
||||||
available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
|
||||||
|
|
||||||
[gcloudcli]: https://developers.google.com/cloud/sdk/gcloud/
|
|
||||||
[indvcla]: https://developers.google.com/open-source/cla/individual
|
|
||||||
[corpcla]: https://developers.google.com/open-source/cla/corporate
|
|
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
177
vendor/cloud.google.com/go/README.md
generated
vendored
177
vendor/cloud.google.com/go/README.md
generated
vendored
|
@ -1,177 +0,0 @@
|
||||||
# Google Cloud Client Libraries for Go
|
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/cloud.google.com/go?status.svg)](https://pkg.go.dev/cloud.google.com/go)
|
|
||||||
|
|
||||||
Go packages for [Google Cloud Platform](https://cloud.google.com) services.
|
|
||||||
|
|
||||||
``` go
|
|
||||||
import "cloud.google.com/go"
|
|
||||||
```
|
|
||||||
|
|
||||||
To install the packages on your system, *do not clone the repo*. Instead:
|
|
||||||
|
|
||||||
1. Change to your project directory:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd /my/cloud/project
|
|
||||||
```
|
|
||||||
1. Get the package you want to use. Some products have their own module, so it's
|
|
||||||
best to `go get` the package(s) you want to use:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get cloud.google.com/go/firestore # Replace with the package you want to use.
|
|
||||||
```
|
|
||||||
|
|
||||||
**NOTE:** Some of these packages are under development, and may occasionally
|
|
||||||
make backwards-incompatible changes.
|
|
||||||
|
|
||||||
**NOTE:** Github repo is a mirror of [https://code.googlesource.com/gocloud](https://code.googlesource.com/gocloud).
|
|
||||||
|
|
||||||
## Supported APIs
|
|
||||||
|
|
||||||
| Google API | Status | Package |
|
|
||||||
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| [Asset][cloud-asset] | stable | [`cloud.google.com/go/asset/apiv1`](https://pkg.go.dev/cloud.google.com/go/asset/v1beta) |
|
|
||||||
| [Automl][cloud-automl] | stable | [`cloud.google.com/go/automl/apiv1`](https://pkg.go.dev/cloud.google.com/go/automl/apiv1) |
|
|
||||||
| [BigQuery][cloud-bigquery] | stable | [`cloud.google.com/go/bigquery`](https://pkg.go.dev/cloud.google.com/go/bigquery) |
|
|
||||||
| [Bigtable][cloud-bigtable] | stable | [`cloud.google.com/go/bigtable`](https://pkg.go.dev/cloud.google.com/go/bigtable) |
|
|
||||||
| [Cloudbuild][cloud-build] | stable | [`cloud.google.com/go/cloudbuild/apiv1`](https://pkg.go.dev/cloud.google.com/go/cloudbuild/apiv1) |
|
|
||||||
| [Cloudtasks][cloud-tasks] | stable | [`cloud.google.com/go/cloudtasks/apiv2`](https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2) |
|
|
||||||
| [Container][cloud-container] | stable | [`cloud.google.com/go/container/apiv1`](https://pkg.go.dev/cloud.google.com/go/container/apiv1) |
|
|
||||||
| [ContainerAnalysis][cloud-containeranalysis] | beta | [`cloud.google.com/go/containeranalysis/apiv1`](https://pkg.go.dev/cloud.google.com/go/containeranalysis/apiv1) |
|
|
||||||
| [Dataproc][cloud-dataproc] | stable | [`cloud.google.com/go/dataproc/apiv1`](https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1) |
|
|
||||||
| [Datastore][cloud-datastore] | stable | [`cloud.google.com/go/datastore`](https://pkg.go.dev/cloud.google.com/go/datastore) |
|
|
||||||
| [Debugger][cloud-debugger] | stable | [`cloud.google.com/go/debugger/apiv2`](https://pkg.go.dev/cloud.google.com/go/debugger/apiv2) |
|
|
||||||
| [Dialogflow][cloud-dialogflow] | stable | [`cloud.google.com/go/dialogflow/apiv2`](https://pkg.go.dev/cloud.google.com/go/dialogflow/apiv2) |
|
|
||||||
| [Data Loss Prevention][cloud-dlp] | stable | [`cloud.google.com/go/dlp/apiv2`](https://pkg.go.dev/cloud.google.com/go/dlp/apiv2) |
|
|
||||||
| [ErrorReporting][cloud-errors] | alpha | [`cloud.google.com/go/errorreporting`](https://pkg.go.dev/cloud.google.com/go/errorreporting) |
|
|
||||||
| [Firestore][cloud-firestore] | stable | [`cloud.google.com/go/firestore`](https://pkg.go.dev/cloud.google.com/go/firestore) |
|
|
||||||
| [IAM][cloud-iam] | stable | [`cloud.google.com/go/iam`](https://pkg.go.dev/cloud.google.com/go/iam) |
|
|
||||||
| [IoT][cloud-iot] | stable | [`cloud.google.com/go/iot/apiv1`](https://pkg.go.dev/cloud.google.com/go/iot/apiv1) |
|
|
||||||
| [IRM][cloud-irm] | alpha | [`cloud.google.com/go/irm/apiv1alpha2`](https://pkg.go.dev/cloud.google.com/go/irm/apiv1alpha2) |
|
|
||||||
| [KMS][cloud-kms] | stable | [`cloud.google.com/go/kms/apiv1`](https://pkg.go.dev/cloud.google.com/go/kms/apiv1) |
|
|
||||||
| [Natural Language][cloud-natural-language] | stable | [`cloud.google.com/go/language/apiv1`](https://pkg.go.dev/cloud.google.com/go/language/apiv1) |
|
|
||||||
| [Logging][cloud-logging] | stable | [`cloud.google.com/go/logging`](https://pkg.go.dev/cloud.google.com/go/logging) |
|
|
||||||
| [Memorystore][cloud-memorystore] | alpha | [`cloud.google.com/go/redis/apiv1`](https://pkg.go.dev/cloud.google.com/go/redis/apiv1) |
|
|
||||||
| [Monitoring][cloud-monitoring] | stable | [`cloud.google.com/go/monitoring/apiv3`](https://pkg.go.dev/cloud.google.com/go/monitoring/apiv3) |
|
|
||||||
| [OS Login][cloud-oslogin] | stable | [`cloud.google.com/go/oslogin/apiv1`](https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1) |
|
|
||||||
| [Pub/Sub][cloud-pubsub] | stable | [`cloud.google.com/go/pubsub`](https://pkg.go.dev/cloud.google.com/go/pubsub) |
|
|
||||||
| [Phishing Protection][cloud-phishingprotection] | alpha | [`cloud.google.com/go/phishingprotection/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/phishingprotection/apiv1beta1) |
|
|
||||||
| [reCAPTCHA Enterprise][cloud-recaptcha] | alpha | [`cloud.google.com/go/recaptchaenterprise/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/recaptchaenterprise/apiv1beta1) |
|
|
||||||
| [Recommender][cloud-recommender] | beta | [`cloud.google.com/go/recommender/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/recommender/apiv1beta1) |
|
|
||||||
| [Scheduler][cloud-scheduler] | stable | [`cloud.google.com/go/scheduler/apiv1`](https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1) |
|
|
||||||
| [Securitycenter][cloud-securitycenter] | stable | [`cloud.google.com/go/securitycenter/apiv1`](https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1) |
|
|
||||||
| [Spanner][cloud-spanner] | stable | [`cloud.google.com/go/spanner`](https://pkg.go.dev/cloud.google.com/go/spanner) |
|
|
||||||
| [Speech][cloud-speech] | stable | [`cloud.google.com/go/speech/apiv1`](https://pkg.go.dev/cloud.google.com/go/speech/apiv1) |
|
|
||||||
| [Storage][cloud-storage] | stable | [`cloud.google.com/go/storage`](https://pkg.go.dev/cloud.google.com/go/storage) |
|
|
||||||
| [Talent][cloud-talent] | alpha | [`cloud.google.com/go/talent/apiv4beta1`](https://pkg.go.dev/cloud.google.com/go/talent/apiv4beta1) |
|
|
||||||
| [Text To Speech][cloud-texttospeech] | stable | [`cloud.google.com/go/texttospeech/apiv1`](https://pkg.go.dev/cloud.google.com/go/texttospeech/apiv1) |
|
|
||||||
| [Trace][cloud-trace] | stable | [`cloud.google.com/go/trace/apiv2`](https://pkg.go.dev/cloud.google.com/go/trace/apiv2) |
|
|
||||||
| [Translate][cloud-translate] | stable | [`cloud.google.com/go/translate`](https://pkg.go.dev/cloud.google.com/go/translate) |
|
|
||||||
| [Video Intelligence][cloud-video] | beta | [`cloud.google.com/go/videointelligence/apiv1beta2`](https://pkg.go.dev/cloud.google.com/go/videointelligence/apiv1beta2) |
|
|
||||||
| [Vision][cloud-vision] | stable | [`cloud.google.com/go/vision/apiv1`](https://pkg.go.dev/cloud.google.com/go/vision/apiv1) |
|
|
||||||
| [Webrisk][cloud-webrisk] | alpha | [`cloud.google.com/go/webrisk/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/webrisk/apiv1beta1) |
|
|
||||||
|
|
||||||
> **Alpha status**: the API is still being actively developed. As a
|
|
||||||
> result, it might change in backward-incompatible ways and is not recommended
|
|
||||||
> for production use.
|
|
||||||
>
|
|
||||||
> **Beta status**: the API is largely complete, but still has outstanding
|
|
||||||
> features and bugs to be addressed. There may be minor backwards-incompatible
|
|
||||||
> changes where necessary.
|
|
||||||
>
|
|
||||||
> **Stable status**: the API is mature and ready for production use. We will
|
|
||||||
> continue addressing bugs and feature requests.
|
|
||||||
|
|
||||||
Documentation and examples are available at [pkg.go.dev/cloud.google.com/go](https://pkg.go.dev/cloud.google.com/go)
|
|
||||||
|
|
||||||
## [Go Versions Supported](#supported-versions)
|
|
||||||
|
|
||||||
We currently support Go versions 1.11 and newer.
|
|
||||||
|
|
||||||
## Authorization
|
|
||||||
|
|
||||||
By default, each API will use [Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials)
|
|
||||||
for authorization credentials used in calling the API endpoints. This will allow your
|
|
||||||
application to run in many environments without requiring explicit configuration.
|
|
||||||
|
|
||||||
[snip]:# (auth)
|
|
||||||
```go
|
|
||||||
client, err := storage.NewClient(ctx)
|
|
||||||
```
|
|
||||||
|
|
||||||
To authorize using a
|
|
||||||
[JSON key file](https://cloud.google.com/iam/docs/managing-service-account-keys),
|
|
||||||
pass
|
|
||||||
[`option.WithCredentialsFile`](https://pkg.go.dev/google.golang.org/api/option#WithCredentialsFile)
|
|
||||||
to the `NewClient` function of the desired package. For example:
|
|
||||||
|
|
||||||
[snip]:# (auth-JSON)
|
|
||||||
```go
|
|
||||||
client, err := storage.NewClient(ctx, option.WithCredentialsFile("path/to/keyfile.json"))
|
|
||||||
```
|
|
||||||
|
|
||||||
You can exert more control over authorization by using the
|
|
||||||
[`golang.org/x/oauth2`](https://pkg.go.dev/golang.org/x/oauth2) package to
|
|
||||||
create an `oauth2.TokenSource`. Then pass
|
|
||||||
[`option.WithTokenSource`](https://pkg.go.dev/google.golang.org/api/option#WithTokenSource)
|
|
||||||
to the `NewClient` function:
|
|
||||||
[snip]:# (auth-ts)
|
|
||||||
```go
|
|
||||||
tokenSource := ...
|
|
||||||
client, err := storage.NewClient(ctx, option.WithTokenSource(tokenSource))
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are welcome. Please, see the
|
|
||||||
[CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/CONTRIBUTING.md)
|
|
||||||
document for details.
|
|
||||||
|
|
||||||
Please note that this project is released with a Contributor Code of Conduct.
|
|
||||||
By participating in this project you agree to abide by its terms.
|
|
||||||
See [Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/CONTRIBUTING.md#contributor-code-of-conduct)
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
[cloud-asset]: https://cloud.google.com/security-command-center/docs/how-to-asset-inventory
|
|
||||||
[cloud-automl]: https://cloud.google.com/automl
|
|
||||||
[cloud-build]: https://cloud.google.com/cloud-build/
|
|
||||||
[cloud-bigquery]: https://cloud.google.com/bigquery/
|
|
||||||
[cloud-bigtable]: https://cloud.google.com/bigtable/
|
|
||||||
[cloud-container]: https://cloud.google.com/containers/
|
|
||||||
[cloud-containeranalysis]: https://cloud.google.com/container-registry/docs/container-analysis
|
|
||||||
[cloud-dataproc]: https://cloud.google.com/dataproc/
|
|
||||||
[cloud-datastore]: https://cloud.google.com/datastore/
|
|
||||||
[cloud-dialogflow]: https://cloud.google.com/dialogflow-enterprise/
|
|
||||||
[cloud-debugger]: https://cloud.google.com/debugger/
|
|
||||||
[cloud-dlp]: https://cloud.google.com/dlp/
|
|
||||||
[cloud-errors]: https://cloud.google.com/error-reporting/
|
|
||||||
[cloud-firestore]: https://cloud.google.com/firestore/
|
|
||||||
[cloud-iam]: https://cloud.google.com/iam/
|
|
||||||
[cloud-iot]: https://cloud.google.com/iot-core/
|
|
||||||
[cloud-irm]: https://cloud.google.com/incident-response/docs/concepts
|
|
||||||
[cloud-kms]: https://cloud.google.com/kms/
|
|
||||||
[cloud-pubsub]: https://cloud.google.com/pubsub/
|
|
||||||
[cloud-storage]: https://cloud.google.com/storage/
|
|
||||||
[cloud-language]: https://cloud.google.com/natural-language
|
|
||||||
[cloud-logging]: https://cloud.google.com/logging/
|
|
||||||
[cloud-natural-language]: https://cloud.google.com/natural-language/
|
|
||||||
[cloud-memorystore]: https://cloud.google.com/memorystore/
|
|
||||||
[cloud-monitoring]: https://cloud.google.com/monitoring/
|
|
||||||
[cloud-oslogin]: https://cloud.google.com/compute/docs/oslogin/rest
|
|
||||||
[cloud-phishingprotection]: https://cloud.google.com/phishing-protection/
|
|
||||||
[cloud-securitycenter]: https://cloud.google.com/security-command-center/
|
|
||||||
[cloud-scheduler]: https://cloud.google.com/scheduler
|
|
||||||
[cloud-spanner]: https://cloud.google.com/spanner/
|
|
||||||
[cloud-speech]: https://cloud.google.com/speech
|
|
||||||
[cloud-talent]: https://cloud.google.com/solutions/talent-solution/
|
|
||||||
[cloud-tasks]: https://cloud.google.com/tasks/
|
|
||||||
[cloud-texttospeech]: https://cloud.google.com/texttospeech/
|
|
||||||
[cloud-talent]: https://cloud.google.com/solutions/talent-solution/
|
|
||||||
[cloud-trace]: https://cloud.google.com/trace/
|
|
||||||
[cloud-translate]: https://cloud.google.com/translate
|
|
||||||
[cloud-recaptcha]: https://cloud.google.com/recaptcha-enterprise/
|
|
||||||
[cloud-recommender]: https://cloud.google.com/recommendations/
|
|
||||||
[cloud-video]: https://cloud.google.com/video-intelligence/
|
|
||||||
[cloud-vision]: https://cloud.google.com/vision
|
|
||||||
[cloud-webrisk]: https://cloud.google.com/web-risk/
|
|
144
vendor/cloud.google.com/go/RELEASING.md
generated
vendored
144
vendor/cloud.google.com/go/RELEASING.md
generated
vendored
|
@ -1,144 +0,0 @@
|
||||||
# Setup from scratch
|
|
||||||
|
|
||||||
1. [Install Go](https://golang.org/dl/).
|
|
||||||
1. Ensure that your `GOBIN` directory (by default `$(go env GOPATH)/bin`)
|
|
||||||
is in your `PATH`.
|
|
||||||
1. Check it's working by running `go version`.
|
|
||||||
* If it doesn't work, check the install location, usually
|
|
||||||
`/usr/local/go`, is on your `PATH`.
|
|
||||||
|
|
||||||
1. Sign one of the
|
|
||||||
[contributor license agreements](#contributor-license-agreements) below.
|
|
||||||
|
|
||||||
1. Clone the repo:
|
|
||||||
`git clone https://github.com/googleapis/google-cloud-go`
|
|
||||||
|
|
||||||
1. Change into the checked out source:
|
|
||||||
`cd google-cloud-go`
|
|
||||||
|
|
||||||
1. Fork the repo and add your fork as a secondary remote (this is necessary in
|
|
||||||
order to create PRs).
|
|
||||||
|
|
||||||
# Which module to release?
|
|
||||||
|
|
||||||
The Go client libraries have several modules. Each module does not strictly
|
|
||||||
correspond to a single library - they correspond to trees of directories. If a
|
|
||||||
file needs to be released, you must release the closest ancestor module.
|
|
||||||
|
|
||||||
To see all modules:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cat `find . -name go.mod` | grep module
|
|
||||||
module cloud.google.com/go
|
|
||||||
module cloud.google.com/go/bigtable
|
|
||||||
module cloud.google.com/go/firestore
|
|
||||||
module cloud.google.com/go/bigquery
|
|
||||||
module cloud.google.com/go/storage
|
|
||||||
module cloud.google.com/go/datastore
|
|
||||||
module cloud.google.com/go/pubsub
|
|
||||||
module cloud.google.com/go/spanner
|
|
||||||
module cloud.google.com/go/logging
|
|
||||||
```
|
|
||||||
|
|
||||||
The `cloud.google.com/go` is the repository root module. Each other module is
|
|
||||||
a submodule.
|
|
||||||
|
|
||||||
So, if you need to release a change in `bigtable/bttest/inmem.go`, the closest
|
|
||||||
ancestor module is `cloud.google.com/go/bigtable` - so you should release a new
|
|
||||||
version of the `cloud.google.com/go/bigtable` submodule.
|
|
||||||
|
|
||||||
If you need to release a change in `asset/apiv1/asset_client.go`, the closest
|
|
||||||
ancestor module is `cloud.google.com/go` - so you should release a new version
|
|
||||||
of the `cloud.google.com/go` repository root module. Note: releasing
|
|
||||||
`cloud.google.com/go` has no impact on any of the submodules, and vice-versa.
|
|
||||||
They are released entirely independently.
|
|
||||||
|
|
||||||
# Test failures
|
|
||||||
|
|
||||||
If there are any test failures in the Kokoro build, releases are blocked until
|
|
||||||
the failures have been resolved.
|
|
||||||
|
|
||||||
# How to release `cloud.google.com/go`
|
|
||||||
|
|
||||||
1. Check for failures in the
|
|
||||||
[continuous Kokoro build](http://go/google-cloud-go-continuous). If there are any
|
|
||||||
failures in the most recent build, address them before proceeding with the
|
|
||||||
release.
|
|
||||||
1. Navigate to `~/code/gocloud/` and switch to master.
|
|
||||||
1. `git pull`
|
|
||||||
1. Run `git tag -l | grep -v beta | grep -v alpha` to see all existing releases.
|
|
||||||
The current latest tag `$CV` is the largest tag. It should look something
|
|
||||||
like `vX.Y.Z` (note: ignore all `LIB/vX.Y.Z` tags - these are tags for a
|
|
||||||
specific library, not the module root). We'll call the current version `$CV`
|
|
||||||
and the new version `$NV`.
|
|
||||||
1. On master, run `git log $CV...` to list all the changes since the last
|
|
||||||
release. NOTE: You must manually visually parse out changes to submodules [1]
|
|
||||||
(the `git log` is going to show you things in submodules, which are not going
|
|
||||||
to be part of your release).
|
|
||||||
1. Edit `CHANGES.md` to include a summary of the changes.
|
|
||||||
1. `cd internal/version && go generate && cd -`
|
|
||||||
1. Commit the changes, push to your fork, and create a PR.
|
|
||||||
1. Wait for the PR to be reviewed and merged. Once it's merged, and without
|
|
||||||
merging any other PRs in the meantime:
|
|
||||||
a. Switch to master.
|
|
||||||
b. `git pull`
|
|
||||||
c. Tag the repo with the next version: `git tag $NV`.
|
|
||||||
d. Push the tag to origin:
|
|
||||||
`git push origin $NV`
|
|
||||||
1. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases)
|
|
||||||
with the new release, copying the contents of `CHANGES.md`.
|
|
||||||
1. Run `go get cloud.google.com/go@vX.Y.Z` then wait for the release
|
|
||||||
to show up on http://pkg.go.dev/cloud.google.com/go (a few minutes).
|
|
||||||
1. Go to the [doc publishing job](http://go/google-cloud-go-publish-docs) and
|
|
||||||
trigger the job with the following environment variables:
|
|
||||||
`MODULE=cloud.google.com,VERSION=vX.Y.Z`.
|
|
||||||
Replace the version with the value for the module you're
|
|
||||||
releasing. See [`publish_docs.sh`](/internal/kokoro/publish_docs.sh).
|
|
||||||
|
|
||||||
# How to release a submodule
|
|
||||||
|
|
||||||
We have several submodules, including `cloud.google.com/go/logging`,
|
|
||||||
`cloud.google.com/go/datastore`, and so on.
|
|
||||||
|
|
||||||
To release a submodule:
|
|
||||||
|
|
||||||
(these instructions assume we're releasing `cloud.google.com/go/datastore` - adjust accordingly)
|
|
||||||
|
|
||||||
1. Check for failures in the
|
|
||||||
[continuous Kokoro build](http://go/google-cloud-go-continuous). If there are any
|
|
||||||
failures in the most recent build, address them before proceeding with the
|
|
||||||
release. (This applies even if the failures are in a different submodule from the one
|
|
||||||
being released.)
|
|
||||||
1. Navigate to `~/code/gocloud/` and switch to master.
|
|
||||||
1. `git pull`
|
|
||||||
1. Run `git tag -l | grep datastore | grep -v beta | grep -v alpha` to see all
|
|
||||||
existing releases. The current latest tag `$CV` is the largest tag. It
|
|
||||||
should look something like `datastore/vX.Y.Z`. We'll call the current version
|
|
||||||
`$CV` and the new version `$NV`.
|
|
||||||
1. On master, run `git log $CV.. -- datastore/` to list all the changes to the
|
|
||||||
submodule directory since the last release.
|
|
||||||
1. Edit `datastore/CHANGES.md` to include a summary of the changes.
|
|
||||||
1. `cd internal/version && go generate && cd -`
|
|
||||||
1. Commit the changes, push to your fork, and create a PR.
|
|
||||||
1. Wait for the PR to be reviewed and merged. Once it's merged, and without
|
|
||||||
merging any other PRs in the meantime:
|
|
||||||
a. Switch to master.
|
|
||||||
b. `git pull`
|
|
||||||
c. Tag the repo with the next version: `git tag $NV`.
|
|
||||||
d. Push the tag to origin:
|
|
||||||
`git push origin $NV`
|
|
||||||
1. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases)
|
|
||||||
with the new release, copying the contents of `datastore/CHANGES.md`.
|
|
||||||
1. Run `go get cloud.google.com/go/datastore@vX.Y.Z` then wait for the release
|
|
||||||
to show up on http://pkg.go.dev/cloud.google.com/go/datastore (a few
|
|
||||||
minutes).
|
|
||||||
1. Go to the [doc publishing job](http://go/google-cloud-go-publish-docs) and
|
|
||||||
trigger the job with the following environment variables:
|
|
||||||
`MODULE=cloud.google.com/go/datastore,VERSION=vX.Y.Z`.
|
|
||||||
Replace the module path and version with the values for the module you're
|
|
||||||
releasing. You can leave all of the other fields blank.
|
|
||||||
See [`publish_docs.sh`](/internal/kokoro/publish_docs.sh).
|
|
||||||
|
|
||||||
# Appendix
|
|
||||||
|
|
||||||
1: This should get better as submodule tooling matures.
|
|
519
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
519
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
|
@ -1,519 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package metadata provides access to Google Compute Engine (GCE)
|
|
||||||
// metadata and API service accounts.
|
|
||||||
//
|
|
||||||
// This package is a wrapper around the GCE metadata service,
|
|
||||||
// as documented at https://developers.google.com/compute/docs/metadata.
|
|
||||||
package metadata // import "cloud.google.com/go/compute/metadata"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// metadataIP is the documented metadata server IP address.
|
|
||||||
metadataIP = "169.254.169.254"
|
|
||||||
|
|
||||||
// metadataHostEnv is the environment variable specifying the
|
|
||||||
// GCE metadata hostname. If empty, the default value of
|
|
||||||
// metadataIP ("169.254.169.254") is used instead.
|
|
||||||
// This is variable name is not defined by any spec, as far as
|
|
||||||
// I know; it was made up for the Go package.
|
|
||||||
metadataHostEnv = "GCE_METADATA_HOST"
|
|
||||||
|
|
||||||
userAgent = "gcloud-golang/0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type cachedValue struct {
|
|
||||||
k string
|
|
||||||
trim bool
|
|
||||||
mu sync.Mutex
|
|
||||||
v string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
projID = &cachedValue{k: "project/project-id", trim: true}
|
|
||||||
projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
|
|
||||||
instID = &cachedValue{k: "instance/id", trim: true}
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultClient = &Client{hc: &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Dial: (&net.Dialer{
|
|
||||||
Timeout: 2 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).Dial,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
|
|
||||||
// NotDefinedError is returned when requested metadata is not defined.
|
|
||||||
//
|
|
||||||
// The underlying string is the suffix after "/computeMetadata/v1/".
|
|
||||||
//
|
|
||||||
// This error is not returned if the value is defined to be the empty
|
|
||||||
// string.
|
|
||||||
type NotDefinedError string
|
|
||||||
|
|
||||||
func (suffix NotDefinedError) Error() string {
|
|
||||||
return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cachedValue) get(cl *Client) (v string, err error) {
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
c.mu.Lock()
|
|
||||||
if c.v != "" {
|
|
||||||
return c.v, nil
|
|
||||||
}
|
|
||||||
if c.trim {
|
|
||||||
v, err = cl.getTrimmed(c.k)
|
|
||||||
} else {
|
|
||||||
v, err = cl.Get(c.k)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
c.v = v
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
onGCEOnce sync.Once
|
|
||||||
onGCE bool
|
|
||||||
)
|
|
||||||
|
|
||||||
// OnGCE reports whether this process is running on Google Compute Engine.
|
|
||||||
func OnGCE() bool {
|
|
||||||
onGCEOnce.Do(initOnGCE)
|
|
||||||
return onGCE
|
|
||||||
}
|
|
||||||
|
|
||||||
func initOnGCE() {
|
|
||||||
onGCE = testOnGCE()
|
|
||||||
}
|
|
||||||
|
|
||||||
func testOnGCE() bool {
|
|
||||||
// The user explicitly said they're on GCE, so trust them.
|
|
||||||
if os.Getenv(metadataHostEnv) != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
resc := make(chan bool, 2)
|
|
||||||
|
|
||||||
// Try two strategies in parallel.
|
|
||||||
// See https://github.com/googleapis/google-cloud-go/issues/194
|
|
||||||
go func() {
|
|
||||||
req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
|
|
||||||
req.Header.Set("User-Agent", userAgent)
|
|
||||||
res, err := defaultClient.hc.Do(req.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
resc <- res.Header.Get("Metadata-Flavor") == "Google"
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
addrs, err := net.DefaultResolver.LookupHost(ctx, "metadata.google.internal")
|
|
||||||
if err != nil || len(addrs) == 0 {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resc <- strsContains(addrs, metadataIP)
|
|
||||||
}()
|
|
||||||
|
|
||||||
tryHarder := systemInfoSuggestsGCE()
|
|
||||||
if tryHarder {
|
|
||||||
res := <-resc
|
|
||||||
if res {
|
|
||||||
// The first strategy succeeded, so let's use it.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Wait for either the DNS or metadata server probe to
|
|
||||||
// contradict the other one and say we are running on
|
|
||||||
// GCE. Give it a lot of time to do so, since the system
|
|
||||||
// info already suggests we're running on a GCE BIOS.
|
|
||||||
timer := time.NewTimer(5 * time.Second)
|
|
||||||
defer timer.Stop()
|
|
||||||
select {
|
|
||||||
case res = <-resc:
|
|
||||||
return res
|
|
||||||
case <-timer.C:
|
|
||||||
// Too slow. Who knows what this system is.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There's no hint from the system info that we're running on
|
|
||||||
// GCE, so use the first probe's result as truth, whether it's
|
|
||||||
// true or false. The goal here is to optimize for speed for
|
|
||||||
// users who are NOT running on GCE. We can't assume that
|
|
||||||
// either a DNS lookup or an HTTP request to a blackholed IP
|
|
||||||
// address is fast. Worst case this should return when the
|
|
||||||
// metaClient's Transport.ResponseHeaderTimeout or
|
|
||||||
// Transport.Dial.Timeout fires (in two seconds).
|
|
||||||
return <-resc
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemInfoSuggestsGCE reports whether the local system (without
|
|
||||||
// doing network requests) suggests that we're running on GCE. If this
|
|
||||||
// returns true, testOnGCE tries a bit harder to reach its metadata
|
|
||||||
// server.
|
|
||||||
func systemInfoSuggestsGCE() bool {
|
|
||||||
if runtime.GOOS != "linux" {
|
|
||||||
// We don't have any non-Linux clues available, at least yet.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name")
|
|
||||||
name := strings.TrimSpace(string(slurp))
|
|
||||||
return name == "Google" || name == "Google Compute Engine"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe calls Client.Subscribe on the default client.
|
|
||||||
func Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
|
||||||
return defaultClient.Subscribe(suffix, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get calls Client.Get on the default client.
|
|
||||||
func Get(suffix string) (string, error) { return defaultClient.Get(suffix) }
|
|
||||||
|
|
||||||
// ProjectID returns the current instance's project ID string.
|
|
||||||
func ProjectID() (string, error) { return defaultClient.ProjectID() }
|
|
||||||
|
|
||||||
// NumericProjectID returns the current instance's numeric project ID.
|
|
||||||
func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() }
|
|
||||||
|
|
||||||
// InternalIP returns the instance's primary internal IP address.
|
|
||||||
func InternalIP() (string, error) { return defaultClient.InternalIP() }
|
|
||||||
|
|
||||||
// ExternalIP returns the instance's primary external (public) IP address.
|
|
||||||
func ExternalIP() (string, error) { return defaultClient.ExternalIP() }
|
|
||||||
|
|
||||||
// Email calls Client.Email on the default client.
|
|
||||||
func Email(serviceAccount string) (string, error) { return defaultClient.Email(serviceAccount) }
|
|
||||||
|
|
||||||
// Hostname returns the instance's hostname. This will be of the form
|
|
||||||
// "<instanceID>.c.<projID>.internal".
|
|
||||||
func Hostname() (string, error) { return defaultClient.Hostname() }
|
|
||||||
|
|
||||||
// InstanceTags returns the list of user-defined instance tags,
|
|
||||||
// assigned when initially creating a GCE instance.
|
|
||||||
func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() }
|
|
||||||
|
|
||||||
// InstanceID returns the current VM's numeric instance ID.
|
|
||||||
func InstanceID() (string, error) { return defaultClient.InstanceID() }
|
|
||||||
|
|
||||||
// InstanceName returns the current VM's instance ID string.
|
|
||||||
func InstanceName() (string, error) { return defaultClient.InstanceName() }
|
|
||||||
|
|
||||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
|
||||||
func Zone() (string, error) { return defaultClient.Zone() }
|
|
||||||
|
|
||||||
// InstanceAttributes calls Client.InstanceAttributes on the default client.
|
|
||||||
func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() }
|
|
||||||
|
|
||||||
// ProjectAttributes calls Client.ProjectAttributes on the default client.
|
|
||||||
func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() }
|
|
||||||
|
|
||||||
// InstanceAttributeValue calls Client.InstanceAttributeValue on the default client.
|
|
||||||
func InstanceAttributeValue(attr string) (string, error) {
|
|
||||||
return defaultClient.InstanceAttributeValue(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectAttributeValue calls Client.ProjectAttributeValue on the default client.
|
|
||||||
func ProjectAttributeValue(attr string) (string, error) {
|
|
||||||
return defaultClient.ProjectAttributeValue(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopes calls Client.Scopes on the default client.
|
|
||||||
func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) }
|
|
||||||
|
|
||||||
func strsContains(ss []string, s string) bool {
|
|
||||||
for _, v := range ss {
|
|
||||||
if v == s {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Client provides metadata.
|
|
||||||
type Client struct {
|
|
||||||
hc *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient returns a Client that can be used to fetch metadata.
|
|
||||||
// Returns the client that uses the specified http.Client for HTTP requests.
|
|
||||||
// If nil is specified, returns the default client.
|
|
||||||
func NewClient(c *http.Client) *Client {
|
|
||||||
if c == nil {
|
|
||||||
return defaultClient
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Client{hc: c}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getETag returns a value from the metadata service as well as the associated ETag.
|
|
||||||
// This func is otherwise equivalent to Get.
|
|
||||||
func (c *Client) getETag(suffix string) (value, etag string, err error) {
|
|
||||||
// Using a fixed IP makes it very difficult to spoof the metadata service in
|
|
||||||
// a container, which is an important use-case for local testing of cloud
|
|
||||||
// deployments. To enable spoofing of the metadata service, the environment
|
|
||||||
// variable GCE_METADATA_HOST is first inspected to decide where metadata
|
|
||||||
// requests shall go.
|
|
||||||
host := os.Getenv(metadataHostEnv)
|
|
||||||
if host == "" {
|
|
||||||
// Using 169.254.169.254 instead of "metadata" here because Go
|
|
||||||
// binaries built with the "netgo" tag and without cgo won't
|
|
||||||
// know the search suffix for "metadata" is
|
|
||||||
// ".google.internal", and this IP address is documented as
|
|
||||||
// being stable anyway.
|
|
||||||
host = metadataIP
|
|
||||||
}
|
|
||||||
suffix = strings.TrimLeft(suffix, "/")
|
|
||||||
u := "http://" + host + "/computeMetadata/v1/" + suffix
|
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
req.Header.Set("Metadata-Flavor", "Google")
|
|
||||||
req.Header.Set("User-Agent", userAgent)
|
|
||||||
res, err := c.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
if res.StatusCode == http.StatusNotFound {
|
|
||||||
return "", "", NotDefinedError(suffix)
|
|
||||||
}
|
|
||||||
all, err := ioutil.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
if res.StatusCode != 200 {
|
|
||||||
return "", "", &Error{Code: res.StatusCode, Message: string(all)}
|
|
||||||
}
|
|
||||||
return string(all), res.Header.Get("Etag"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a value from the metadata service.
|
|
||||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
|
||||||
//
|
|
||||||
// If the GCE_METADATA_HOST environment variable is not defined, a default of
|
|
||||||
// 169.254.169.254 will be used instead.
|
|
||||||
//
|
|
||||||
// If the requested metadata is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
func (c *Client) Get(suffix string) (string, error) {
|
|
||||||
val, _, err := c.getETag(suffix)
|
|
||||||
return val, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) getTrimmed(suffix string) (s string, err error) {
|
|
||||||
s, err = c.Get(suffix)
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) lines(suffix string) ([]string, error) {
|
|
||||||
j, err := c.Get(suffix)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s := strings.Split(strings.TrimSpace(j), "\n")
|
|
||||||
for i := range s {
|
|
||||||
s[i] = strings.TrimSpace(s[i])
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectID returns the current instance's project ID string.
|
|
||||||
func (c *Client) ProjectID() (string, error) { return projID.get(c) }
|
|
||||||
|
|
||||||
// NumericProjectID returns the current instance's numeric project ID.
|
|
||||||
func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) }
|
|
||||||
|
|
||||||
// InstanceID returns the current VM's numeric instance ID.
|
|
||||||
func (c *Client) InstanceID() (string, error) { return instID.get(c) }
|
|
||||||
|
|
||||||
// InternalIP returns the instance's primary internal IP address.
|
|
||||||
func (c *Client) InternalIP() (string, error) {
|
|
||||||
return c.getTrimmed("instance/network-interfaces/0/ip")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Email returns the email address associated with the service account.
|
|
||||||
// The account may be empty or the string "default" to use the instance's
|
|
||||||
// main account.
|
|
||||||
func (c *Client) Email(serviceAccount string) (string, error) {
|
|
||||||
if serviceAccount == "" {
|
|
||||||
serviceAccount = "default"
|
|
||||||
}
|
|
||||||
return c.getTrimmed("instance/service-accounts/" + serviceAccount + "/email")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExternalIP returns the instance's primary external (public) IP address.
|
|
||||||
func (c *Client) ExternalIP() (string, error) {
|
|
||||||
return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hostname returns the instance's hostname. This will be of the form
|
|
||||||
// "<instanceID>.c.<projID>.internal".
|
|
||||||
func (c *Client) Hostname() (string, error) {
|
|
||||||
return c.getTrimmed("instance/hostname")
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceTags returns the list of user-defined instance tags,
|
|
||||||
// assigned when initially creating a GCE instance.
|
|
||||||
func (c *Client) InstanceTags() ([]string, error) {
|
|
||||||
var s []string
|
|
||||||
j, err := c.Get("instance/tags")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceName returns the current VM's instance ID string.
|
|
||||||
func (c *Client) InstanceName() (string, error) {
|
|
||||||
return c.getTrimmed("instance/name")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
|
||||||
func (c *Client) Zone() (string, error) {
|
|
||||||
zone, err := c.getTrimmed("instance/zone")
|
|
||||||
// zone is of the form "projects/<projNum>/zones/<zoneName>".
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return zone[strings.LastIndex(zone, "/")+1:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceAttributes returns the list of user-defined attributes,
|
|
||||||
// assigned when initially creating a GCE VM instance. The value of an
|
|
||||||
// attribute can be obtained with InstanceAttributeValue.
|
|
||||||
func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") }
|
|
||||||
|
|
||||||
// ProjectAttributes returns the list of user-defined attributes
|
|
||||||
// applying to the project as a whole, not just this VM. The value of
|
|
||||||
// an attribute can be obtained with ProjectAttributeValue.
|
|
||||||
func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") }
|
|
||||||
|
|
||||||
// InstanceAttributeValue returns the value of the provided VM
|
|
||||||
// instance attribute.
|
|
||||||
//
|
|
||||||
// If the requested attribute is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
//
|
|
||||||
// InstanceAttributeValue may return ("", nil) if the attribute was
|
|
||||||
// defined to be the empty string.
|
|
||||||
func (c *Client) InstanceAttributeValue(attr string) (string, error) {
|
|
||||||
return c.Get("instance/attributes/" + attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectAttributeValue returns the value of the provided
|
|
||||||
// project attribute.
|
|
||||||
//
|
|
||||||
// If the requested attribute is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
//
|
|
||||||
// ProjectAttributeValue may return ("", nil) if the attribute was
|
|
||||||
// defined to be the empty string.
|
|
||||||
func (c *Client) ProjectAttributeValue(attr string) (string, error) {
|
|
||||||
return c.Get("project/attributes/" + attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopes returns the service account scopes for the given account.
|
|
||||||
// The account may be empty or the string "default" to use the instance's
|
|
||||||
// main account.
|
|
||||||
func (c *Client) Scopes(serviceAccount string) ([]string, error) {
|
|
||||||
if serviceAccount == "" {
|
|
||||||
serviceAccount = "default"
|
|
||||||
}
|
|
||||||
return c.lines("instance/service-accounts/" + serviceAccount + "/scopes")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe subscribes to a value from the metadata service.
|
|
||||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
|
||||||
// The suffix may contain query parameters.
|
|
||||||
//
|
|
||||||
// Subscribe calls fn with the latest metadata value indicated by the provided
|
|
||||||
// suffix. If the metadata value is deleted, fn is called with the empty string
|
|
||||||
// and ok false. Subscribe blocks until fn returns a non-nil error or the value
|
|
||||||
// is deleted. Subscribe returns the error value returned from the last call to
|
|
||||||
// fn, which may be nil when ok == false.
|
|
||||||
func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
|
||||||
const failedSubscribeSleep = time.Second * 5
|
|
||||||
|
|
||||||
// First check to see if the metadata value exists at all.
|
|
||||||
val, lastETag, err := c.getETag(suffix)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := fn(val, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ok := true
|
|
||||||
if strings.ContainsRune(suffix, '?') {
|
|
||||||
suffix += "&wait_for_change=true&last_etag="
|
|
||||||
} else {
|
|
||||||
suffix += "?wait_for_change=true&last_etag="
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag))
|
|
||||||
if err != nil {
|
|
||||||
if _, deleted := err.(NotDefinedError); !deleted {
|
|
||||||
time.Sleep(failedSubscribeSleep)
|
|
||||||
continue // Retry on other errors.
|
|
||||||
}
|
|
||||||
ok = false
|
|
||||||
}
|
|
||||||
lastETag = etag
|
|
||||||
|
|
||||||
if err := fn(val, ok); err != nil || !ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error contains an error response from the server.
|
|
||||||
type Error struct {
|
|
||||||
// Code is the HTTP response status code.
|
|
||||||
Code int
|
|
||||||
// Message is the server response message.
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message)
|
|
||||||
}
|
|
109
vendor/cloud.google.com/go/doc.go
generated
vendored
109
vendor/cloud.google.com/go/doc.go
generated
vendored
|
@ -1,109 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package cloud is the root of the packages used to access Google Cloud
|
|
||||||
Services. See https://godoc.org/cloud.google.com/go for a full list
|
|
||||||
of sub-packages.
|
|
||||||
|
|
||||||
|
|
||||||
Client Options
|
|
||||||
|
|
||||||
All clients in sub-packages are configurable via client options. These options are
|
|
||||||
described here: https://godoc.org/google.golang.org/api/option.
|
|
||||||
|
|
||||||
|
|
||||||
Authentication and Authorization
|
|
||||||
|
|
||||||
All the clients in sub-packages support authentication via Google Application Default
|
|
||||||
Credentials (see https://cloud.google.com/docs/authentication/production), or
|
|
||||||
by providing a JSON key file for a Service Account. See the authentication examples
|
|
||||||
in this package for details.
|
|
||||||
|
|
||||||
|
|
||||||
Timeouts and Cancellation
|
|
||||||
|
|
||||||
By default, non-streaming methods, like Create or Get, will have a default deadline applied to the
|
|
||||||
context provided at call time, unless a context deadline is already set. Streaming
|
|
||||||
methods have no default deadline and will run indefinitely. To set timeouts or
|
|
||||||
arrange for cancellation, use contexts. See the examples for details. Transient
|
|
||||||
errors will be retried when correctness allows.
|
|
||||||
|
|
||||||
To opt out of default deadlines, set the temporary environment variable
|
|
||||||
GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE to "true" prior to client
|
|
||||||
creation. This affects all Google Cloud Go client libraries. This opt-out
|
|
||||||
mechanism will be removed in a future release. File an issue at
|
|
||||||
https://github.com/googleapis/google-cloud-go if the default deadlines
|
|
||||||
cannot work for you.
|
|
||||||
|
|
||||||
Do not attempt to control the initial connection (dialing) of a service by setting a
|
|
||||||
timeout on the context passed to NewClient. Dialing is non-blocking, so timeouts
|
|
||||||
would be ineffective and would only interfere with credential refreshing, which uses
|
|
||||||
the same context.
|
|
||||||
|
|
||||||
|
|
||||||
Connection Pooling
|
|
||||||
|
|
||||||
Connection pooling differs in clients based on their transport. Cloud
|
|
||||||
clients either rely on HTTP or gRPC transports to communicate
|
|
||||||
with Google Cloud.
|
|
||||||
|
|
||||||
Cloud clients that use HTTP (bigquery, compute, storage, and translate) rely on the
|
|
||||||
underlying HTTP transport to cache connections for later re-use. These are cached to
|
|
||||||
the default http.MaxIdleConns and http.MaxIdleConnsPerHost settings in
|
|
||||||
http.DefaultTransport.
|
|
||||||
|
|
||||||
For gRPC clients (all others in this repo), connection pooling is configurable. Users
|
|
||||||
of cloud client libraries may specify option.WithGRPCConnectionPool(n) as a client
|
|
||||||
option to NewClient calls. This configures the underlying gRPC connections to be
|
|
||||||
pooled and addressed in a round robin fashion.
|
|
||||||
|
|
||||||
|
|
||||||
Using the Libraries with Docker
|
|
||||||
|
|
||||||
Minimal docker images like Alpine lack CA certificates. This causes RPCs to appear to
|
|
||||||
hang, because gRPC retries indefinitely. See https://github.com/googleapis/google-cloud-go/issues/928
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
|
|
||||||
Debugging
|
|
||||||
|
|
||||||
To see gRPC logs, set the environment variable GRPC_GO_LOG_SEVERITY_LEVEL. See
|
|
||||||
https://godoc.org/google.golang.org/grpc/grpclog for more information.
|
|
||||||
|
|
||||||
For HTTP logging, set the GODEBUG environment variable to "http2debug=1" or "http2debug=2".
|
|
||||||
|
|
||||||
|
|
||||||
Client Stability
|
|
||||||
|
|
||||||
Clients in this repository are considered alpha or beta unless otherwise
|
|
||||||
marked as stable in the README.md. Semver is not used to communicate stability
|
|
||||||
of clients.
|
|
||||||
|
|
||||||
Alpha and beta clients may change or go away without notice.
|
|
||||||
|
|
||||||
Clients marked stable will maintain compatibility with future versions for as
|
|
||||||
long as we can reasonably sustain. Incompatible changes might be made in some
|
|
||||||
situations, including:
|
|
||||||
|
|
||||||
- Security bugs may prompt backwards-incompatible changes.
|
|
||||||
|
|
||||||
- Situations in which components are no longer feasible to maintain without
|
|
||||||
making breaking changes, including removal.
|
|
||||||
|
|
||||||
- Parts of the client surface may be outright unstable and subject to change.
|
|
||||||
These parts of the surface will be labeled with the note, "It is EXPERIMENTAL
|
|
||||||
and subject to change or removal without notice."
|
|
||||||
*/
|
|
||||||
package cloud // import "cloud.google.com/go"
|
|
23
vendor/cloud.google.com/go/go.mod
generated
vendored
23
vendor/cloud.google.com/go/go.mod
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
module cloud.google.com/go
|
|
||||||
|
|
||||||
go 1.11
|
|
||||||
|
|
||||||
require (
|
|
||||||
cloud.google.com/go/storage v1.10.0
|
|
||||||
github.com/golang/mock v1.4.4
|
|
||||||
github.com/golang/protobuf v1.4.2
|
|
||||||
github.com/google/go-cmp v0.5.2
|
|
||||||
github.com/google/martian/v3 v3.0.0
|
|
||||||
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1
|
|
||||||
go.opencensus.io v0.22.5
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
|
|
||||||
golang.org/x/text v0.3.3
|
|
||||||
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752
|
|
||||||
google.golang.org/api v0.33.0
|
|
||||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9
|
|
||||||
google.golang.org/grpc v1.32.0
|
|
||||||
)
|
|
531
vendor/cloud.google.com/go/go.sum
generated
vendored
531
vendor/cloud.google.com/go/go.sum
generated
vendored
|
@ -1,531 +0,0 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0 h1:a/O/bK/vWrYGOTFtH8di4rBxMZnmkjy+Y5LxpDwo+dA=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0 h1:9/vpR43S4aJaROxqQHQ3nH9lfyKKV0dC3vOmnw8ebQQ=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0 h1:RPUcBvDeYgQFMfQu1eBMq6piD1SXmLH+vK3qjewZPus=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0 h1:86K1Gel7BQ9/WmNWn7dTKMvTLFzwtBe5FNqYbi9X35g=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
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-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
|
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
|
||||||
github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg=
|
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
|
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
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.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
|
||||||
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57 h1:eqyIo2HjKhKe/mJzTG8n4VqvLXIOEG+SLdDqX7xGtkY=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35 h1:WL9iUw2tSwvaCb3++2fMsg2dAmpZd5AykgFftgfHETc=
|
|
||||||
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
|
|
||||||
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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
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/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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|
||||||
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
|
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA=
|
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f h1:hX65Cu3JDlGH3uEdK7I99Ii+9kjD6mvnnpfLdEAH0x4=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
|
||||||
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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/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-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-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 h1:OKbAoGs4fGM5cPLlVQLZGYkFC8OnOfgo6tt0Smf9XhM=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
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.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138 h1:H3uGjxCR/6Ds0Mjgyp7LMK81+LvmbvWWEnJhzk1Pi9E=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c h1:97SnQk1GYRXJgvwZ8fadnxDOWfKvkNQHH3CtZntPSrM=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d h1:lzLdP95xJmMpwQ6LUHwrc5V7js93hTiY7gkznu0BgmY=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88 h1:4j84u0sokprDu3IdSYHJMmou+YSLflMz8p7yAx/QI4g=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d h1:szSOL78iTCl0LF1AMjhSWJj8tIM0KixlUUnBtYXsmd8=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
|
||||||
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752 h1:2ntEwh02rqo2jSsrYmp4yKHHjh0CbXP3ZtSUetSB+q8=
|
|
||||||
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0 h1:0q95w+VuFtv4PAx4PZVQdBMmYbaCHbnfKaEiDIcVyag=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw=
|
|
||||||
google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk=
|
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84 h1:pSLkPbrjnPyLDYUO2VM9mDLqo2V6CFBY84lFSZAfoi4=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380 h1:xriR1EgvKfkKxIoU2uUvrMVl+H26359loFFUleSMXFo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c h1:Lq4llNryJoaVFRmvrIwC/ZHH7tNt4tUYIu8+se2aayY=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9 h1:fG84H9C3EXfuDlzkG+VEPDYHHExklP6scH1QZ5gQTqU=
|
|
||||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
|
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
|
|
||||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc h1:TnonUr8u3himcMY0vSh23jFOXA+cnucl1gB6EQTReBI=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
|
||||||
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=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a h1:/8zB6iBfHCl1qAnEAWwGPNrUvapuy6CPla1VM0k8hQw=
|
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
387
vendor/cloud.google.com/go/iam/iam.go
generated
vendored
387
vendor/cloud.google.com/go/iam/iam.go
generated
vendored
|
@ -1,387 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package iam supports the resource-specific operations of Google Cloud
|
|
||||||
// IAM (Identity and Access Management) for the Google Cloud Libraries.
|
|
||||||
// See https://cloud.google.com/iam for more about IAM.
|
|
||||||
//
|
|
||||||
// Users of the Google Cloud Libraries will typically not use this package
|
|
||||||
// directly. Instead they will begin with some resource that supports IAM, like
|
|
||||||
// a pubsub topic, and call its IAM method to get a Handle for that resource.
|
|
||||||
package iam
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
pb "google.golang.org/genproto/googleapis/iam/v1"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
|
||||||
|
|
||||||
// client abstracts the IAMPolicy API to allow multiple implementations.
|
|
||||||
type client interface {
|
|
||||||
Get(ctx context.Context, resource string) (*pb.Policy, error)
|
|
||||||
Set(ctx context.Context, resource string, p *pb.Policy) error
|
|
||||||
Test(ctx context.Context, resource string, perms []string) ([]string, error)
|
|
||||||
GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (*pb.Policy, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// grpcClient implements client for the standard gRPC-based IAMPolicy service.
|
|
||||||
type grpcClient struct {
|
|
||||||
c pb.IAMPolicyClient
|
|
||||||
}
|
|
||||||
|
|
||||||
var withRetry = gax.WithRetry(func() gax.Retryer {
|
|
||||||
return gax.OnCodes([]codes.Code{
|
|
||||||
codes.DeadlineExceeded,
|
|
||||||
codes.Unavailable,
|
|
||||||
}, gax.Backoff{
|
|
||||||
Initial: 100 * time.Millisecond,
|
|
||||||
Max: 60 * time.Second,
|
|
||||||
Multiplier: 1.3,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Policy, error) {
|
|
||||||
return g.GetWithVersion(ctx, resource, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *grpcClient) GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (*pb.Policy, error) {
|
|
||||||
var proto *pb.Policy
|
|
||||||
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
|
|
||||||
ctx = insertMetadata(ctx, md)
|
|
||||||
|
|
||||||
err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
|
|
||||||
var err error
|
|
||||||
proto, err = g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{
|
|
||||||
Resource: resource,
|
|
||||||
Options: &pb.GetPolicyOptions{
|
|
||||||
RequestedPolicyVersion: requestedPolicyVersion,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, withRetry)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return proto, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *grpcClient) Set(ctx context.Context, resource string, p *pb.Policy) error {
|
|
||||||
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
|
|
||||||
ctx = insertMetadata(ctx, md)
|
|
||||||
|
|
||||||
return gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
|
|
||||||
_, err := g.c.SetIamPolicy(ctx, &pb.SetIamPolicyRequest{
|
|
||||||
Resource: resource,
|
|
||||||
Policy: p,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, withRetry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *grpcClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) {
|
|
||||||
var res *pb.TestIamPermissionsResponse
|
|
||||||
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
|
|
||||||
ctx = insertMetadata(ctx, md)
|
|
||||||
|
|
||||||
err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
|
|
||||||
var err error
|
|
||||||
res, err = g.c.TestIamPermissions(ctx, &pb.TestIamPermissionsRequest{
|
|
||||||
Resource: resource,
|
|
||||||
Permissions: perms,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}, withRetry)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return res.Permissions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Handle provides IAM operations for a resource.
|
|
||||||
type Handle struct {
|
|
||||||
c client
|
|
||||||
resource string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Handle3 provides IAM operations for a resource. It is similar to a Handle, but provides access to newer IAM features (e.g., conditions).
|
|
||||||
type Handle3 struct {
|
|
||||||
c client
|
|
||||||
resource string
|
|
||||||
version int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalNewHandle is for use by the Google Cloud Libraries only.
|
|
||||||
//
|
|
||||||
// InternalNewHandle returns a Handle for resource.
|
|
||||||
// The conn parameter refers to a server that must support the IAMPolicy service.
|
|
||||||
func InternalNewHandle(conn grpc.ClientConnInterface, resource string) *Handle {
|
|
||||||
return InternalNewHandleGRPCClient(pb.NewIAMPolicyClient(conn), resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalNewHandleGRPCClient is for use by the Google Cloud Libraries only.
|
|
||||||
//
|
|
||||||
// InternalNewHandleClient returns a Handle for resource using the given
|
|
||||||
// grpc service that implements IAM as a mixin
|
|
||||||
func InternalNewHandleGRPCClient(c pb.IAMPolicyClient, resource string) *Handle {
|
|
||||||
return InternalNewHandleClient(&grpcClient{c: c}, resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalNewHandleClient is for use by the Google Cloud Libraries only.
|
|
||||||
//
|
|
||||||
// InternalNewHandleClient returns a Handle for resource using the given
|
|
||||||
// client implementation.
|
|
||||||
func InternalNewHandleClient(c client, resource string) *Handle {
|
|
||||||
return &Handle{
|
|
||||||
c: c,
|
|
||||||
resource: resource,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// V3 returns a Handle3, which is like Handle except it sets
|
|
||||||
// requestedPolicyVersion to 3 when retrieving a policy and policy.version to 3
|
|
||||||
// when storing a policy.
|
|
||||||
func (h *Handle) V3() *Handle3 {
|
|
||||||
return &Handle3{
|
|
||||||
c: h.c,
|
|
||||||
resource: h.resource,
|
|
||||||
version: 3,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Policy retrieves the IAM policy for the resource.
|
|
||||||
func (h *Handle) Policy(ctx context.Context) (*Policy, error) {
|
|
||||||
proto, err := h.c.Get(ctx, h.resource)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Policy{InternalProto: proto}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPolicy replaces the resource's current policy with the supplied Policy.
|
|
||||||
//
|
|
||||||
// If policy was created from a prior call to Get, then the modification will
|
|
||||||
// only succeed if the policy has not changed since the Get.
|
|
||||||
func (h *Handle) SetPolicy(ctx context.Context, policy *Policy) error {
|
|
||||||
return h.c.Set(ctx, h.resource, policy.InternalProto)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPermissions returns the subset of permissions that the caller has on the resource.
|
|
||||||
func (h *Handle) TestPermissions(ctx context.Context, permissions []string) ([]string, error) {
|
|
||||||
return h.c.Test(ctx, h.resource, permissions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A RoleName is a name representing a collection of permissions.
|
|
||||||
type RoleName string
|
|
||||||
|
|
||||||
// Common role names.
|
|
||||||
const (
|
|
||||||
Owner RoleName = "roles/owner"
|
|
||||||
Editor RoleName = "roles/editor"
|
|
||||||
Viewer RoleName = "roles/viewer"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// AllUsers is a special member that denotes all users, even unauthenticated ones.
|
|
||||||
AllUsers = "allUsers"
|
|
||||||
|
|
||||||
// AllAuthenticatedUsers is a special member that denotes all authenticated users.
|
|
||||||
AllAuthenticatedUsers = "allAuthenticatedUsers"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Policy is a list of Bindings representing roles
|
|
||||||
// granted to members.
|
|
||||||
//
|
|
||||||
// The zero Policy is a valid policy with no bindings.
|
|
||||||
type Policy struct {
|
|
||||||
// TODO(jba): when type aliases are available, put Policy into an internal package
|
|
||||||
// and provide an exported alias here.
|
|
||||||
|
|
||||||
// This field is exported for use by the Google Cloud Libraries only.
|
|
||||||
// It may become unexported in a future release.
|
|
||||||
InternalProto *pb.Policy
|
|
||||||
}
|
|
||||||
|
|
||||||
// Members returns the list of members with the supplied role.
|
|
||||||
// The return value should not be modified. Use Add and Remove
|
|
||||||
// to modify the members of a role.
|
|
||||||
func (p *Policy) Members(r RoleName) []string {
|
|
||||||
b := p.binding(r)
|
|
||||||
if b == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return b.Members
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasRole reports whether member has role r.
|
|
||||||
func (p *Policy) HasRole(member string, r RoleName) bool {
|
|
||||||
return memberIndex(member, p.binding(r)) >= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds member member to role r if it is not already present.
|
|
||||||
// A new binding is created if there is no binding for the role.
|
|
||||||
func (p *Policy) Add(member string, r RoleName) {
|
|
||||||
b := p.binding(r)
|
|
||||||
if b == nil {
|
|
||||||
if p.InternalProto == nil {
|
|
||||||
p.InternalProto = &pb.Policy{}
|
|
||||||
}
|
|
||||||
p.InternalProto.Bindings = append(p.InternalProto.Bindings, &pb.Binding{
|
|
||||||
Role: string(r),
|
|
||||||
Members: []string{member},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if memberIndex(member, b) < 0 {
|
|
||||||
b.Members = append(b.Members, member)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove removes member from role r if it is present.
|
|
||||||
func (p *Policy) Remove(member string, r RoleName) {
|
|
||||||
bi := p.bindingIndex(r)
|
|
||||||
if bi < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bindings := p.InternalProto.Bindings
|
|
||||||
b := bindings[bi]
|
|
||||||
mi := memberIndex(member, b)
|
|
||||||
if mi < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Order doesn't matter for bindings or members, so to remove, move the last item
|
|
||||||
// into the removed spot and shrink the slice.
|
|
||||||
if len(b.Members) == 1 {
|
|
||||||
// Remove binding.
|
|
||||||
last := len(bindings) - 1
|
|
||||||
bindings[bi] = bindings[last]
|
|
||||||
bindings[last] = nil
|
|
||||||
p.InternalProto.Bindings = bindings[:last]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Remove member.
|
|
||||||
// TODO(jba): worry about multiple copies of m?
|
|
||||||
last := len(b.Members) - 1
|
|
||||||
b.Members[mi] = b.Members[last]
|
|
||||||
b.Members[last] = ""
|
|
||||||
b.Members = b.Members[:last]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Roles returns the names of all the roles that appear in the Policy.
|
|
||||||
func (p *Policy) Roles() []RoleName {
|
|
||||||
if p.InternalProto == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var rns []RoleName
|
|
||||||
for _, b := range p.InternalProto.Bindings {
|
|
||||||
rns = append(rns, RoleName(b.Role))
|
|
||||||
}
|
|
||||||
return rns
|
|
||||||
}
|
|
||||||
|
|
||||||
// binding returns the Binding for the suppied role, or nil if there isn't one.
|
|
||||||
func (p *Policy) binding(r RoleName) *pb.Binding {
|
|
||||||
i := p.bindingIndex(r)
|
|
||||||
if i < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return p.InternalProto.Bindings[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Policy) bindingIndex(r RoleName) int {
|
|
||||||
if p.InternalProto == nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
for i, b := range p.InternalProto.Bindings {
|
|
||||||
if b.Role == string(r) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// memberIndex returns the index of m in b's Members, or -1 if not found.
|
|
||||||
func memberIndex(m string, b *pb.Binding) int {
|
|
||||||
if b == nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
for i, mm := range b.Members {
|
|
||||||
if mm == m {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// insertMetadata inserts metadata into the given context
|
|
||||||
func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
|
|
||||||
out, _ := metadata.FromOutgoingContext(ctx)
|
|
||||||
out = out.Copy()
|
|
||||||
for _, md := range mds {
|
|
||||||
for k, v := range md {
|
|
||||||
out[k] = append(out[k], v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metadata.NewOutgoingContext(ctx, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Policy3 is a list of Bindings representing roles granted to members.
|
|
||||||
//
|
|
||||||
// The zero Policy3 is a valid policy with no bindings.
|
|
||||||
//
|
|
||||||
// It is similar to a Policy, except a Policy3 provides direct access to the
|
|
||||||
// list of Bindings.
|
|
||||||
//
|
|
||||||
// The policy version is always set to 3.
|
|
||||||
type Policy3 struct {
|
|
||||||
etag []byte
|
|
||||||
Bindings []*pb.Binding
|
|
||||||
}
|
|
||||||
|
|
||||||
// Policy retrieves the IAM policy for the resource.
|
|
||||||
//
|
|
||||||
// requestedPolicyVersion is always set to 3.
|
|
||||||
func (h *Handle3) Policy(ctx context.Context) (*Policy3, error) {
|
|
||||||
proto, err := h.c.GetWithVersion(ctx, h.resource, h.version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Policy3{
|
|
||||||
Bindings: proto.Bindings,
|
|
||||||
etag: proto.Etag,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPolicy replaces the resource's current policy with the supplied Policy.
|
|
||||||
//
|
|
||||||
// If policy was created from a prior call to Get, then the modification will
|
|
||||||
// only succeed if the policy has not changed since the Get.
|
|
||||||
func (h *Handle3) SetPolicy(ctx context.Context, policy *Policy3) error {
|
|
||||||
return h.c.Set(ctx, h.resource, &pb.Policy{
|
|
||||||
Bindings: policy.Bindings,
|
|
||||||
Etag: policy.etag,
|
|
||||||
Version: h.version,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPermissions returns the subset of permissions that the caller has on the resource.
|
|
||||||
func (h *Handle3) TestPermissions(ctx context.Context, permissions []string) ([]string, error) {
|
|
||||||
return h.c.Test(ctx, h.resource, permissions)
|
|
||||||
}
|
|
914
vendor/cloud.google.com/go/internal/.repo-metadata-full.json
generated
vendored
914
vendor/cloud.google.com/go/internal/.repo-metadata-full.json
generated
vendored
|
@ -1,914 +0,0 @@
|
||||||
{
|
|
||||||
"cloud.google.com/go/accessapproval/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/accessapproval/apiv1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/accessapproval/apiv1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/analytics/admin/apiv1alpha": {
|
|
||||||
"distribution_name": "cloud.google.com/go/analytics/admin/apiv1alpha",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/analytics/admin/apiv1alpha",
|
|
||||||
"release_level": "alpha"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/analytics/data/apiv1alpha": {
|
|
||||||
"distribution_name": "cloud.google.com/go/analytics/data/apiv1alpha",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/analytics/data/apiv1alpha",
|
|
||||||
"release_level": "alpha"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/area120/tables/apiv1alpha1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/area120/tables/apiv1alpha1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/area120/tables/apiv1alpha1",
|
|
||||||
"release_level": "alpha"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/asset/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/asset/apiv1",
|
|
||||||
"description": "Cloud Asset API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/asset/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/asset/apiv1beta1",
|
|
||||||
"description": "Cloud Asset API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/asset/apiv1p2beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/asset/apiv1p2beta1",
|
|
||||||
"description": "Cloud Asset API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1p2beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/asset/apiv1p5beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/asset/apiv1p5beta1",
|
|
||||||
"description": "Cloud Asset API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1p5beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/assuredworkloads/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/assuredworkloads/apiv1beta1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/assuredworkloads/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/automl/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/automl/apiv1",
|
|
||||||
"description": "Cloud AutoML API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/automl/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/automl/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/automl/apiv1beta1",
|
|
||||||
"description": "Cloud AutoML API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/automl/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery",
|
|
||||||
"description": "BigQuery",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/connection/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/connection/apiv1",
|
|
||||||
"description": "BigQuery Connection API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/connection/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/connection/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/connection/apiv1beta1",
|
|
||||||
"description": "BigQuery Connection API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/connection/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/datatransfer/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/datatransfer/apiv1",
|
|
||||||
"description": "BigQuery Data Transfer API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/datatransfer/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/reservation/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/reservation/apiv1",
|
|
||||||
"description": "BigQuery Reservation API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/reservation/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/reservation/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/reservation/apiv1beta1",
|
|
||||||
"description": "BigQuery Reservation API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/reservation/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/storage/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/storage/apiv1",
|
|
||||||
"description": "BigQuery Storage API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/storage/apiv1alpha2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/storage/apiv1alpha2",
|
|
||||||
"description": "BigQuery Storage API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1alpha2",
|
|
||||||
"release_level": "alpha"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/storage/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/storage/apiv1beta1",
|
|
||||||
"description": "BigQuery Storage API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigquery/storage/apiv1beta2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigquery/storage/apiv1beta2",
|
|
||||||
"description": "BigQuery Storage API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1beta2",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/bigtable": {
|
|
||||||
"distribution_name": "cloud.google.com/go/bigtable",
|
|
||||||
"description": "Cloud BigTable",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigtable",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/billing/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/billing/apiv1",
|
|
||||||
"description": "Cloud Billing API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/billing/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/billing/budgets/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/billing/budgets/apiv1beta1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/billing/budgets/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/cloudbuild/apiv1/v2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/cloudbuild/apiv1/v2",
|
|
||||||
"description": "Cloud Build API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/cloudbuild/apiv1/v2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/cloudtasks/apiv2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/cloudtasks/apiv2",
|
|
||||||
"description": "Cloud Tasks API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/cloudtasks/apiv2beta2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/cloudtasks/apiv2beta2",
|
|
||||||
"description": "Cloud Tasks API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2beta2",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/cloudtasks/apiv2beta3": {
|
|
||||||
"distribution_name": "cloud.google.com/go/cloudtasks/apiv2beta3",
|
|
||||||
"description": "Cloud Tasks API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2beta3",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/container/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/container/apiv1",
|
|
||||||
"description": "Kubernetes Engine API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/container/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/containeranalysis/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/containeranalysis/apiv1beta1",
|
|
||||||
"description": "Container Analysis API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/containeranalysis/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/datacatalog/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/datacatalog/apiv1",
|
|
||||||
"description": "Google Cloud Data Catalog API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/datacatalog/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/datacatalog/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/datacatalog/apiv1beta1",
|
|
||||||
"description": "Google Cloud Data Catalog API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/datacatalog/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/dataproc/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/dataproc/apiv1",
|
|
||||||
"description": "Cloud Dataproc API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/dataproc/apiv1beta2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/dataproc/apiv1beta2",
|
|
||||||
"description": "Cloud Dataproc API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1beta2",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/datastore": {
|
|
||||||
"distribution_name": "cloud.google.com/go/datastore",
|
|
||||||
"description": "Cloud Datastore",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/datastore",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/datastore/admin/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/datastore/admin/apiv1",
|
|
||||||
"description": "Cloud Datastore API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/datastore/admin/apiv1",
|
|
||||||
"release_level": "alpha"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/debugger/apiv2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/debugger/apiv2",
|
|
||||||
"description": "Stackdriver Debugger API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/debugger/apiv2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/dialogflow/apiv2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/dialogflow/apiv2",
|
|
||||||
"description": "Dialogflow API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/dialogflow/apiv2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/dialogflow/cx/apiv3beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/dialogflow/cx/apiv3beta1",
|
|
||||||
"description": "Dialogflow API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/dialogflow/cx/apiv3beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/dlp/apiv2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/dlp/apiv2",
|
|
||||||
"description": "Cloud Data Loss Prevention (DLP) API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/dlp/apiv2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/errorreporting": {
|
|
||||||
"distribution_name": "cloud.google.com/go/errorreporting",
|
|
||||||
"description": "Cloud Error Reporting API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/errorreporting",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/errorreporting/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/errorreporting/apiv1beta1",
|
|
||||||
"description": "Cloud Error Reporting API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/errorreporting/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/firestore": {
|
|
||||||
"distribution_name": "cloud.google.com/go/firestore",
|
|
||||||
"description": "Cloud Firestore API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/firestore",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/firestore/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/firestore/apiv1",
|
|
||||||
"description": "Cloud Firestore API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/firestore/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/firestore/apiv1/admin": {
|
|
||||||
"distribution_name": "cloud.google.com/go/firestore/apiv1/admin",
|
|
||||||
"description": "Google Cloud Firestore Admin API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/firestore/apiv1/admin",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/functions/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/functions/apiv1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/functions/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/gaming/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/gaming/apiv1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/gaming/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/gaming/apiv1beta": {
|
|
||||||
"distribution_name": "cloud.google.com/go/gaming/apiv1beta",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/gaming/apiv1beta",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/iam": {
|
|
||||||
"distribution_name": "cloud.google.com/go/iam",
|
|
||||||
"description": "Cloud IAM",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/iam",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/iam/credentials/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/iam/credentials/apiv1",
|
|
||||||
"description": "IAM Service Account Credentials API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/iam/credentials/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/iot/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/iot/apiv1",
|
|
||||||
"description": "Cloud IoT API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/iot/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/kms/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/kms/apiv1",
|
|
||||||
"description": "Cloud Key Management Service (KMS) API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/kms/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/language/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/language/apiv1",
|
|
||||||
"description": "Cloud Natural Language API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/language/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/language/apiv1beta2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/language/apiv1beta2",
|
|
||||||
"description": "Cloud Natural Language API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/language/apiv1beta2",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/logging": {
|
|
||||||
"distribution_name": "cloud.google.com/go/logging",
|
|
||||||
"description": "Cloud Logging API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/logging",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/logging/apiv2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/logging/apiv2",
|
|
||||||
"description": "Cloud Logging API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/logging/apiv2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/longrunning/autogen": {
|
|
||||||
"distribution_name": "cloud.google.com/go/longrunning/autogen",
|
|
||||||
"description": "Long Running Operations API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/longrunning/autogen",
|
|
||||||
"release_level": "alpha"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/memcache/apiv1beta2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/memcache/apiv1beta2",
|
|
||||||
"description": "Cloud Memorystore for Memcached API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/memcache/apiv1beta2",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/monitoring/apiv3/v2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/monitoring/apiv3/v2",
|
|
||||||
"description": "Cloud Monitoring API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/monitoring/apiv3/v2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/monitoring/dashboard/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/monitoring/dashboard/apiv1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/monitoring/dashboard/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/notebooks/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/notebooks/apiv1beta1",
|
|
||||||
"description": "Notebooks API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/notebooks/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/osconfig/agentendpoint/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/osconfig/agentendpoint/apiv1",
|
|
||||||
"description": "Cloud OS Config API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/osconfig/agentendpoint/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/osconfig/agentendpoint/apiv1beta": {
|
|
||||||
"distribution_name": "cloud.google.com/go/osconfig/agentendpoint/apiv1beta",
|
|
||||||
"description": "Cloud OS Config API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/osconfig/agentendpoint/apiv1beta",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/osconfig/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/osconfig/apiv1",
|
|
||||||
"description": "Cloud OS Config API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/osconfig/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/osconfig/apiv1beta": {
|
|
||||||
"distribution_name": "cloud.google.com/go/osconfig/apiv1beta",
|
|
||||||
"description": "Cloud OS Config API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/osconfig/apiv1beta",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/oslogin/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/oslogin/apiv1",
|
|
||||||
"description": "Cloud OS Login API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/oslogin/apiv1beta": {
|
|
||||||
"distribution_name": "cloud.google.com/go/oslogin/apiv1beta",
|
|
||||||
"description": "Cloud OS Login API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1beta",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/phishingprotection/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/phishingprotection/apiv1beta1",
|
|
||||||
"description": "Phishing Protection API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/phishingprotection/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/policytroubleshooter/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/policytroubleshooter/apiv1",
|
|
||||||
"description": "Policy Troubleshooter API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/policytroubleshooter/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/profiler": {
|
|
||||||
"distribution_name": "cloud.google.com/go/profiler",
|
|
||||||
"description": "Cloud Profiler",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/profiler",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/pubsub": {
|
|
||||||
"distribution_name": "cloud.google.com/go/pubsub",
|
|
||||||
"description": "Cloud PubSub",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/pubsub",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/pubsub/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/pubsub/apiv1",
|
|
||||||
"description": "Cloud Pub/Sub API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/pubsub/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/pubsublite/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/pubsublite/apiv1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/pubsublite/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/recaptchaenterprise/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/recaptchaenterprise/apiv1",
|
|
||||||
"description": "reCAPTCHA Enterprise API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/recaptchaenterprise/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/recaptchaenterprise/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/recaptchaenterprise/apiv1beta1",
|
|
||||||
"description": "reCAPTCHA Enterprise API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/recaptchaenterprise/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/recommender/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/recommender/apiv1",
|
|
||||||
"description": "Recommender API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/recommender/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/recommender/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/recommender/apiv1beta1",
|
|
||||||
"description": "Recommender API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/recommender/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/redis/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/redis/apiv1",
|
|
||||||
"description": "Google Cloud Memorystore for Redis API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/redis/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/redis/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/redis/apiv1beta1",
|
|
||||||
"description": "Google Cloud Memorystore for Redis API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/redis/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/rpcreplay": {
|
|
||||||
"distribution_name": "cloud.google.com/go/rpcreplay",
|
|
||||||
"description": "RPC Replay",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/rpcreplay",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/scheduler/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/scheduler/apiv1",
|
|
||||||
"description": "Cloud Scheduler API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/scheduler/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/scheduler/apiv1beta1",
|
|
||||||
"description": "Cloud Scheduler API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/secretmanager/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/secretmanager/apiv1",
|
|
||||||
"description": "Secret Manager API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/secretmanager/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/secretmanager/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/secretmanager/apiv1beta1",
|
|
||||||
"description": "Secret Manager API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/secretmanager/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/security/privateca/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/security/privateca/apiv1beta1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/security/privateca/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/securitycenter/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/securitycenter/apiv1",
|
|
||||||
"description": "Security Command Center API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/securitycenter/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/securitycenter/apiv1beta1",
|
|
||||||
"description": "Security Command Center API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/securitycenter/apiv1p1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/securitycenter/apiv1p1beta1",
|
|
||||||
"description": "Security Command Center API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1p1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/securitycenter/settings/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/securitycenter/settings/apiv1beta1",
|
|
||||||
"description": "Cloud Security Command Center API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/settings/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/servicedirectory/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/servicedirectory/apiv1beta1",
|
|
||||||
"description": "Service Directory API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/servicedirectory/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/spanner": {
|
|
||||||
"distribution_name": "cloud.google.com/go/spanner",
|
|
||||||
"description": "Cloud Spanner",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/spanner",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/spanner/admin/database/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/spanner/admin/database/apiv1",
|
|
||||||
"description": "Cloud Spanner Database Admin API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/spanner/admin/database/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/spanner/admin/instance/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/spanner/admin/instance/apiv1",
|
|
||||||
"description": "Cloud Spanner Instance Admin API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/spanner/admin/instance/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/spanner/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/spanner/apiv1",
|
|
||||||
"description": "Cloud Spanner API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/spanner/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/speech/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/speech/apiv1",
|
|
||||||
"description": "Cloud Speech-to-Text API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/speech/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/speech/apiv1p1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/speech/apiv1p1beta1",
|
|
||||||
"description": "Cloud Speech-to-Text API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/speech/apiv1p1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/storage": {
|
|
||||||
"distribution_name": "cloud.google.com/go/storage",
|
|
||||||
"description": "Cloud Storage (GCS)",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/storage",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/talent/apiv4": {
|
|
||||||
"distribution_name": "cloud.google.com/go/talent/apiv4",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/talent/apiv4",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/talent/apiv4beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/talent/apiv4beta1",
|
|
||||||
"description": "Cloud Talent Solution API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/talent/apiv4beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/texttospeech/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/texttospeech/apiv1",
|
|
||||||
"description": "Cloud Text-to-Speech API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/texttospeech/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/trace": {
|
|
||||||
"distribution_name": "cloud.google.com/go/trace",
|
|
||||||
"description": "Stackdriver Trace",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "manual",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/trace",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/trace/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/trace/apiv1",
|
|
||||||
"description": "Stackdriver Trace API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/trace/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/trace/apiv2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/trace/apiv2",
|
|
||||||
"description": "Stackdriver Trace API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/trace/apiv2",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/translate/apiv3": {
|
|
||||||
"distribution_name": "cloud.google.com/go/translate/apiv3",
|
|
||||||
"description": "Cloud Translation API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/translate/apiv3",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/video/transcoder/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/video/transcoder/apiv1beta1",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/video/transcoder/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/videointelligence/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/videointelligence/apiv1",
|
|
||||||
"description": "Cloud Video Intelligence API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/videointelligence/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/videointelligence/apiv1beta2": {
|
|
||||||
"distribution_name": "cloud.google.com/go/videointelligence/apiv1beta2",
|
|
||||||
"description": "Google Cloud Video Intelligence API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/videointelligence/apiv1beta2",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/vision/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/vision/apiv1",
|
|
||||||
"description": "Cloud Vision API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/vision/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/vision/apiv1p1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/vision/apiv1p1beta1",
|
|
||||||
"description": "Cloud Vision API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/vision/apiv1p1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/webrisk/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/webrisk/apiv1",
|
|
||||||
"description": "Web Risk API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/webrisk/apiv1",
|
|
||||||
"release_level": "ga"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/webrisk/apiv1beta1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/webrisk/apiv1beta1",
|
|
||||||
"description": "Web Risk API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/webrisk/apiv1beta1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/websecurityscanner/apiv1": {
|
|
||||||
"distribution_name": "cloud.google.com/go/websecurityscanner/apiv1",
|
|
||||||
"description": "Web Security Scanner API",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/websecurityscanner/apiv1",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/workflows/apiv1beta": {
|
|
||||||
"distribution_name": "cloud.google.com/go/workflows/apiv1beta",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/workflows/apiv1beta",
|
|
||||||
"release_level": "beta"
|
|
||||||
},
|
|
||||||
"cloud.google.com/go/workflows/executions/apiv1beta": {
|
|
||||||
"distribution_name": "cloud.google.com/go/workflows/executions/apiv1beta",
|
|
||||||
"description": "",
|
|
||||||
"language": "Go",
|
|
||||||
"client_library_type": "generated",
|
|
||||||
"docs_url": "https://pkg.go.dev/cloud.google.com/go/workflows/executions/apiv1beta",
|
|
||||||
"release_level": "beta"
|
|
||||||
}
|
|
||||||
}
|
|
18
vendor/cloud.google.com/go/internal/README.md
generated
vendored
18
vendor/cloud.google.com/go/internal/README.md
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
# Internal
|
|
||||||
|
|
||||||
This directory contains internal code for cloud.google.com/go packages.
|
|
||||||
|
|
||||||
## .repo-metadata-full.json
|
|
||||||
|
|
||||||
`.repo-metadata-full.json` contains metadata about the packages in this repo. It
|
|
||||||
is generated by `internal/gapicgen/generator`. It's processed by external tools
|
|
||||||
to build lists of all of the packages.
|
|
||||||
|
|
||||||
Don't make breaking changes to the format without consulting with the external
|
|
||||||
tools.
|
|
||||||
|
|
||||||
One day, we may want to create individual `.repo-metadata.json` files next to
|
|
||||||
each package, which is the pattern followed by some other languages. External
|
|
||||||
tools would then talk to pkg.go.dev or some other service to get the overall
|
|
||||||
list of packages and use the `.repo-metadata.json` files to get the additional
|
|
||||||
metadata required. For now, `.repo-metadata-full.json` includes everything.
|
|
54
vendor/cloud.google.com/go/internal/annotate.go
generated
vendored
54
vendor/cloud.google.com/go/internal/annotate.go
generated
vendored
|
@ -1,54 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Annotate prepends msg to the error message in err, attempting
|
|
||||||
// to preserve other information in err, like an error code.
|
|
||||||
//
|
|
||||||
// Annotate panics if err is nil.
|
|
||||||
//
|
|
||||||
// Annotate knows about these error types:
|
|
||||||
// - "google.golang.org/grpc/status".Status
|
|
||||||
// - "google.golang.org/api/googleapi".Error
|
|
||||||
// If the error is not one of these types, Annotate behaves
|
|
||||||
// like
|
|
||||||
// fmt.Errorf("%s: %v", msg, err)
|
|
||||||
func Annotate(err error, msg string) error {
|
|
||||||
if err == nil {
|
|
||||||
panic("Annotate called with nil")
|
|
||||||
}
|
|
||||||
if s, ok := status.FromError(err); ok {
|
|
||||||
p := s.Proto()
|
|
||||||
p.Message = msg + ": " + p.Message
|
|
||||||
return status.ErrorProto(p)
|
|
||||||
}
|
|
||||||
if g, ok := err.(*googleapi.Error); ok {
|
|
||||||
g.Message = msg + ": " + g.Message
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
return fmt.Errorf("%s: %v", msg, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Annotatef uses format and args to format a string, then calls Annotate.
|
|
||||||
func Annotatef(err error, format string, args ...interface{}) error {
|
|
||||||
return Annotate(err, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
108
vendor/cloud.google.com/go/internal/optional/optional.go
generated
vendored
108
vendor/cloud.google.com/go/internal/optional/optional.go
generated
vendored
|
@ -1,108 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package optional provides versions of primitive types that can
|
|
||||||
// be nil. These are useful in methods that update some of an API object's
|
|
||||||
// fields.
|
|
||||||
package optional
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// Bool is either a bool or nil.
|
|
||||||
Bool interface{}
|
|
||||||
|
|
||||||
// String is either a string or nil.
|
|
||||||
String interface{}
|
|
||||||
|
|
||||||
// Int is either an int or nil.
|
|
||||||
Int interface{}
|
|
||||||
|
|
||||||
// Uint is either a uint or nil.
|
|
||||||
Uint interface{}
|
|
||||||
|
|
||||||
// Float64 is either a float64 or nil.
|
|
||||||
Float64 interface{}
|
|
||||||
|
|
||||||
// Duration is either a time.Duration or nil.
|
|
||||||
Duration interface{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToBool returns its argument as a bool.
|
|
||||||
// It panics if its argument is nil or not a bool.
|
|
||||||
func ToBool(v Bool) bool {
|
|
||||||
x, ok := v.(bool)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Bool", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToString returns its argument as a string.
|
|
||||||
// It panics if its argument is nil or not a string.
|
|
||||||
func ToString(v String) string {
|
|
||||||
x, ok := v.(string)
|
|
||||||
if !ok {
|
|
||||||
doPanic("String", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToInt returns its argument as an int.
|
|
||||||
// It panics if its argument is nil or not an int.
|
|
||||||
func ToInt(v Int) int {
|
|
||||||
x, ok := v.(int)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Int", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToUint returns its argument as a uint.
|
|
||||||
// It panics if its argument is nil or not a uint.
|
|
||||||
func ToUint(v Uint) uint {
|
|
||||||
x, ok := v.(uint)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Uint", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToFloat64 returns its argument as a float64.
|
|
||||||
// It panics if its argument is nil or not a float64.
|
|
||||||
func ToFloat64(v Float64) float64 {
|
|
||||||
x, ok := v.(float64)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Float64", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToDuration returns its argument as a time.Duration.
|
|
||||||
// It panics if its argument is nil or not a time.Duration.
|
|
||||||
func ToDuration(v Duration) time.Duration {
|
|
||||||
x, ok := v.(time.Duration)
|
|
||||||
if !ok {
|
|
||||||
doPanic("Duration", v)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
func doPanic(capType string, v interface{}) {
|
|
||||||
panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v))
|
|
||||||
}
|
|
54
vendor/cloud.google.com/go/internal/retry.go
generated
vendored
54
vendor/cloud.google.com/go/internal/retry.go
generated
vendored
|
@ -1,54 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Retry calls the supplied function f repeatedly according to the provided
|
|
||||||
// backoff parameters. It returns when one of the following occurs:
|
|
||||||
// When f's first return value is true, Retry immediately returns with f's second
|
|
||||||
// return value.
|
|
||||||
// When the provided context is done, Retry returns with an error that
|
|
||||||
// includes both ctx.Error() and the last error returned by f.
|
|
||||||
func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error {
|
|
||||||
return retry(ctx, bo, f, gax.Sleep)
|
|
||||||
}
|
|
||||||
|
|
||||||
func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error),
|
|
||||||
sleep func(context.Context, time.Duration) error) error {
|
|
||||||
var lastErr error
|
|
||||||
for {
|
|
||||||
stop, err := f()
|
|
||||||
if stop {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Remember the last "real" error from f.
|
|
||||||
if err != nil && err != context.Canceled && err != context.DeadlineExceeded {
|
|
||||||
lastErr = err
|
|
||||||
}
|
|
||||||
p := bo.Pause()
|
|
||||||
if cerr := sleep(ctx, p); cerr != nil {
|
|
||||||
if lastErr != nil {
|
|
||||||
return Annotatef(lastErr, "retry failed with %v; last error", cerr)
|
|
||||||
}
|
|
||||||
return cerr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
109
vendor/cloud.google.com/go/internal/trace/trace.go
generated
vendored
109
vendor/cloud.google.com/go/internal/trace/trace.go
generated
vendored
|
@ -1,109 +0,0 @@
|
||||||
// Copyright 2018 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package trace
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"go.opencensus.io/trace"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/genproto/googleapis/rpc/code"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StartSpan adds a span to the trace with the given name.
|
|
||||||
func StartSpan(ctx context.Context, name string) context.Context {
|
|
||||||
ctx, _ = trace.StartSpan(ctx, name)
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
// EndSpan ends a span with the given error.
|
|
||||||
func EndSpan(ctx context.Context, err error) {
|
|
||||||
span := trace.FromContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
span.SetStatus(toStatus(err))
|
|
||||||
}
|
|
||||||
span.End()
|
|
||||||
}
|
|
||||||
|
|
||||||
// toStatus interrogates an error and converts it to an appropriate
|
|
||||||
// OpenCensus status.
|
|
||||||
func toStatus(err error) trace.Status {
|
|
||||||
if err2, ok := err.(*googleapi.Error); ok {
|
|
||||||
return trace.Status{Code: httpStatusCodeToOCCode(err2.Code), Message: err2.Message}
|
|
||||||
} else if s, ok := status.FromError(err); ok {
|
|
||||||
return trace.Status{Code: int32(s.Code()), Message: s.Message()}
|
|
||||||
} else {
|
|
||||||
return trace.Status{Code: int32(code.Code_UNKNOWN), Message: err.Error()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(deklerk): switch to using OpenCensus function when it becomes available.
|
|
||||||
// Reference: https://github.com/googleapis/googleapis/blob/26b634d2724ac5dd30ae0b0cbfb01f07f2e4050e/google/rpc/code.proto
|
|
||||||
func httpStatusCodeToOCCode(httpStatusCode int) int32 {
|
|
||||||
switch httpStatusCode {
|
|
||||||
case 200:
|
|
||||||
return int32(code.Code_OK)
|
|
||||||
case 499:
|
|
||||||
return int32(code.Code_CANCELLED)
|
|
||||||
case 500:
|
|
||||||
return int32(code.Code_UNKNOWN) // Could also be Code_INTERNAL, Code_DATA_LOSS
|
|
||||||
case 400:
|
|
||||||
return int32(code.Code_INVALID_ARGUMENT) // Could also be Code_OUT_OF_RANGE
|
|
||||||
case 504:
|
|
||||||
return int32(code.Code_DEADLINE_EXCEEDED)
|
|
||||||
case 404:
|
|
||||||
return int32(code.Code_NOT_FOUND)
|
|
||||||
case 409:
|
|
||||||
return int32(code.Code_ALREADY_EXISTS) // Could also be Code_ABORTED
|
|
||||||
case 403:
|
|
||||||
return int32(code.Code_PERMISSION_DENIED)
|
|
||||||
case 401:
|
|
||||||
return int32(code.Code_UNAUTHENTICATED)
|
|
||||||
case 429:
|
|
||||||
return int32(code.Code_RESOURCE_EXHAUSTED)
|
|
||||||
case 501:
|
|
||||||
return int32(code.Code_UNIMPLEMENTED)
|
|
||||||
case 503:
|
|
||||||
return int32(code.Code_UNAVAILABLE)
|
|
||||||
default:
|
|
||||||
return int32(code.Code_UNKNOWN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: (odeke-em): perhaps just pass around spans due to the cost
|
|
||||||
// incurred from using trace.FromContext(ctx) yet we could avoid
|
|
||||||
// throwing away the work done by ctx, span := trace.StartSpan.
|
|
||||||
func TracePrintf(ctx context.Context, attrMap map[string]interface{}, format string, args ...interface{}) {
|
|
||||||
var attrs []trace.Attribute
|
|
||||||
for k, v := range attrMap {
|
|
||||||
var a trace.Attribute
|
|
||||||
switch v := v.(type) {
|
|
||||||
case string:
|
|
||||||
a = trace.StringAttribute(k, v)
|
|
||||||
case bool:
|
|
||||||
a = trace.BoolAttribute(k, v)
|
|
||||||
case int:
|
|
||||||
a = trace.Int64Attribute(k, int64(v))
|
|
||||||
case int64:
|
|
||||||
a = trace.Int64Attribute(k, v)
|
|
||||||
default:
|
|
||||||
a = trace.StringAttribute(k, fmt.Sprintf("%#v", v))
|
|
||||||
}
|
|
||||||
attrs = append(attrs, a)
|
|
||||||
}
|
|
||||||
trace.FromContext(ctx).Annotatef(attrs, format, args...)
|
|
||||||
}
|
|
19
vendor/cloud.google.com/go/internal/version/update_version.sh
generated
vendored
19
vendor/cloud.google.com/go/internal/version/update_version.sh
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2019 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
today=$(date +%Y%m%d)
|
|
||||||
|
|
||||||
sed -i -r -e 's/const Repo = "([0-9]{8})"/const Repo = "'$today'"/' $GOFILE
|
|
||||||
|
|
71
vendor/cloud.google.com/go/internal/version/version.go
generated
vendored
71
vendor/cloud.google.com/go/internal/version/version.go
generated
vendored
|
@ -1,71 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
//go:generate ./update_version.sh
|
|
||||||
|
|
||||||
// Package version contains version information for Google Cloud Client
|
|
||||||
// Libraries for Go, as reported in request headers.
|
|
||||||
package version
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Repo is the current version of the client libraries in this
|
|
||||||
// repo. It should be a date in YYYYMMDD format.
|
|
||||||
const Repo = "20201012"
|
|
||||||
|
|
||||||
// Go returns the Go runtime version. The returned string
|
|
||||||
// has no whitespace.
|
|
||||||
func Go() string {
|
|
||||||
return goVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
var goVersion = goVer(runtime.Version())
|
|
||||||
|
|
||||||
const develPrefix = "devel +"
|
|
||||||
|
|
||||||
func goVer(s string) string {
|
|
||||||
if strings.HasPrefix(s, develPrefix) {
|
|
||||||
s = s[len(develPrefix):]
|
|
||||||
if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
|
|
||||||
s = s[:p]
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(s, "go1") {
|
|
||||||
s = s[2:]
|
|
||||||
var prerelease string
|
|
||||||
if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
|
|
||||||
s, prerelease = s[:p], s[p:]
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(s, ".") {
|
|
||||||
s += "0"
|
|
||||||
} else if strings.Count(s, ".") < 2 {
|
|
||||||
s += ".0"
|
|
||||||
}
|
|
||||||
if prerelease != "" {
|
|
||||||
s += "-" + prerelease
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func notSemverRune(r rune) bool {
|
|
||||||
return !strings.ContainsRune("0123456789.", r)
|
|
||||||
}
|
|
94
vendor/cloud.google.com/go/storage/CHANGES.md
generated
vendored
94
vendor/cloud.google.com/go/storage/CHANGES.md
generated
vendored
|
@ -1,94 +0,0 @@
|
||||||
# Changes
|
|
||||||
|
|
||||||
## v1.12.0
|
|
||||||
- V4 signed URL fixes:
|
|
||||||
- Fix encoding of spaces in query parameters.
|
|
||||||
- Add fields that were missing from PostPolicyV4 policy conditions.
|
|
||||||
- Fix Query to correctly list prefixes as well as objects when SetAttrSelection
|
|
||||||
is used.
|
|
||||||
|
|
||||||
## v1.11.0
|
|
||||||
- Add support for CustomTime and NoncurrentTime object lifecycle management
|
|
||||||
features.
|
|
||||||
|
|
||||||
## v1.10.0
|
|
||||||
- Bump dependency on google.golang.org/api to capture changes to retry logic
|
|
||||||
which will make retries on writes more resilient.
|
|
||||||
- Improve documentation for Writer.ChunkSize.
|
|
||||||
- Fix a bug in lifecycle to allow callers to clear lifecycle rules on a bucket.
|
|
||||||
|
|
||||||
## v1.9.0
|
|
||||||
- Add retry for transient network errors on most operations (with the exception
|
|
||||||
of writes).
|
|
||||||
- Bump dependency for google.golang.org/api to capture a change in the default
|
|
||||||
HTTP transport which will improve performance for reads under heavy load.
|
|
||||||
- Add CRC32C checksum validation option to Composer.
|
|
||||||
|
|
||||||
## v1.8.0
|
|
||||||
- Add support for V4 signed post policies.
|
|
||||||
|
|
||||||
## v1.7.0
|
|
||||||
- V4 signed URL support:
|
|
||||||
- Add support for bucket-bound domains and virtual hosted style URLs.
|
|
||||||
- Add support for query parameters in the signature.
|
|
||||||
- Fix text encoding to align with standards.
|
|
||||||
- Add the object name to query parameters for write calls.
|
|
||||||
- Fix retry behavior when reading files with Content-Encoding gzip.
|
|
||||||
- Fix response header in reader.
|
|
||||||
- New code examples:
|
|
||||||
- Error handling for `ObjectHandle` preconditions.
|
|
||||||
- Existence checks for buckets and objects.
|
|
||||||
|
|
||||||
## v1.6.0
|
|
||||||
|
|
||||||
- Updated option handling:
|
|
||||||
- Don't drop custom scopes (#1756)
|
|
||||||
- Don't drop port in provided endpoint (#1737)
|
|
||||||
|
|
||||||
## v1.5.0
|
|
||||||
|
|
||||||
- Honor WithEndpoint client option for reads as well as writes.
|
|
||||||
- Add archive storage class to docs.
|
|
||||||
- Make fixes to storage benchwrapper.
|
|
||||||
|
|
||||||
## v1.4.0
|
|
||||||
|
|
||||||
- When listing objects in a bucket, allow callers to specify which attributes
|
|
||||||
are queried. This allows for performance optimization.
|
|
||||||
|
|
||||||
## v1.3.0
|
|
||||||
|
|
||||||
- Use `storage.googleapis.com/storage/v1` by default for GCS requests
|
|
||||||
instead of `www.googleapis.com/storage/v1`.
|
|
||||||
|
|
||||||
## v1.2.1
|
|
||||||
|
|
||||||
- Fixed a bug where UniformBucketLevelAccess and BucketPolicyOnly were not
|
|
||||||
being sent in all cases.
|
|
||||||
|
|
||||||
## v1.2.0
|
|
||||||
|
|
||||||
- Add support for UniformBucketLevelAccess. This configures access checks
|
|
||||||
to use only bucket-level IAM policies.
|
|
||||||
See: https://godoc.org/cloud.google.com/go/storage#UniformBucketLevelAccess.
|
|
||||||
- Fix userAgent to use correct version.
|
|
||||||
|
|
||||||
## v1.1.2
|
|
||||||
|
|
||||||
- Fix memory leak in BucketIterator and ObjectIterator.
|
|
||||||
|
|
||||||
## v1.1.1
|
|
||||||
|
|
||||||
- Send BucketPolicyOnly even when it's disabled.
|
|
||||||
|
|
||||||
## v1.1.0
|
|
||||||
|
|
||||||
- Performance improvements for ObjectIterator and BucketIterator.
|
|
||||||
- Fix Bucket.ObjectIterator size calculation checks.
|
|
||||||
- Added HMACKeyOptions to all the methods which allows for options such as
|
|
||||||
UserProject to be set per invocation and optionally be used.
|
|
||||||
|
|
||||||
## v1.0.0
|
|
||||||
|
|
||||||
This is the first tag to carve out storage as its own module. See:
|
|
||||||
https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.
|
|
202
vendor/cloud.google.com/go/storage/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/storage/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
32
vendor/cloud.google.com/go/storage/README.md
generated
vendored
32
vendor/cloud.google.com/go/storage/README.md
generated
vendored
|
@ -1,32 +0,0 @@
|
||||||
## Cloud Storage [![GoDoc](https://godoc.org/cloud.google.com/go/storage?status.svg)](https://godoc.org/cloud.google.com/go/storage)
|
|
||||||
|
|
||||||
- [About Cloud Storage](https://cloud.google.com/storage/)
|
|
||||||
- [API documentation](https://cloud.google.com/storage/docs)
|
|
||||||
- [Go client documentation](https://godoc.org/cloud.google.com/go/storage)
|
|
||||||
- [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/storage)
|
|
||||||
|
|
||||||
### Example Usage
|
|
||||||
|
|
||||||
First create a `storage.Client` to use throughout your application:
|
|
||||||
|
|
||||||
[snip]:# (storage-1)
|
|
||||||
```go
|
|
||||||
client, err := storage.NewClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[snip]:# (storage-2)
|
|
||||||
```go
|
|
||||||
// Read the object1 from bucket.
|
|
||||||
rc, err := client.Bucket("bucket").Object("object1").NewReader(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer rc.Close()
|
|
||||||
body, err := ioutil.ReadAll(rc)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
```
|
|
335
vendor/cloud.google.com/go/storage/acl.go
generated
vendored
335
vendor/cloud.google.com/go/storage/acl.go
generated
vendored
|
@ -1,335 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACLRole is the level of access to grant.
|
|
||||||
type ACLRole string
|
|
||||||
|
|
||||||
const (
|
|
||||||
RoleOwner ACLRole = "OWNER"
|
|
||||||
RoleReader ACLRole = "READER"
|
|
||||||
RoleWriter ACLRole = "WRITER"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACLEntity refers to a user or group.
|
|
||||||
// They are sometimes referred to as grantees.
|
|
||||||
//
|
|
||||||
// It could be in the form of:
|
|
||||||
// "user-<userId>", "user-<email>", "group-<groupId>", "group-<email>",
|
|
||||||
// "domain-<domain>" and "project-team-<projectId>".
|
|
||||||
//
|
|
||||||
// Or one of the predefined constants: AllUsers, AllAuthenticatedUsers.
|
|
||||||
type ACLEntity string
|
|
||||||
|
|
||||||
const (
|
|
||||||
AllUsers ACLEntity = "allUsers"
|
|
||||||
AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACLRule represents a grant for a role to an entity (user, group or team) for a
|
|
||||||
// Google Cloud Storage object or bucket.
|
|
||||||
type ACLRule struct {
|
|
||||||
Entity ACLEntity
|
|
||||||
EntityID string
|
|
||||||
Role ACLRole
|
|
||||||
Domain string
|
|
||||||
Email string
|
|
||||||
ProjectTeam *ProjectTeam
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectTeam is the project team associated with the entity, if any.
|
|
||||||
type ProjectTeam struct {
|
|
||||||
ProjectNumber string
|
|
||||||
Team string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object.
|
|
||||||
type ACLHandle struct {
|
|
||||||
c *Client
|
|
||||||
bucket string
|
|
||||||
object string
|
|
||||||
isDefault bool
|
|
||||||
userProject string // for requester-pays buckets
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete permanently deletes the ACL entry for the given entity.
|
|
||||||
func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Delete")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if a.object != "" {
|
|
||||||
return a.objectDelete(ctx, entity)
|
|
||||||
}
|
|
||||||
if a.isDefault {
|
|
||||||
return a.bucketDefaultDelete(ctx, entity)
|
|
||||||
}
|
|
||||||
return a.bucketDelete(ctx, entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the role for the given entity.
|
|
||||||
func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Set")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if a.object != "" {
|
|
||||||
return a.objectSet(ctx, entity, role, false)
|
|
||||||
}
|
|
||||||
if a.isDefault {
|
|
||||||
return a.objectSet(ctx, entity, role, true)
|
|
||||||
}
|
|
||||||
return a.bucketSet(ctx, entity, role)
|
|
||||||
}
|
|
||||||
|
|
||||||
// List retrieves ACL entries.
|
|
||||||
func (a *ACLHandle) List(ctx context.Context) (rules []ACLRule, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.List")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if a.object != "" {
|
|
||||||
return a.objectList(ctx)
|
|
||||||
}
|
|
||||||
if a.isDefault {
|
|
||||||
return a.bucketDefaultList(ctx)
|
|
||||||
}
|
|
||||||
return a.bucketList(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) {
|
|
||||||
var acls *raw.ObjectAccessControls
|
|
||||||
var err error
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.DefaultObjectAccessControls.List(a.bucket)
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
acls, err = req.Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return toObjectACLRules(acls.Items), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error {
|
|
||||||
return runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity))
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
return req.Do()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) {
|
|
||||||
var acls *raw.BucketAccessControls
|
|
||||||
var err error
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.BucketAccessControls.List(a.bucket)
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
acls, err = req.Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return toBucketACLRules(acls.Items), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error {
|
|
||||||
acl := &raw.BucketAccessControl{
|
|
||||||
Bucket: a.bucket,
|
|
||||||
Entity: string(entity),
|
|
||||||
Role: string(role),
|
|
||||||
}
|
|
||||||
err := runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl)
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
_, err := req.Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error {
|
|
||||||
return runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity))
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
return req.Do()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) {
|
|
||||||
var acls *raw.ObjectAccessControls
|
|
||||||
var err error
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.ObjectAccessControls.List(a.bucket, a.object)
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
acls, err = req.Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return toObjectACLRules(acls.Items), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error {
|
|
||||||
type setRequest interface {
|
|
||||||
Do(opts ...googleapi.CallOption) (*raw.ObjectAccessControl, error)
|
|
||||||
Header() http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
acl := &raw.ObjectAccessControl{
|
|
||||||
Bucket: a.bucket,
|
|
||||||
Entity: string(entity),
|
|
||||||
Role: string(role),
|
|
||||||
}
|
|
||||||
var req setRequest
|
|
||||||
if isBucketDefault {
|
|
||||||
req = a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl)
|
|
||||||
} else {
|
|
||||||
req = a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl)
|
|
||||||
}
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
return runWithRetry(ctx, func() error {
|
|
||||||
_, err := req.Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error {
|
|
||||||
return runWithRetry(ctx, func() error {
|
|
||||||
req := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity))
|
|
||||||
a.configureCall(ctx, req)
|
|
||||||
return req.Do()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACLHandle) configureCall(ctx context.Context, call interface{ Header() http.Header }) {
|
|
||||||
vc := reflect.ValueOf(call)
|
|
||||||
vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)})
|
|
||||||
if a.userProject != "" {
|
|
||||||
vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)})
|
|
||||||
}
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectACLRules(items []*raw.ObjectAccessControl) []ACLRule {
|
|
||||||
var rs []ACLRule
|
|
||||||
for _, item := range items {
|
|
||||||
rs = append(rs, toObjectACLRule(item))
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketACLRules(items []*raw.BucketAccessControl) []ACLRule {
|
|
||||||
var rs []ACLRule
|
|
||||||
for _, item := range items {
|
|
||||||
rs = append(rs, toBucketACLRule(item))
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectACLRule(a *raw.ObjectAccessControl) ACLRule {
|
|
||||||
return ACLRule{
|
|
||||||
Entity: ACLEntity(a.Entity),
|
|
||||||
EntityID: a.EntityId,
|
|
||||||
Role: ACLRole(a.Role),
|
|
||||||
Domain: a.Domain,
|
|
||||||
Email: a.Email,
|
|
||||||
ProjectTeam: toObjectProjectTeam(a.ProjectTeam),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketACLRule(a *raw.BucketAccessControl) ACLRule {
|
|
||||||
return ACLRule{
|
|
||||||
Entity: ACLEntity(a.Entity),
|
|
||||||
EntityID: a.EntityId,
|
|
||||||
Role: ACLRole(a.Role),
|
|
||||||
Domain: a.Domain,
|
|
||||||
Email: a.Email,
|
|
||||||
ProjectTeam: toBucketProjectTeam(a.ProjectTeam),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toRawObjectACL(rules []ACLRule) []*raw.ObjectAccessControl {
|
|
||||||
if len(rules) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := make([]*raw.ObjectAccessControl, 0, len(rules))
|
|
||||||
for _, rule := range rules {
|
|
||||||
r = append(r, rule.toRawObjectAccessControl("")) // bucket name unnecessary
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func toRawBucketACL(rules []ACLRule) []*raw.BucketAccessControl {
|
|
||||||
if len(rules) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := make([]*raw.BucketAccessControl, 0, len(rules))
|
|
||||||
for _, rule := range rules {
|
|
||||||
r = append(r, rule.toRawBucketAccessControl("")) // bucket name unnecessary
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ACLRule) toRawBucketAccessControl(bucket string) *raw.BucketAccessControl {
|
|
||||||
return &raw.BucketAccessControl{
|
|
||||||
Bucket: bucket,
|
|
||||||
Entity: string(r.Entity),
|
|
||||||
Role: string(r.Role),
|
|
||||||
// The other fields are not settable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ACLRule) toRawObjectAccessControl(bucket string) *raw.ObjectAccessControl {
|
|
||||||
return &raw.ObjectAccessControl{
|
|
||||||
Bucket: bucket,
|
|
||||||
Entity: string(r.Entity),
|
|
||||||
Role: string(r.Role),
|
|
||||||
// The other fields are not settable.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBucketProjectTeam(p *raw.BucketAccessControlProjectTeam) *ProjectTeam {
|
|
||||||
if p == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &ProjectTeam{
|
|
||||||
ProjectNumber: p.ProjectNumber,
|
|
||||||
Team: p.Team,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toObjectProjectTeam(p *raw.ObjectAccessControlProjectTeam) *ProjectTeam {
|
|
||||||
if p == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &ProjectTeam{
|
|
||||||
ProjectNumber: p.ProjectNumber,
|
|
||||||
Team: p.Team,
|
|
||||||
}
|
|
||||||
}
|
|
1314
vendor/cloud.google.com/go/storage/bucket.go
generated
vendored
1314
vendor/cloud.google.com/go/storage/bucket.go
generated
vendored
File diff suppressed because it is too large
Load diff
238
vendor/cloud.google.com/go/storage/copy.go
generated
vendored
238
vendor/cloud.google.com/go/storage/copy.go
generated
vendored
|
@ -1,238 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CopierFrom creates a Copier that can copy src to dst.
|
|
||||||
// You can immediately call Run on the returned Copier, or
|
|
||||||
// you can configure it first.
|
|
||||||
//
|
|
||||||
// For Requester Pays buckets, the user project of dst is billed, unless it is empty,
|
|
||||||
// in which case the user project of src is billed.
|
|
||||||
func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier {
|
|
||||||
return &Copier{dst: dst, src: src}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Copier copies a source object to a destination.
|
|
||||||
type Copier struct {
|
|
||||||
// ObjectAttrs are optional attributes to set on the destination object.
|
|
||||||
// Any attributes must be initialized before any calls on the Copier. Nil
|
|
||||||
// or zero-valued attributes are ignored.
|
|
||||||
ObjectAttrs
|
|
||||||
|
|
||||||
// RewriteToken can be set before calling Run to resume a copy
|
|
||||||
// operation. After Run returns a non-nil error, RewriteToken will
|
|
||||||
// have been updated to contain the value needed to resume the copy.
|
|
||||||
RewriteToken string
|
|
||||||
|
|
||||||
// ProgressFunc can be used to monitor the progress of a multi-RPC copy
|
|
||||||
// operation. If ProgressFunc is not nil and copying requires multiple
|
|
||||||
// calls to the underlying service (see
|
|
||||||
// https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then
|
|
||||||
// ProgressFunc will be invoked after each call with the number of bytes of
|
|
||||||
// content copied so far and the total size in bytes of the source object.
|
|
||||||
//
|
|
||||||
// ProgressFunc is intended to make upload progress available to the
|
|
||||||
// application. For example, the implementation of ProgressFunc may update
|
|
||||||
// a progress bar in the application's UI, or log the result of
|
|
||||||
// float64(copiedBytes)/float64(totalBytes).
|
|
||||||
//
|
|
||||||
// ProgressFunc should return quickly without blocking.
|
|
||||||
ProgressFunc func(copiedBytes, totalBytes uint64)
|
|
||||||
|
|
||||||
// The Cloud KMS key, in the form projects/P/locations/L/keyRings/R/cryptoKeys/K,
|
|
||||||
// that will be used to encrypt the object. Overrides the object's KMSKeyName, if
|
|
||||||
// any.
|
|
||||||
//
|
|
||||||
// Providing both a DestinationKMSKeyName and a customer-supplied encryption key
|
|
||||||
// (via ObjectHandle.Key) on the destination object will result in an error when
|
|
||||||
// Run is called.
|
|
||||||
DestinationKMSKeyName string
|
|
||||||
|
|
||||||
dst, src *ObjectHandle
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run performs the copy.
|
|
||||||
func (c *Copier) Run(ctx context.Context) (attrs *ObjectAttrs, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Copier.Run")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if err := c.src.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := c.dst.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c.DestinationKMSKeyName != "" && c.dst.encryptionKey != nil {
|
|
||||||
return nil, errors.New("storage: cannot use DestinationKMSKeyName with a customer-supplied encryption key")
|
|
||||||
}
|
|
||||||
// Convert destination attributes to raw form, omitting the bucket.
|
|
||||||
// If the bucket is included but name or content-type aren't, the service
|
|
||||||
// returns a 400 with "Required" as the only message. Omitting the bucket
|
|
||||||
// does not cause any problems.
|
|
||||||
rawObject := c.ObjectAttrs.toRawObject("")
|
|
||||||
for {
|
|
||||||
res, err := c.callRewrite(ctx, rawObject)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c.ProgressFunc != nil {
|
|
||||||
c.ProgressFunc(uint64(res.TotalBytesRewritten), uint64(res.ObjectSize))
|
|
||||||
}
|
|
||||||
if res.Done { // Finished successfully.
|
|
||||||
return newObject(res.Resource), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Copier) callRewrite(ctx context.Context, rawObj *raw.Object) (*raw.RewriteResponse, error) {
|
|
||||||
call := c.dst.c.raw.Objects.Rewrite(c.src.bucket, c.src.object, c.dst.bucket, c.dst.object, rawObj)
|
|
||||||
|
|
||||||
call.Context(ctx).Projection("full")
|
|
||||||
if c.RewriteToken != "" {
|
|
||||||
call.RewriteToken(c.RewriteToken)
|
|
||||||
}
|
|
||||||
if c.DestinationKMSKeyName != "" {
|
|
||||||
call.DestinationKmsKeyName(c.DestinationKMSKeyName)
|
|
||||||
}
|
|
||||||
if c.PredefinedACL != "" {
|
|
||||||
call.DestinationPredefinedAcl(c.PredefinedACL)
|
|
||||||
}
|
|
||||||
if err := applyConds("Copy destination", c.dst.gen, c.dst.conds, call); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c.dst.userProject != "" {
|
|
||||||
call.UserProject(c.dst.userProject)
|
|
||||||
} else if c.src.userProject != "" {
|
|
||||||
call.UserProject(c.src.userProject)
|
|
||||||
}
|
|
||||||
if err := applySourceConds(c.src.gen, c.src.conds, call); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := setEncryptionHeaders(call.Header(), c.src.encryptionKey, true); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var res *raw.RewriteResponse
|
|
||||||
var err error
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
err = runWithRetry(ctx, func() error { res, err = call.Do(); return err })
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.RewriteToken = res.RewriteToken
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComposerFrom creates a Composer that can compose srcs into dst.
|
|
||||||
// You can immediately call Run on the returned Composer, or you can
|
|
||||||
// configure it first.
|
|
||||||
//
|
|
||||||
// The encryption key for the destination object will be used to decrypt all
|
|
||||||
// source objects and encrypt the destination object. It is an error
|
|
||||||
// to specify an encryption key for any of the source objects.
|
|
||||||
func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer {
|
|
||||||
return &Composer{dst: dst, srcs: srcs}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Composer composes source objects into a destination object.
|
|
||||||
//
|
|
||||||
// For Requester Pays buckets, the user project of dst is billed.
|
|
||||||
type Composer struct {
|
|
||||||
// ObjectAttrs are optional attributes to set on the destination object.
|
|
||||||
// Any attributes must be initialized before any calls on the Composer. Nil
|
|
||||||
// or zero-valued attributes are ignored.
|
|
||||||
ObjectAttrs
|
|
||||||
|
|
||||||
// SendCRC specifies whether to transmit a CRC32C field. It should be set
|
|
||||||
// to true in addition to setting the Composer's CRC32C field, because zero
|
|
||||||
// is a valid CRC and normally a zero would not be transmitted.
|
|
||||||
// If a CRC32C is sent, and the data in the destination object does not match
|
|
||||||
// the checksum, the compose will be rejected.
|
|
||||||
SendCRC32C bool
|
|
||||||
|
|
||||||
dst *ObjectHandle
|
|
||||||
srcs []*ObjectHandle
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run performs the compose operation.
|
|
||||||
func (c *Composer) Run(ctx context.Context) (attrs *ObjectAttrs, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Composer.Run")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if err := c.dst.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(c.srcs) == 0 {
|
|
||||||
return nil, errors.New("storage: at least one source object must be specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
req := &raw.ComposeRequest{}
|
|
||||||
// Compose requires a non-empty Destination, so we always set it,
|
|
||||||
// even if the caller-provided ObjectAttrs is the zero value.
|
|
||||||
req.Destination = c.ObjectAttrs.toRawObject(c.dst.bucket)
|
|
||||||
if c.SendCRC32C {
|
|
||||||
req.Destination.Crc32c = encodeUint32(c.ObjectAttrs.CRC32C)
|
|
||||||
}
|
|
||||||
for _, src := range c.srcs {
|
|
||||||
if err := src.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if src.bucket != c.dst.bucket {
|
|
||||||
return nil, fmt.Errorf("storage: all source objects must be in bucket %q, found %q", c.dst.bucket, src.bucket)
|
|
||||||
}
|
|
||||||
if src.encryptionKey != nil {
|
|
||||||
return nil, fmt.Errorf("storage: compose source %s.%s must not have encryption key", src.bucket, src.object)
|
|
||||||
}
|
|
||||||
srcObj := &raw.ComposeRequestSourceObjects{
|
|
||||||
Name: src.object,
|
|
||||||
}
|
|
||||||
if err := applyConds("ComposeFrom source", src.gen, src.conds, composeSourceObj{srcObj}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.SourceObjects = append(req.SourceObjects, srcObj)
|
|
||||||
}
|
|
||||||
|
|
||||||
call := c.dst.c.raw.Objects.Compose(c.dst.bucket, c.dst.object, req).Context(ctx)
|
|
||||||
if err := applyConds("ComposeFrom destination", c.dst.gen, c.dst.conds, call); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c.dst.userProject != "" {
|
|
||||||
call.UserProject(c.dst.userProject)
|
|
||||||
}
|
|
||||||
if c.PredefinedACL != "" {
|
|
||||||
call.DestinationPredefinedAcl(c.PredefinedACL)
|
|
||||||
}
|
|
||||||
if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var obj *raw.Object
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return newObject(obj), nil
|
|
||||||
}
|
|
231
vendor/cloud.google.com/go/storage/doc.go
generated
vendored
231
vendor/cloud.google.com/go/storage/doc.go
generated
vendored
|
@ -1,231 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package storage provides an easy way to work with Google Cloud Storage.
|
|
||||||
Google Cloud Storage stores data in named objects, which are grouped into buckets.
|
|
||||||
|
|
||||||
More information about Google Cloud Storage is available at
|
|
||||||
https://cloud.google.com/storage/docs.
|
|
||||||
|
|
||||||
See https://godoc.org/cloud.google.com/go for authentication, timeouts,
|
|
||||||
connection pooling and similar aspects of this package.
|
|
||||||
|
|
||||||
All of the methods of this package use exponential backoff to retry calls that fail
|
|
||||||
with certain errors, as described in
|
|
||||||
https://cloud.google.com/storage/docs/exponential-backoff. Retrying continues
|
|
||||||
indefinitely unless the controlling context is canceled or the client is closed. See
|
|
||||||
context.WithTimeout and context.WithCancel.
|
|
||||||
|
|
||||||
|
|
||||||
Creating a Client
|
|
||||||
|
|
||||||
To start working with this package, create a client:
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
client, err := storage.NewClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
The client will use your default application credentials. Clients should be
|
|
||||||
reused instead of created as needed. The methods of Client are safe for
|
|
||||||
concurrent use by multiple goroutines.
|
|
||||||
|
|
||||||
If you only wish to access public data, you can create
|
|
||||||
an unauthenticated client with
|
|
||||||
|
|
||||||
client, err := storage.NewClient(ctx, option.WithoutAuthentication())
|
|
||||||
|
|
||||||
Buckets
|
|
||||||
|
|
||||||
A Google Cloud Storage bucket is a collection of objects. To work with a
|
|
||||||
bucket, make a bucket handle:
|
|
||||||
|
|
||||||
bkt := client.Bucket(bucketName)
|
|
||||||
|
|
||||||
A handle is a reference to a bucket. You can have a handle even if the
|
|
||||||
bucket doesn't exist yet. To create a bucket in Google Cloud Storage,
|
|
||||||
call Create on the handle:
|
|
||||||
|
|
||||||
if err := bkt.Create(ctx, projectID, nil); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
Note that although buckets are associated with projects, bucket names are
|
|
||||||
global across all projects.
|
|
||||||
|
|
||||||
Each bucket has associated metadata, represented in this package by
|
|
||||||
BucketAttrs. The third argument to BucketHandle.Create allows you to set
|
|
||||||
the initial BucketAttrs of a bucket. To retrieve a bucket's attributes, use
|
|
||||||
Attrs:
|
|
||||||
|
|
||||||
attrs, err := bkt.Attrs(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n",
|
|
||||||
attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass)
|
|
||||||
|
|
||||||
Objects
|
|
||||||
|
|
||||||
An object holds arbitrary data as a sequence of bytes, like a file. You
|
|
||||||
refer to objects using a handle, just as with buckets, but unlike buckets
|
|
||||||
you don't explicitly create an object. Instead, the first time you write
|
|
||||||
to an object it will be created. You can use the standard Go io.Reader
|
|
||||||
and io.Writer interfaces to read and write object data:
|
|
||||||
|
|
||||||
obj := bkt.Object("data")
|
|
||||||
// Write something to obj.
|
|
||||||
// w implements io.Writer.
|
|
||||||
w := obj.NewWriter(ctx)
|
|
||||||
// Write some text to obj. This will either create the object or overwrite whatever is there already.
|
|
||||||
if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
// Close, just like writing a file.
|
|
||||||
if err := w.Close(); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read it back.
|
|
||||||
r, err := obj.NewReader(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
if _, err := io.Copy(os.Stdout, r); err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
// Prints "This object contains text."
|
|
||||||
|
|
||||||
Objects also have attributes, which you can fetch with Attrs:
|
|
||||||
|
|
||||||
objAttrs, err := obj.Attrs(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Printf("object %s has size %d and can be read using %s\n",
|
|
||||||
objAttrs.Name, objAttrs.Size, objAttrs.MediaLink)
|
|
||||||
|
|
||||||
Listing objects
|
|
||||||
|
|
||||||
Listing objects in a bucket is done with the Bucket.Objects method:
|
|
||||||
|
|
||||||
query := &storage.Query{Prefix: ""}
|
|
||||||
|
|
||||||
var names []string
|
|
||||||
it := bkt.Objects(ctx, query)
|
|
||||||
for {
|
|
||||||
attrs, err := it.Next()
|
|
||||||
if err == iterator.Done {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
names = append(names, attrs.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
Objects are listed lexicographically by name. To filter objects
|
|
||||||
lexicographically, Query.StartOffset and/or Query.EndOffset can be used:
|
|
||||||
|
|
||||||
query := &storage.Query{
|
|
||||||
Prefix: "",
|
|
||||||
StartOffset: "bar/", // Only list objects lexicographically >= "bar/"
|
|
||||||
EndOffset: "foo/", // Only list objects lexicographically < "foo/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... as before
|
|
||||||
|
|
||||||
If only a subset of object attributes is needed when listing, specifying this
|
|
||||||
subset using Query.SetAttrSelection may speed up the listing process:
|
|
||||||
|
|
||||||
query := &storage.Query{Prefix: ""}
|
|
||||||
query.SetAttrSelection([]string{"Name"})
|
|
||||||
|
|
||||||
// ... as before
|
|
||||||
|
|
||||||
ACLs
|
|
||||||
|
|
||||||
Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of
|
|
||||||
ACLRules, each of which specifies the role of a user, group or project. ACLs
|
|
||||||
are suitable for fine-grained control, but you may prefer using IAM to control
|
|
||||||
access at the project level (see
|
|
||||||
https://cloud.google.com/storage/docs/access-control/iam).
|
|
||||||
|
|
||||||
To list the ACLs of a bucket or object, obtain an ACLHandle and call its List method:
|
|
||||||
|
|
||||||
acls, err := obj.ACL().List(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
for _, rule := range acls {
|
|
||||||
fmt.Printf("%s has role %s\n", rule.Entity, rule.Role)
|
|
||||||
}
|
|
||||||
|
|
||||||
You can also set and delete ACLs.
|
|
||||||
|
|
||||||
Conditions
|
|
||||||
|
|
||||||
Every object has a generation and a metageneration. The generation changes
|
|
||||||
whenever the content changes, and the metageneration changes whenever the
|
|
||||||
metadata changes. Conditions let you check these values before an operation;
|
|
||||||
the operation only executes if the conditions match. You can use conditions to
|
|
||||||
prevent race conditions in read-modify-write operations.
|
|
||||||
|
|
||||||
For example, say you've read an object's metadata into objAttrs. Now
|
|
||||||
you want to write to that object, but only if its contents haven't changed
|
|
||||||
since you read it. Here is how to express that:
|
|
||||||
|
|
||||||
w = obj.If(storage.Conditions{GenerationMatch: objAttrs.Generation}).NewWriter(ctx)
|
|
||||||
// Proceed with writing as above.
|
|
||||||
|
|
||||||
Signed URLs
|
|
||||||
|
|
||||||
You can obtain a URL that lets anyone read or write an object for a limited time.
|
|
||||||
You don't need to create a client to do this. See the documentation of
|
|
||||||
SignedURL for details.
|
|
||||||
|
|
||||||
url, err := storage.SignedURL(bucketName, "shared-object", opts)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Println(url)
|
|
||||||
|
|
||||||
Post Policy V4 Signed Request
|
|
||||||
|
|
||||||
A type of signed request that allows uploads through HTML forms directly to Cloud Storage with
|
|
||||||
temporary permission. Conditions can be applied to restrict how the HTML form is used and exercised
|
|
||||||
by a user.
|
|
||||||
|
|
||||||
For more information, please see https://cloud.google.com/storage/docs/xml-api/post-object as well
|
|
||||||
as the documentation of GenerateSignedPostPolicyV4.
|
|
||||||
|
|
||||||
pv4, err := storage.GenerateSignedPostPolicyV4(bucketName, objectName, opts)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: Handle error.
|
|
||||||
}
|
|
||||||
fmt.Printf("URL: %s\nFields; %v\n", pv4.URL, pv4.Fields)
|
|
||||||
|
|
||||||
Errors
|
|
||||||
|
|
||||||
Errors returned by this client are often of the type [`googleapi.Error`](https://godoc.org/google.golang.org/api/googleapi#Error).
|
|
||||||
These errors can be introspected for more information by type asserting to the richer `googleapi.Error` type. For example:
|
|
||||||
|
|
||||||
if e, ok := err.(*googleapi.Error); ok {
|
|
||||||
if e.Code == 409 { ... }
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
package storage // import "cloud.google.com/go/storage"
|
|
15
vendor/cloud.google.com/go/storage/go.mod
generated
vendored
15
vendor/cloud.google.com/go/storage/go.mod
generated
vendored
|
@ -1,15 +0,0 @@
|
||||||
module cloud.google.com/go/storage
|
|
||||||
|
|
||||||
go 1.11
|
|
||||||
|
|
||||||
require (
|
|
||||||
cloud.google.com/go v0.66.0
|
|
||||||
github.com/golang/protobuf v1.4.2
|
|
||||||
github.com/google/go-cmp v0.5.2
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
|
|
||||||
golang.org/x/tools v0.0.0-20200918232735-d647fc253266 // indirect
|
|
||||||
google.golang.org/api v0.32.0
|
|
||||||
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5
|
|
||||||
google.golang.org/grpc v1.32.0
|
|
||||||
)
|
|
517
vendor/cloud.google.com/go/storage/go.sum
generated
vendored
517
vendor/cloud.google.com/go/storage/go.sum
generated
vendored
|
@ -1,517 +0,0 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0 h1:GGslhk/BU052LPlnI1vpp3fcbUs+hQ3E+Doti/3/vF8=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0 h1:MZQCQQaRwOrAcuKjiHWHrgKykt4fZyuwF2dtiG3fGW8=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms=
|
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
|
||||||
cloud.google.com/go v0.62.0 h1:RmDygqvj27Zf3fCQjQRtLyC7KwFcHkeJitcO0OoGOcA=
|
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
|
||||||
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
|
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
cloud.google.com/go v0.66.0 h1:DZeAkuQGQqnm9Xv36SbMJEU8aFBz4wL04UpMWPWwjzg=
|
|
||||||
cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0 h1:K2NyuHRuv15ku6eUpe0DQk5ZykPMnSOnvuVf6IHcjaE=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0 h1:a/O/bK/vWrYGOTFtH8di4rBxMZnmkjy+Y5LxpDwo+dA=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0 h1:9/vpR43S4aJaROxqQHQ3nH9lfyKKV0dC3vOmnw8ebQQ=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
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-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
|
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
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.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
|
||||||
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|
||||||
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|
||||||
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299 h1:zQpM52jfKHG6II1ISZY1ZcpygvuSFZpLwfluuF89XOg=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a h1:7Wlg8L54In96HTWOaI4sreLJ6qfyGuvSau5el3fK41Y=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd h1:zkO/Lhoka23X63N9OSzpSeROEUQ5ODw47tM3YWjygbs=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
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-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
|
||||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/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-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-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
|
||||||
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/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
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.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c h1:2EA2K0k9bcvvEDlqD8xdlOhCOqq+O/p9Voqi4x9W1YU=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a h1:7YaEqUc1tUg0yDwvdX+3U5bwrBg7u3FFAZ5D8gUs4/c=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZA7zsDKtFXPNcm7/eI5ZA=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56 h1:DFtSed2q3HtNuVazwVDZ4nSRS/JrZEig0gz2BY4VNrg=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d h1:7M9AXzLrJWWGdDYtBblPHBTnHtaN6KKQ98OYb35mLlY=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb h1:iKlO7ROJc6SttHKlxzwGytRtBUqX4VARrNTgP2YLX5M=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d h1:3K34ovZAOnVaUPxanr0j4ghTZTPTA0CnXvjCl+5lZqk=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4 h1:kDtqNkeBrZb8B+atrj50B5XLHpzXXqcCdZPP/ApQ5NY=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d h1:lzLdP95xJmMpwQ6LUHwrc5V7js93hTiY7gkznu0BgmY=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d h1:szSOL78iTCl0LF1AMjhSWJj8tIM0KixlUUnBtYXsmd8=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
|
||||||
golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
|
||||||
golang.org/x/tools v0.0.0-20200918232735-d647fc253266 h1:k7tVuG0g1JwmD3Jh8oAl1vQ1C3jb4Hi/dUl1wWDBJpQ=
|
|
||||||
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0 h1:0q95w+VuFtv4PAx4PZVQdBMmYbaCHbnfKaEiDIcVyag=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0 h1:GwFK8+l5/gdsOYKz5p6M4UK+QT8OvmHWZPJCnf+5DjA=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0 h1:jMF5hhVfMkTZwHW1SDpKq5CkgWLXOb31Foaca9Zr3oM=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
|
|
||||||
google.golang.org/api v0.32.0 h1:Le77IccnTqEa8ryp9wIpX5W3zYm7Gf9LhOp9PHcwFts=
|
|
||||||
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba h1:pRj9OXZbwNtbtZtOB4dLwfK4u+EVRMvP+e9zKkg2grM=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150 h1:VPpdpQkGvFicX9yo4G5oxZPi9ALBnEOZblPSa/Wa2m4=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90 h1:7THRSvPuzF1bql5kyFzX0JM0vpGhwuhskgJrJsbZ80Y=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce h1:1mbrb1tUU+Zmt5C94IGKADBTJZjZXAd+BubWi7r9EiI=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383 h1:Vo0fD5w0fUKriWlZLyrim2GXbumyN0D6euW79T9PgEE=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171 h1:xes2Q2k+d/+YNXVw0FpZkIDJiaux4OVrRKXRAzH6A0U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672 h1:jiDSspVssiikoRPFHT6pYrL+CL6/yIc3b9AuHO/4xik=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940 h1:MRHtG0U6SnaUb+s+LhNE1qt1FQ1wlhqr5E4usBKC0uA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84 h1:pSLkPbrjnPyLDYUO2VM9mDLqo2V6CFBY84lFSZAfoi4=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c h1:Lq4llNryJoaVFRmvrIwC/ZHH7tNt4tUYIu8+se2aayY=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5 h1:B9nroC8SSX5GtbVvxPF9tYIVkaCpjhVLOrlAY8ONzm8=
|
|
||||||
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
|
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
|
|
||||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.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.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=
|
|
||||||
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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
48
vendor/cloud.google.com/go/storage/go110.go
generated
vendored
48
vendor/cloud.google.com/go/storage/go110.go
generated
vendored
|
@ -1,48 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// +build go1.10
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
)
|
|
||||||
|
|
||||||
func shouldRetry(err error) bool {
|
|
||||||
switch e := err.(type) {
|
|
||||||
case *googleapi.Error:
|
|
||||||
// Retry on 429 and 5xx, according to
|
|
||||||
// https://cloud.google.com/storage/docs/exponential-backoff.
|
|
||||||
return e.Code == 429 || (e.Code >= 500 && e.Code < 600)
|
|
||||||
case *url.Error:
|
|
||||||
// Retry socket-level errors ECONNREFUSED and ENETUNREACH (from syscall).
|
|
||||||
// Unfortunately the error type is unexported, so we resort to string
|
|
||||||
// matching.
|
|
||||||
retriable := []string{"connection refused", "connection reset"}
|
|
||||||
for _, s := range retriable {
|
|
||||||
if strings.Contains(e.Error(), s) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
case interface{ Temporary() bool }:
|
|
||||||
return e.Temporary()
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
22
vendor/cloud.google.com/go/storage/go_mod_tidy_hack.go
generated
vendored
22
vendor/cloud.google.com/go/storage/go_mod_tidy_hack.go
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
// Copyright 2019 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// This file, and the cloud.google.com/go import, won't actually become part of
|
|
||||||
// the resultant binary.
|
|
||||||
// +build modhack
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
// Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
|
||||||
import _ "cloud.google.com/go"
|
|
441
vendor/cloud.google.com/go/storage/hmac.go
generated
vendored
441
vendor/cloud.google.com/go/storage/hmac.go
generated
vendored
|
@ -1,441 +0,0 @@
|
||||||
// Copyright 2019 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"google.golang.org/api/iterator"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HMACState is the state of the HMAC key.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACState string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Active is the status for an active key that can be used to sign
|
|
||||||
// requests.
|
|
||||||
Active HMACState = "ACTIVE"
|
|
||||||
|
|
||||||
// Inactive is the status for an inactive key thus requests signed by
|
|
||||||
// this key will be denied.
|
|
||||||
Inactive HMACState = "INACTIVE"
|
|
||||||
|
|
||||||
// Deleted is the status for a key that is deleted.
|
|
||||||
// Once in this state the key cannot key cannot be recovered
|
|
||||||
// and does not count towards key limits. Deleted keys will be cleaned
|
|
||||||
// up later.
|
|
||||||
Deleted HMACState = "DELETED"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HMACKey is the representation of a Google Cloud Storage HMAC key.
|
|
||||||
//
|
|
||||||
// HMAC keys are used to authenticate signed access to objects. To enable HMAC key
|
|
||||||
// authentication, please visit https://cloud.google.com/storage/docs/migrating.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKey struct {
|
|
||||||
// The HMAC's secret key.
|
|
||||||
Secret string
|
|
||||||
|
|
||||||
// AccessID is the ID of the HMAC key.
|
|
||||||
AccessID string
|
|
||||||
|
|
||||||
// Etag is the HTTP/1.1 Entity tag.
|
|
||||||
Etag string
|
|
||||||
|
|
||||||
// ID is the ID of the HMAC key, including the ProjectID and AccessID.
|
|
||||||
ID string
|
|
||||||
|
|
||||||
// ProjectID is the ID of the project that owns the
|
|
||||||
// service account to which the key authenticates.
|
|
||||||
ProjectID string
|
|
||||||
|
|
||||||
// ServiceAccountEmail is the email address
|
|
||||||
// of the key's associated service account.
|
|
||||||
ServiceAccountEmail string
|
|
||||||
|
|
||||||
// CreatedTime is the creation time of the HMAC key.
|
|
||||||
CreatedTime time.Time
|
|
||||||
|
|
||||||
// UpdatedTime is the last modification time of the HMAC key metadata.
|
|
||||||
UpdatedTime time.Time
|
|
||||||
|
|
||||||
// State is the state of the HMAC key.
|
|
||||||
// It can be one of StateActive, StateInactive or StateDeleted.
|
|
||||||
State HMACState
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyHandle helps provide access and management for HMAC keys.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeyHandle struct {
|
|
||||||
projectID string
|
|
||||||
accessID string
|
|
||||||
|
|
||||||
raw *raw.ProjectsHmacKeysService
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyHandle creates a handle that will be used for HMACKey operations.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (c *Client) HMACKeyHandle(projectID, accessID string) *HMACKeyHandle {
|
|
||||||
return &HMACKeyHandle{
|
|
||||||
projectID: projectID,
|
|
||||||
accessID: accessID,
|
|
||||||
raw: raw.NewProjectsHmacKeysService(c.raw),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get invokes an RPC to retrieve the HMAC key referenced by the
|
|
||||||
// HMACKeyHandle's accessID.
|
|
||||||
//
|
|
||||||
// Options such as UserProjectForHMACKeys can be used to set the
|
|
||||||
// userProject to be billed against for operations.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (hkh *HMACKeyHandle) Get(ctx context.Context, opts ...HMACKeyOption) (*HMACKey, error) {
|
|
||||||
call := hkh.raw.Get(hkh.projectID, hkh.accessID)
|
|
||||||
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
if desc.userProjectID != "" {
|
|
||||||
call = call.UserProject(desc.userProjectID)
|
|
||||||
}
|
|
||||||
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
|
|
||||||
var metadata *raw.HmacKeyMetadata
|
|
||||||
var err error
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
metadata, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hkPb := &raw.HmacKey{
|
|
||||||
Metadata: metadata,
|
|
||||||
}
|
|
||||||
return pbHmacKeyToHMACKey(hkPb, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete invokes an RPC to delete the key referenced by accessID, on Google Cloud Storage.
|
|
||||||
// Only inactive HMAC keys can be deleted.
|
|
||||||
// After deletion, a key cannot be used to authenticate requests.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (hkh *HMACKeyHandle) Delete(ctx context.Context, opts ...HMACKeyOption) error {
|
|
||||||
delCall := hkh.raw.Delete(hkh.projectID, hkh.accessID)
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
if desc.userProjectID != "" {
|
|
||||||
delCall = delCall.UserProject(desc.userProjectID)
|
|
||||||
}
|
|
||||||
setClientHeader(delCall.Header())
|
|
||||||
|
|
||||||
return runWithRetry(ctx, func() error {
|
|
||||||
return delCall.Context(ctx).Do()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func pbHmacKeyToHMACKey(pb *raw.HmacKey, updatedTimeCanBeNil bool) (*HMACKey, error) {
|
|
||||||
pbmd := pb.Metadata
|
|
||||||
if pbmd == nil {
|
|
||||||
return nil, errors.New("field Metadata cannot be nil")
|
|
||||||
}
|
|
||||||
createdTime, err := time.Parse(time.RFC3339, pbmd.TimeCreated)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("field CreatedTime: %v", err)
|
|
||||||
}
|
|
||||||
updatedTime, err := time.Parse(time.RFC3339, pbmd.Updated)
|
|
||||||
if err != nil && !updatedTimeCanBeNil {
|
|
||||||
return nil, fmt.Errorf("field UpdatedTime: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hmk := &HMACKey{
|
|
||||||
AccessID: pbmd.AccessId,
|
|
||||||
Secret: pb.Secret,
|
|
||||||
Etag: pbmd.Etag,
|
|
||||||
ID: pbmd.Id,
|
|
||||||
State: HMACState(pbmd.State),
|
|
||||||
ProjectID: pbmd.ProjectId,
|
|
||||||
CreatedTime: createdTime,
|
|
||||||
UpdatedTime: updatedTime,
|
|
||||||
|
|
||||||
ServiceAccountEmail: pbmd.ServiceAccountEmail,
|
|
||||||
}
|
|
||||||
|
|
||||||
return hmk, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateHMACKey invokes an RPC for Google Cloud Storage to create a new HMACKey.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (c *Client) CreateHMACKey(ctx context.Context, projectID, serviceAccountEmail string, opts ...HMACKeyOption) (*HMACKey, error) {
|
|
||||||
if projectID == "" {
|
|
||||||
return nil, errors.New("storage: expecting a non-blank projectID")
|
|
||||||
}
|
|
||||||
if serviceAccountEmail == "" {
|
|
||||||
return nil, errors.New("storage: expecting a non-blank service account email")
|
|
||||||
}
|
|
||||||
|
|
||||||
svc := raw.NewProjectsHmacKeysService(c.raw)
|
|
||||||
call := svc.Create(projectID, serviceAccountEmail)
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
if desc.userProjectID != "" {
|
|
||||||
call = call.UserProject(desc.userProjectID)
|
|
||||||
}
|
|
||||||
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
|
|
||||||
var hkPb *raw.HmacKey
|
|
||||||
var err error
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
hkPb, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pbHmacKeyToHMACKey(hkPb, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyAttrsToUpdate defines the attributes of an HMACKey that will be updated.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeyAttrsToUpdate struct {
|
|
||||||
// State is required and must be either StateActive or StateInactive.
|
|
||||||
State HMACState
|
|
||||||
|
|
||||||
// Etag is an optional field and it is the HTTP/1.1 Entity tag.
|
|
||||||
Etag string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update mutates the HMACKey referred to by accessID.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (h *HMACKeyHandle) Update(ctx context.Context, au HMACKeyAttrsToUpdate, opts ...HMACKeyOption) (*HMACKey, error) {
|
|
||||||
if au.State != Active && au.State != Inactive {
|
|
||||||
return nil, fmt.Errorf("storage: invalid state %q for update, must be either %q or %q", au.State, Active, Inactive)
|
|
||||||
}
|
|
||||||
|
|
||||||
call := h.raw.Update(h.projectID, h.accessID, &raw.HmacKeyMetadata{
|
|
||||||
Etag: au.Etag,
|
|
||||||
State: string(au.State),
|
|
||||||
})
|
|
||||||
|
|
||||||
desc := new(hmacKeyDesc)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(desc)
|
|
||||||
}
|
|
||||||
if desc.userProjectID != "" {
|
|
||||||
call = call.UserProject(desc.userProjectID)
|
|
||||||
}
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
|
|
||||||
var metadata *raw.HmacKeyMetadata
|
|
||||||
var err error
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
metadata, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hkPb := &raw.HmacKey{
|
|
||||||
Metadata: metadata,
|
|
||||||
}
|
|
||||||
return pbHmacKeyToHMACKey(hkPb, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// An HMACKeysIterator is an iterator over HMACKeys.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This type is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeysIterator struct {
|
|
||||||
ctx context.Context
|
|
||||||
raw *raw.ProjectsHmacKeysService
|
|
||||||
projectID string
|
|
||||||
hmacKeys []*HMACKey
|
|
||||||
pageInfo *iterator.PageInfo
|
|
||||||
nextFunc func() error
|
|
||||||
index int
|
|
||||||
desc hmacKeyDesc
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListHMACKeys returns an iterator for listing HMACKeys.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (c *Client) ListHMACKeys(ctx context.Context, projectID string, opts ...HMACKeyOption) *HMACKeysIterator {
|
|
||||||
it := &HMACKeysIterator{
|
|
||||||
ctx: ctx,
|
|
||||||
raw: raw.NewProjectsHmacKeysService(c.raw),
|
|
||||||
projectID: projectID,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt.withHMACKeyDesc(&it.desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
it.pageInfo, it.nextFunc = iterator.NewPageInfo(
|
|
||||||
it.fetch,
|
|
||||||
func() int { return len(it.hmacKeys) - it.index },
|
|
||||||
func() interface{} {
|
|
||||||
prev := it.hmacKeys
|
|
||||||
it.hmacKeys = it.hmacKeys[:0]
|
|
||||||
it.index = 0
|
|
||||||
return prev
|
|
||||||
})
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next returns the next result. Its second return value is iterator.Done if
|
|
||||||
// there are no more results. Once Next returns iterator.Done, all subsequent
|
|
||||||
// calls will return iterator.Done.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (it *HMACKeysIterator) Next() (*HMACKey, error) {
|
|
||||||
if err := it.nextFunc(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := it.hmacKeys[it.index]
|
|
||||||
it.index++
|
|
||||||
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
|
|
||||||
//
|
|
||||||
// Note: This iterator is not safe for concurrent operations without explicit synchronization.
|
|
||||||
//
|
|
||||||
// This method is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func (it *HMACKeysIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }
|
|
||||||
|
|
||||||
func (it *HMACKeysIterator) fetch(pageSize int, pageToken string) (token string, err error) {
|
|
||||||
call := it.raw.List(it.projectID)
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if pageToken != "" {
|
|
||||||
call = call.PageToken(pageToken)
|
|
||||||
}
|
|
||||||
if it.desc.showDeletedKeys {
|
|
||||||
call = call.ShowDeletedKeys(true)
|
|
||||||
}
|
|
||||||
if it.desc.userProjectID != "" {
|
|
||||||
call = call.UserProject(it.desc.userProjectID)
|
|
||||||
}
|
|
||||||
if it.desc.forServiceAccountEmail != "" {
|
|
||||||
call = call.ServiceAccountEmail(it.desc.forServiceAccountEmail)
|
|
||||||
}
|
|
||||||
if pageSize > 0 {
|
|
||||||
call = call.MaxResults(int64(pageSize))
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := it.ctx
|
|
||||||
var resp *raw.HmacKeysMetadata
|
|
||||||
err = runWithRetry(it.ctx, func() error {
|
|
||||||
resp, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, metadata := range resp.Items {
|
|
||||||
hkPb := &raw.HmacKey{
|
|
||||||
Metadata: metadata,
|
|
||||||
}
|
|
||||||
hkey, err := pbHmacKeyToHMACKey(hkPb, true)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
it.hmacKeys = append(it.hmacKeys, hkey)
|
|
||||||
}
|
|
||||||
return resp.NextPageToken, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type hmacKeyDesc struct {
|
|
||||||
forServiceAccountEmail string
|
|
||||||
showDeletedKeys bool
|
|
||||||
userProjectID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// HMACKeyOption configures the behavior of HMACKey related methods and actions.
|
|
||||||
//
|
|
||||||
// This interface is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
type HMACKeyOption interface {
|
|
||||||
withHMACKeyDesc(*hmacKeyDesc)
|
|
||||||
}
|
|
||||||
|
|
||||||
type hmacKeyDescFunc func(*hmacKeyDesc)
|
|
||||||
|
|
||||||
func (hkdf hmacKeyDescFunc) withHMACKeyDesc(hkd *hmacKeyDesc) {
|
|
||||||
hkdf(hkd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForHMACKeyServiceAccountEmail returns HMAC Keys that are
|
|
||||||
// associated with the email address of a service account in the project.
|
|
||||||
//
|
|
||||||
// Only one service account email can be used as a filter, so if multiple
|
|
||||||
// of these options are applied, the last email to be set will be used.
|
|
||||||
//
|
|
||||||
// This option is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func ForHMACKeyServiceAccountEmail(serviceAccountEmail string) HMACKeyOption {
|
|
||||||
return hmacKeyDescFunc(func(hkd *hmacKeyDesc) {
|
|
||||||
hkd.forServiceAccountEmail = serviceAccountEmail
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowDeletedHMACKeys will also list keys whose state is "DELETED".
|
|
||||||
//
|
|
||||||
// This option is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func ShowDeletedHMACKeys() HMACKeyOption {
|
|
||||||
return hmacKeyDescFunc(func(hkd *hmacKeyDesc) {
|
|
||||||
hkd.showDeletedKeys = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserProjectForHMACKeys will bill the request against userProjectID
|
|
||||||
// if userProjectID is non-empty.
|
|
||||||
//
|
|
||||||
// Note: This is a noop right now and only provided for API compatibility.
|
|
||||||
//
|
|
||||||
// This option is EXPERIMENTAL and subject to change or removal without notice.
|
|
||||||
func UserProjectForHMACKeys(userProjectID string) HMACKeyOption {
|
|
||||||
return hmacKeyDescFunc(func(hkd *hmacKeyDesc) {
|
|
||||||
hkd.userProjectID = userProjectID
|
|
||||||
})
|
|
||||||
}
|
|
162
vendor/cloud.google.com/go/storage/iam.go
generated
vendored
162
vendor/cloud.google.com/go/storage/iam.go
generated
vendored
|
@ -1,162 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"cloud.google.com/go/iam"
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
iampb "google.golang.org/genproto/googleapis/iam/v1"
|
|
||||||
"google.golang.org/genproto/googleapis/type/expr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IAM provides access to IAM access control for the bucket.
|
|
||||||
func (b *BucketHandle) IAM() *iam.Handle {
|
|
||||||
return iam.InternalNewHandleClient(&iamClient{
|
|
||||||
raw: b.c.raw,
|
|
||||||
userProject: b.userProject,
|
|
||||||
}, b.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// iamClient implements the iam.client interface.
|
|
||||||
type iamClient struct {
|
|
||||||
raw *raw.Service
|
|
||||||
userProject string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) Get(ctx context.Context, resource string) (p *iampb.Policy, err error) {
|
|
||||||
return c.GetWithVersion(ctx, resource, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (p *iampb.Policy, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Get")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
call := c.raw.Buckets.GetIamPolicy(resource).OptionsRequestedPolicyVersion(int64(requestedPolicyVersion))
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if c.userProject != "" {
|
|
||||||
call.UserProject(c.userProject)
|
|
||||||
}
|
|
||||||
var rp *raw.Policy
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
rp, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return iamFromStoragePolicy(rp), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Set")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
rp := iamToStoragePolicy(p)
|
|
||||||
call := c.raw.Buckets.SetIamPolicy(resource, rp)
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if c.userProject != "" {
|
|
||||||
call.UserProject(c.userProject)
|
|
||||||
}
|
|
||||||
return runWithRetry(ctx, func() error {
|
|
||||||
_, err := call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *iamClient) Test(ctx context.Context, resource string, perms []string) (permissions []string, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Test")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
call := c.raw.Buckets.TestIamPermissions(resource, perms)
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if c.userProject != "" {
|
|
||||||
call.UserProject(c.userProject)
|
|
||||||
}
|
|
||||||
var res *raw.TestIamPermissionsResponse
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
res, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return res.Permissions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy {
|
|
||||||
return &raw.Policy{
|
|
||||||
Bindings: iamToStorageBindings(ip.Bindings),
|
|
||||||
Etag: string(ip.Etag),
|
|
||||||
Version: int64(ip.Version),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings {
|
|
||||||
var rbs []*raw.PolicyBindings
|
|
||||||
for _, ib := range ibs {
|
|
||||||
rbs = append(rbs, &raw.PolicyBindings{
|
|
||||||
Role: ib.Role,
|
|
||||||
Members: ib.Members,
|
|
||||||
Condition: iamToStorageCondition(ib.Condition),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return rbs
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamToStorageCondition(exprpb *expr.Expr) *raw.Expr {
|
|
||||||
if exprpb == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &raw.Expr{
|
|
||||||
Expression: exprpb.Expression,
|
|
||||||
Description: exprpb.Description,
|
|
||||||
Location: exprpb.Location,
|
|
||||||
Title: exprpb.Title,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy {
|
|
||||||
return &iampb.Policy{
|
|
||||||
Bindings: iamFromStorageBindings(rp.Bindings),
|
|
||||||
Etag: []byte(rp.Etag),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding {
|
|
||||||
var ibs []*iampb.Binding
|
|
||||||
for _, rb := range rbs {
|
|
||||||
ibs = append(ibs, &iampb.Binding{
|
|
||||||
Role: rb.Role,
|
|
||||||
Members: rb.Members,
|
|
||||||
Condition: iamFromStorageCondition(rb.Condition),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return ibs
|
|
||||||
}
|
|
||||||
|
|
||||||
func iamFromStorageCondition(rawexpr *raw.Expr) *expr.Expr {
|
|
||||||
if rawexpr == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &expr.Expr{
|
|
||||||
Expression: rawexpr.Expression,
|
|
||||||
Description: rawexpr.Description,
|
|
||||||
Location: rawexpr.Location,
|
|
||||||
Title: rawexpr.Title,
|
|
||||||
}
|
|
||||||
}
|
|
37
vendor/cloud.google.com/go/storage/invoke.go
generated
vendored
37
vendor/cloud.google.com/go/storage/invoke.go
generated
vendored
|
@ -1,37 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal"
|
|
||||||
gax "github.com/googleapis/gax-go/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// runWithRetry calls the function until it returns nil or a non-retryable error, or
|
|
||||||
// the context is done.
|
|
||||||
func runWithRetry(ctx context.Context, call func() error) error {
|
|
||||||
return internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) {
|
|
||||||
err = call()
|
|
||||||
if err == nil {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
if shouldRetry(err) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, err
|
|
||||||
})
|
|
||||||
}
|
|
42
vendor/cloud.google.com/go/storage/not_go110.go
generated
vendored
42
vendor/cloud.google.com/go/storage/not_go110.go
generated
vendored
|
@ -1,42 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// +build !go1.10
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
)
|
|
||||||
|
|
||||||
func shouldRetry(err error) bool {
|
|
||||||
switch e := err.(type) {
|
|
||||||
case *googleapi.Error:
|
|
||||||
// Retry on 429 and 5xx, according to
|
|
||||||
// https://cloud.google.com/storage/docs/exponential-backoff.
|
|
||||||
return e.Code == 429 || (e.Code >= 500 && e.Code < 600)
|
|
||||||
case *url.Error:
|
|
||||||
// Retry on REFUSED_STREAM.
|
|
||||||
// Unfortunately the error type is unexported, so we resort to string
|
|
||||||
// matching.
|
|
||||||
return strings.Contains(e.Error(), "REFUSED_STREAM")
|
|
||||||
case interface{ Temporary() bool }:
|
|
||||||
return e.Temporary()
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
188
vendor/cloud.google.com/go/storage/notifications.go
generated
vendored
188
vendor/cloud.google.com/go/storage/notifications.go
generated
vendored
|
@ -1,188 +0,0 @@
|
||||||
// Copyright 2017 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Notification describes how to send Cloud PubSub messages when certain
|
|
||||||
// events occur in a bucket.
|
|
||||||
type Notification struct {
|
|
||||||
//The ID of the notification.
|
|
||||||
ID string
|
|
||||||
|
|
||||||
// The ID of the topic to which this subscription publishes.
|
|
||||||
TopicID string
|
|
||||||
|
|
||||||
// The ID of the project to which the topic belongs.
|
|
||||||
TopicProjectID string
|
|
||||||
|
|
||||||
// Only send notifications about listed event types. If empty, send notifications
|
|
||||||
// for all event types.
|
|
||||||
// See https://cloud.google.com/storage/docs/pubsub-notifications#events.
|
|
||||||
EventTypes []string
|
|
||||||
|
|
||||||
// If present, only apply this notification configuration to object names that
|
|
||||||
// begin with this prefix.
|
|
||||||
ObjectNamePrefix string
|
|
||||||
|
|
||||||
// An optional list of additional attributes to attach to each Cloud PubSub
|
|
||||||
// message published for this notification subscription.
|
|
||||||
CustomAttributes map[string]string
|
|
||||||
|
|
||||||
// The contents of the message payload.
|
|
||||||
// See https://cloud.google.com/storage/docs/pubsub-notifications#payload.
|
|
||||||
PayloadFormat string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Values for Notification.PayloadFormat.
|
|
||||||
const (
|
|
||||||
// Send no payload with notification messages.
|
|
||||||
NoPayload = "NONE"
|
|
||||||
|
|
||||||
// Send object metadata as JSON with notification messages.
|
|
||||||
JSONPayload = "JSON_API_V1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Values for Notification.EventTypes.
|
|
||||||
const (
|
|
||||||
// Event that occurs when an object is successfully created.
|
|
||||||
ObjectFinalizeEvent = "OBJECT_FINALIZE"
|
|
||||||
|
|
||||||
// Event that occurs when the metadata of an existing object changes.
|
|
||||||
ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
|
|
||||||
|
|
||||||
// Event that occurs when an object is permanently deleted.
|
|
||||||
ObjectDeleteEvent = "OBJECT_DELETE"
|
|
||||||
|
|
||||||
// Event that occurs when the live version of an object becomes an
|
|
||||||
// archived version.
|
|
||||||
ObjectArchiveEvent = "OBJECT_ARCHIVE"
|
|
||||||
)
|
|
||||||
|
|
||||||
func toNotification(rn *raw.Notification) *Notification {
|
|
||||||
n := &Notification{
|
|
||||||
ID: rn.Id,
|
|
||||||
EventTypes: rn.EventTypes,
|
|
||||||
ObjectNamePrefix: rn.ObjectNamePrefix,
|
|
||||||
CustomAttributes: rn.CustomAttributes,
|
|
||||||
PayloadFormat: rn.PayloadFormat,
|
|
||||||
}
|
|
||||||
n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)")
|
|
||||||
|
|
||||||
// parseNotificationTopic extracts the project and topic IDs from from the full
|
|
||||||
// resource name returned by the service. If the name is malformed, it returns
|
|
||||||
// "?" for both IDs.
|
|
||||||
func parseNotificationTopic(nt string) (projectID, topicID string) {
|
|
||||||
matches := topicRE.FindStringSubmatch(nt)
|
|
||||||
if matches == nil {
|
|
||||||
return "?", "?"
|
|
||||||
}
|
|
||||||
return matches[1], matches[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
func toRawNotification(n *Notification) *raw.Notification {
|
|
||||||
return &raw.Notification{
|
|
||||||
Id: n.ID,
|
|
||||||
Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
|
|
||||||
n.TopicProjectID, n.TopicID),
|
|
||||||
EventTypes: n.EventTypes,
|
|
||||||
ObjectNamePrefix: n.ObjectNamePrefix,
|
|
||||||
CustomAttributes: n.CustomAttributes,
|
|
||||||
PayloadFormat: string(n.PayloadFormat),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID
|
|
||||||
// and PayloadFormat, and must not set its ID. The other fields are all optional. The
|
|
||||||
// returned Notification's ID can be used to refer to it.
|
|
||||||
func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (ret *Notification, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.AddNotification")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if n.ID != "" {
|
|
||||||
return nil, errors.New("storage: AddNotification: ID must not be set")
|
|
||||||
}
|
|
||||||
if n.TopicProjectID == "" {
|
|
||||||
return nil, errors.New("storage: AddNotification: missing TopicProjectID")
|
|
||||||
}
|
|
||||||
if n.TopicID == "" {
|
|
||||||
return nil, errors.New("storage: AddNotification: missing TopicID")
|
|
||||||
}
|
|
||||||
call := b.c.raw.Notifications.Insert(b.name, toRawNotification(n))
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if b.userProject != "" {
|
|
||||||
call.UserProject(b.userProject)
|
|
||||||
}
|
|
||||||
rn, err := call.Context(ctx).Do()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return toNotification(rn), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notifications returns all the Notifications configured for this bucket, as a map
|
|
||||||
// indexed by notification ID.
|
|
||||||
func (b *BucketHandle) Notifications(ctx context.Context) (n map[string]*Notification, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Notifications")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
call := b.c.raw.Notifications.List(b.name)
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if b.userProject != "" {
|
|
||||||
call.UserProject(b.userProject)
|
|
||||||
}
|
|
||||||
var res *raw.Notifications
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
res, err = call.Context(ctx).Do()
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return notificationsToMap(res.Items), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func notificationsToMap(rns []*raw.Notification) map[string]*Notification {
|
|
||||||
m := map[string]*Notification{}
|
|
||||||
for _, rn := range rns {
|
|
||||||
m[rn.Id] = toNotification(rn)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteNotification deletes the notification with the given ID.
|
|
||||||
func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) (err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.DeleteNotification")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
call := b.c.raw.Notifications.Delete(b.name, id)
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
if b.userProject != "" {
|
|
||||||
call.UserProject(b.userProject)
|
|
||||||
}
|
|
||||||
return call.Context(ctx).Do()
|
|
||||||
}
|
|
387
vendor/cloud.google.com/go/storage/post_policy_v4.go
generated
vendored
387
vendor/cloud.google.com/go/storage/post_policy_v4.go
generated
vendored
|
@ -1,387 +0,0 @@
|
||||||
// Copyright 2020 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostPolicyV4Options are used to construct a signed post policy.
|
|
||||||
// Please see https://cloud.google.com/storage/docs/xml-api/post-object
|
|
||||||
// for reference about the fields.
|
|
||||||
type PostPolicyV4Options struct {
|
|
||||||
// GoogleAccessID represents the authorizer of the signed URL generation.
|
|
||||||
// It is typically the Google service account client email address from
|
|
||||||
// the Google Developers Console in the form of "xxx@developer.gserviceaccount.com".
|
|
||||||
// Required.
|
|
||||||
GoogleAccessID string
|
|
||||||
|
|
||||||
// PrivateKey is the Google service account private key. It is obtainable
|
|
||||||
// from the Google Developers Console.
|
|
||||||
// At https://console.developers.google.com/project/<your-project-id>/apiui/credential,
|
|
||||||
// create a service account client ID or reuse one of your existing service account
|
|
||||||
// credentials. Click on the "Generate new P12 key" to generate and download
|
|
||||||
// a new private key. Once you download the P12 file, use the following command
|
|
||||||
// to convert it into a PEM file.
|
|
||||||
//
|
|
||||||
// $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes
|
|
||||||
//
|
|
||||||
// Provide the contents of the PEM file as a byte slice.
|
|
||||||
// Exactly one of PrivateKey or SignBytes must be non-nil.
|
|
||||||
PrivateKey []byte
|
|
||||||
|
|
||||||
// SignBytes is a function for implementing custom signing. For example, if
|
|
||||||
// your application is running on Google App Engine, you can use
|
|
||||||
// appengine's internal signing function:
|
|
||||||
// ctx := appengine.NewContext(request)
|
|
||||||
// acc, _ := appengine.ServiceAccount(ctx)
|
|
||||||
// url, err := SignedURL("bucket", "object", &SignedURLOptions{
|
|
||||||
// GoogleAccessID: acc,
|
|
||||||
// SignBytes: func(b []byte) ([]byte, error) {
|
|
||||||
// _, signedBytes, err := appengine.SignBytes(ctx, b)
|
|
||||||
// return signedBytes, err
|
|
||||||
// },
|
|
||||||
// // etc.
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// Exactly one of PrivateKey or SignBytes must be non-nil.
|
|
||||||
SignBytes func(hashBytes []byte) (signature []byte, err error)
|
|
||||||
|
|
||||||
// Expires is the expiration time on the signed URL.
|
|
||||||
// It must be a time in the future.
|
|
||||||
// Required.
|
|
||||||
Expires time.Time
|
|
||||||
|
|
||||||
// Style provides options for the type of URL to use. Options are
|
|
||||||
// PathStyle (default), BucketBoundHostname, and VirtualHostedStyle. See
|
|
||||||
// https://cloud.google.com/storage/docs/request-endpoints for details.
|
|
||||||
// Optional.
|
|
||||||
Style URLStyle
|
|
||||||
|
|
||||||
// Insecure when set indicates that the generated URL's scheme
|
|
||||||
// will use "http" instead of "https" (default).
|
|
||||||
// Optional.
|
|
||||||
Insecure bool
|
|
||||||
|
|
||||||
// Fields specifies the attributes of a PostPolicyV4 request.
|
|
||||||
// When Fields is non-nil, its attributes must match those that will
|
|
||||||
// passed into field Conditions.
|
|
||||||
// Optional.
|
|
||||||
Fields *PolicyV4Fields
|
|
||||||
|
|
||||||
// The conditions that the uploaded file will be expected to conform to.
|
|
||||||
// When used, the failure of an upload to satisfy a condition will result in
|
|
||||||
// a 4XX status code, back with the message describing the problem.
|
|
||||||
// Optional.
|
|
||||||
Conditions []PostPolicyV4Condition
|
|
||||||
}
|
|
||||||
|
|
||||||
// PolicyV4Fields describes the attributes for a PostPolicyV4 request.
|
|
||||||
type PolicyV4Fields struct {
|
|
||||||
// ACL specifies the access control permissions for the object.
|
|
||||||
// Optional.
|
|
||||||
ACL string
|
|
||||||
// CacheControl specifies the caching directives for the object.
|
|
||||||
// Optional.
|
|
||||||
CacheControl string
|
|
||||||
// ContentType specifies the media type of the object.
|
|
||||||
// Optional.
|
|
||||||
ContentType string
|
|
||||||
// ContentDisposition specifies how the file will be served back to requesters.
|
|
||||||
// Optional.
|
|
||||||
ContentDisposition string
|
|
||||||
// ContentEncoding specifies the decompressive transcoding that the object.
|
|
||||||
// This field is complementary to ContentType in that the file could be
|
|
||||||
// compressed but ContentType specifies the file's original media type.
|
|
||||||
// Optional.
|
|
||||||
ContentEncoding string
|
|
||||||
// Metadata specifies custom metadata for the object.
|
|
||||||
// If any key doesn't begin with "x-goog-meta-", an error will be returned.
|
|
||||||
// Optional.
|
|
||||||
Metadata map[string]string
|
|
||||||
// StatusCodeOnSuccess when set, specifies the status code that Cloud Storage
|
|
||||||
// will serve back on successful upload of the object.
|
|
||||||
// Optional.
|
|
||||||
StatusCodeOnSuccess int
|
|
||||||
// RedirectToURLOnSuccess when set, specifies the URL that Cloud Storage
|
|
||||||
// will serve back on successful upload of the object.
|
|
||||||
// Optional.
|
|
||||||
RedirectToURLOnSuccess string
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostPolicyV4 describes the URL and respective form fields for a generated PostPolicyV4 request.
|
|
||||||
type PostPolicyV4 struct {
|
|
||||||
// URL is the generated URL that the file upload will be made to.
|
|
||||||
URL string
|
|
||||||
// Fields specifies the generated key-values that the file uploader
|
|
||||||
// must include in their multipart upload form.
|
|
||||||
Fields map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostPolicyV4Condition describes the constraints that the subsequent
|
|
||||||
// object upload's multipart form fields will be expected to conform to.
|
|
||||||
type PostPolicyV4Condition interface {
|
|
||||||
isEmpty() bool
|
|
||||||
json.Marshaler
|
|
||||||
}
|
|
||||||
|
|
||||||
type startsWith struct {
|
|
||||||
key, value string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sw *startsWith) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal([]string{"starts-with", sw.key, sw.value})
|
|
||||||
}
|
|
||||||
func (sw *startsWith) isEmpty() bool {
|
|
||||||
return sw.value == ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConditionStartsWith checks that an attributes starts with value.
|
|
||||||
// An empty value will cause this condition to be ignored.
|
|
||||||
func ConditionStartsWith(key, value string) PostPolicyV4Condition {
|
|
||||||
return &startsWith{key, value}
|
|
||||||
}
|
|
||||||
|
|
||||||
type contentLengthRangeCondition struct {
|
|
||||||
start, end uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (clr *contentLengthRangeCondition) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal([]interface{}{"content-length-range", clr.start, clr.end})
|
|
||||||
}
|
|
||||||
func (clr *contentLengthRangeCondition) isEmpty() bool {
|
|
||||||
return clr.start == 0 && clr.end == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type singleValueCondition struct {
|
|
||||||
name, value string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *singleValueCondition) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(map[string]string{svc.name: svc.value})
|
|
||||||
}
|
|
||||||
func (svc *singleValueCondition) isEmpty() bool {
|
|
||||||
return svc.value == ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConditionContentLengthRange constraints the limits that the
|
|
||||||
// multipart upload's range header will be expected to be within.
|
|
||||||
func ConditionContentLengthRange(start, end uint64) PostPolicyV4Condition {
|
|
||||||
return &contentLengthRangeCondition{start, end}
|
|
||||||
}
|
|
||||||
|
|
||||||
func conditionRedirectToURLOnSuccess(redirectURL string) PostPolicyV4Condition {
|
|
||||||
return &singleValueCondition{"success_action_redirect", redirectURL}
|
|
||||||
}
|
|
||||||
|
|
||||||
func conditionStatusCodeOnSuccess(statusCode int) PostPolicyV4Condition {
|
|
||||||
svc := &singleValueCondition{name: "success_action_status"}
|
|
||||||
if statusCode > 0 {
|
|
||||||
svc.value = fmt.Sprintf("%d", statusCode)
|
|
||||||
}
|
|
||||||
return svc
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateSignedPostPolicyV4 generates a PostPolicyV4 value from bucket, object and opts.
|
|
||||||
// The generated URL and fields will then allow an unauthenticated client to perform multipart uploads.
|
|
||||||
func GenerateSignedPostPolicyV4(bucket, object string, opts *PostPolicyV4Options) (*PostPolicyV4, error) {
|
|
||||||
if bucket == "" {
|
|
||||||
return nil, errors.New("storage: bucket must be non-empty")
|
|
||||||
}
|
|
||||||
if object == "" {
|
|
||||||
return nil, errors.New("storage: object must be non-empty")
|
|
||||||
}
|
|
||||||
now := utcNow()
|
|
||||||
if err := validatePostPolicyV4Options(opts, now); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var signingFn func(hashedBytes []byte) ([]byte, error)
|
|
||||||
switch {
|
|
||||||
case opts.SignBytes != nil:
|
|
||||||
signingFn = opts.SignBytes
|
|
||||||
|
|
||||||
case len(opts.PrivateKey) != 0:
|
|
||||||
parsedRSAPrivKey, err := parseKey(opts.PrivateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
signingFn = func(hashedBytes []byte) ([]byte, error) {
|
|
||||||
return rsa.SignPKCS1v15(rand.Reader, parsedRSAPrivKey, crypto.SHA256, hashedBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, errors.New("storage: exactly one of PrivateKey or SignedBytes must be set")
|
|
||||||
}
|
|
||||||
|
|
||||||
var descFields PolicyV4Fields
|
|
||||||
if opts.Fields != nil {
|
|
||||||
descFields = *opts.Fields
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := validateMetadata(descFields.Metadata); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the policy.
|
|
||||||
conds := make([]PostPolicyV4Condition, len(opts.Conditions))
|
|
||||||
copy(conds, opts.Conditions)
|
|
||||||
conds = append(conds,
|
|
||||||
// These are ordered lexicographically. Technically the order doesn't matter
|
|
||||||
// for creating the policy, but we use this order to match the
|
|
||||||
// cross-language conformance tests for this feature.
|
|
||||||
&singleValueCondition{"acl", descFields.ACL},
|
|
||||||
&singleValueCondition{"cache-control", descFields.CacheControl},
|
|
||||||
&singleValueCondition{"content-disposition", descFields.ContentDisposition},
|
|
||||||
&singleValueCondition{"content-encoding", descFields.ContentEncoding},
|
|
||||||
&singleValueCondition{"content-type", descFields.ContentType},
|
|
||||||
conditionRedirectToURLOnSuccess(descFields.RedirectToURLOnSuccess),
|
|
||||||
conditionStatusCodeOnSuccess(descFields.StatusCodeOnSuccess),
|
|
||||||
)
|
|
||||||
|
|
||||||
YYYYMMDD := now.Format(yearMonthDay)
|
|
||||||
policyFields := map[string]string{
|
|
||||||
"key": object,
|
|
||||||
"x-goog-date": now.Format(iso8601),
|
|
||||||
"x-goog-credential": opts.GoogleAccessID + "/" + YYYYMMDD + "/auto/storage/goog4_request",
|
|
||||||
"x-goog-algorithm": "GOOG4-RSA-SHA256",
|
|
||||||
"acl": descFields.ACL,
|
|
||||||
"cache-control": descFields.CacheControl,
|
|
||||||
"content-disposition": descFields.ContentDisposition,
|
|
||||||
"content-encoding": descFields.ContentEncoding,
|
|
||||||
"content-type": descFields.ContentType,
|
|
||||||
"success_action_redirect": descFields.RedirectToURLOnSuccess,
|
|
||||||
}
|
|
||||||
for key, value := range descFields.Metadata {
|
|
||||||
conds = append(conds, &singleValueCondition{key, value})
|
|
||||||
policyFields[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Following from the order expected by the conformance test cases,
|
|
||||||
// hence manually inserting these fields in a specific order.
|
|
||||||
conds = append(conds,
|
|
||||||
&singleValueCondition{"bucket", bucket},
|
|
||||||
&singleValueCondition{"key", object},
|
|
||||||
&singleValueCondition{"x-goog-date", now.Format(iso8601)},
|
|
||||||
&singleValueCondition{
|
|
||||||
name: "x-goog-credential",
|
|
||||||
value: opts.GoogleAccessID + "/" + YYYYMMDD + "/auto/storage/goog4_request",
|
|
||||||
},
|
|
||||||
&singleValueCondition{"x-goog-algorithm", "GOOG4-RSA-SHA256"},
|
|
||||||
)
|
|
||||||
|
|
||||||
nonEmptyConds := make([]PostPolicyV4Condition, 0, len(opts.Conditions))
|
|
||||||
for _, cond := range conds {
|
|
||||||
if cond == nil || !cond.isEmpty() {
|
|
||||||
nonEmptyConds = append(nonEmptyConds, cond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
condsAsJSON, err := json.Marshal(map[string]interface{}{
|
|
||||||
"conditions": nonEmptyConds,
|
|
||||||
"expiration": opts.Expires.Format(time.RFC3339),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("storage: PostPolicyV4 JSON serialization failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b64Policy := base64.StdEncoding.EncodeToString(condsAsJSON)
|
|
||||||
shaSum := sha256.Sum256([]byte(b64Policy))
|
|
||||||
signature, err := signingFn(shaSum[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
policyFields["policy"] = b64Policy
|
|
||||||
policyFields["x-goog-signature"] = fmt.Sprintf("%x", signature)
|
|
||||||
|
|
||||||
// Construct the URL.
|
|
||||||
scheme := "https"
|
|
||||||
if opts.Insecure {
|
|
||||||
scheme = "http"
|
|
||||||
}
|
|
||||||
path := opts.Style.path(bucket, "") + "/"
|
|
||||||
u := &url.URL{
|
|
||||||
Path: path,
|
|
||||||
RawPath: pathEncodeV4(path),
|
|
||||||
Host: opts.Style.host(bucket),
|
|
||||||
Scheme: scheme,
|
|
||||||
}
|
|
||||||
|
|
||||||
if descFields.StatusCodeOnSuccess > 0 {
|
|
||||||
policyFields["success_action_status"] = fmt.Sprintf("%d", descFields.StatusCodeOnSuccess)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear out fields with blanks values.
|
|
||||||
for key, value := range policyFields {
|
|
||||||
if value == "" {
|
|
||||||
delete(policyFields, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pp4 := &PostPolicyV4{
|
|
||||||
Fields: policyFields,
|
|
||||||
URL: u.String(),
|
|
||||||
}
|
|
||||||
return pp4, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validatePostPolicyV4Options checks that:
|
|
||||||
// * GoogleAccessID is set
|
|
||||||
// * either but not both PrivateKey and SignBytes are set or nil, but not both
|
|
||||||
// * Expires, the deadline is not in the past
|
|
||||||
// * if Style is not set, it'll use PathStyle
|
|
||||||
func validatePostPolicyV4Options(opts *PostPolicyV4Options, now time.Time) error {
|
|
||||||
if opts == nil || opts.GoogleAccessID == "" {
|
|
||||||
return errors.New("storage: missing required GoogleAccessID")
|
|
||||||
}
|
|
||||||
if privBlank, signBlank := len(opts.PrivateKey) == 0, opts.SignBytes == nil; privBlank == signBlank {
|
|
||||||
return errors.New("storage: exactly one of PrivateKey or SignedBytes must be set")
|
|
||||||
}
|
|
||||||
if opts.Expires.Before(now) {
|
|
||||||
return errors.New("storage: expecting Expires to be in the future")
|
|
||||||
}
|
|
||||||
if opts.Style == nil {
|
|
||||||
opts.Style = PathStyle()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateMetadata ensures that all keys passed in have a prefix of "x-goog-meta-",
|
|
||||||
// otherwise it will return an error.
|
|
||||||
func validateMetadata(hdrs map[string]string) (err error) {
|
|
||||||
if len(hdrs) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
badKeys := make([]string, 0, len(hdrs))
|
|
||||||
for key := range hdrs {
|
|
||||||
if !strings.HasPrefix(key, "x-goog-meta-") {
|
|
||||||
badKeys = append(badKeys, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(badKeys) != 0 {
|
|
||||||
err = errors.New("storage: expected metadata to begin with x-goog-meta-, got " + strings.Join(badKeys, ", "))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
435
vendor/cloud.google.com/go/storage/reader.go
generated
vendored
435
vendor/cloud.google.com/go/storage/reader.go
generated
vendored
|
@ -1,435 +0,0 @@
|
||||||
// Copyright 2016 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"hash/crc32"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"cloud.google.com/go/internal/trace"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
)
|
|
||||||
|
|
||||||
var crc32cTable = crc32.MakeTable(crc32.Castagnoli)
|
|
||||||
|
|
||||||
// ReaderObjectAttrs are attributes about the object being read. These are populated
|
|
||||||
// during the New call. This struct only holds a subset of object attributes: to
|
|
||||||
// get the full set of attributes, use ObjectHandle.Attrs.
|
|
||||||
//
|
|
||||||
// Each field is read-only.
|
|
||||||
type ReaderObjectAttrs struct {
|
|
||||||
// Size is the length of the object's content.
|
|
||||||
Size int64
|
|
||||||
|
|
||||||
// StartOffset is the byte offset within the object
|
|
||||||
// from which reading begins.
|
|
||||||
// This value is only non-zero for range requests.
|
|
||||||
StartOffset int64
|
|
||||||
|
|
||||||
// ContentType is the MIME type of the object's content.
|
|
||||||
ContentType string
|
|
||||||
|
|
||||||
// ContentEncoding is the encoding of the object's content.
|
|
||||||
ContentEncoding string
|
|
||||||
|
|
||||||
// CacheControl specifies whether and for how long browser and Internet
|
|
||||||
// caches are allowed to cache your objects.
|
|
||||||
CacheControl string
|
|
||||||
|
|
||||||
// LastModified is the time that the object was last modified.
|
|
||||||
LastModified time.Time
|
|
||||||
|
|
||||||
// Generation is the generation number of the object's content.
|
|
||||||
Generation int64
|
|
||||||
|
|
||||||
// Metageneration is the version of the metadata for this object at
|
|
||||||
// this generation. This field is used for preconditions and for
|
|
||||||
// detecting changes in metadata. A metageneration number is only
|
|
||||||
// meaningful in the context of a particular generation of a
|
|
||||||
// particular object.
|
|
||||||
Metageneration int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewReader creates a new Reader to read the contents of the
|
|
||||||
// object.
|
|
||||||
// ErrObjectNotExist will be returned if the object is not found.
|
|
||||||
//
|
|
||||||
// The caller must call Close on the returned Reader when done reading.
|
|
||||||
func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) {
|
|
||||||
return o.NewRangeReader(ctx, 0, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRangeReader reads part of an object, reading at most length bytes
|
|
||||||
// starting at the given offset. If length is negative, the object is read
|
|
||||||
// until the end. If offset is negative, the object is read abs(offset) bytes
|
|
||||||
// from the end, and length must also be negative to indicate all remaining
|
|
||||||
// bytes will be read.
|
|
||||||
//
|
|
||||||
// If the object's metadata property "Content-Encoding" is set to "gzip" or satisfies
|
|
||||||
// decompressive transcoding per https://cloud.google.com/storage/docs/transcoding
|
|
||||||
// that file will be served back whole, regardless of the requested range as
|
|
||||||
// Google Cloud Storage dictates.
|
|
||||||
func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64) (r *Reader, err error) {
|
|
||||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Object.NewRangeReader")
|
|
||||||
defer func() { trace.EndSpan(ctx, err) }()
|
|
||||||
|
|
||||||
if err := o.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if offset < 0 && length >= 0 {
|
|
||||||
return nil, fmt.Errorf("storage: invalid offset %d < 0 requires negative length", offset)
|
|
||||||
}
|
|
||||||
if o.conds != nil {
|
|
||||||
if err := o.conds.validate("NewRangeReader"); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
u := &url.URL{
|
|
||||||
Scheme: o.c.scheme,
|
|
||||||
Host: o.c.readHost,
|
|
||||||
Path: fmt.Sprintf("/%s/%s", o.bucket, o.object),
|
|
||||||
}
|
|
||||||
verb := "GET"
|
|
||||||
if length == 0 {
|
|
||||||
verb = "HEAD"
|
|
||||||
}
|
|
||||||
req, err := http.NewRequest(verb, u.String(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if o.userProject != "" {
|
|
||||||
req.Header.Set("X-Goog-User-Project", o.userProject)
|
|
||||||
}
|
|
||||||
if o.readCompressed {
|
|
||||||
req.Header.Set("Accept-Encoding", "gzip")
|
|
||||||
}
|
|
||||||
if err := setEncryptionHeaders(req.Header, o.encryptionKey, false); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
gen := o.gen
|
|
||||||
|
|
||||||
// Define a function that initiates a Read with offset and length, assuming we
|
|
||||||
// have already read seen bytes.
|
|
||||||
reopen := func(seen int64) (*http.Response, error) {
|
|
||||||
start := offset + seen
|
|
||||||
if length < 0 && start < 0 {
|
|
||||||
req.Header.Set("Range", fmt.Sprintf("bytes=%d", start))
|
|
||||||
} else if length < 0 && start > 0 {
|
|
||||||
req.Header.Set("Range", fmt.Sprintf("bytes=%d-", start))
|
|
||||||
} else if length > 0 {
|
|
||||||
// The end character isn't affected by how many bytes we've seen.
|
|
||||||
req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, offset+length-1))
|
|
||||||
}
|
|
||||||
// We wait to assign conditions here because the generation number can change in between reopen() runs.
|
|
||||||
req.URL.RawQuery = conditionsQuery(gen, o.conds)
|
|
||||||
var res *http.Response
|
|
||||||
err = runWithRetry(ctx, func() error {
|
|
||||||
res, err = o.c.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if res.StatusCode == http.StatusNotFound {
|
|
||||||
res.Body.Close()
|
|
||||||
return ErrObjectNotExist
|
|
||||||
}
|
|
||||||
if res.StatusCode < 200 || res.StatusCode > 299 {
|
|
||||||
body, _ := ioutil.ReadAll(res.Body)
|
|
||||||
res.Body.Close()
|
|
||||||
return &googleapi.Error{
|
|
||||||
Code: res.StatusCode,
|
|
||||||
Header: res.Header,
|
|
||||||
Body: string(body),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partialContentNotSatisfied :=
|
|
||||||
!decompressiveTranscoding(res) &&
|
|
||||||
start > 0 && length != 0 &&
|
|
||||||
res.StatusCode != http.StatusPartialContent
|
|
||||||
|
|
||||||
if partialContentNotSatisfied {
|
|
||||||
res.Body.Close()
|
|
||||||
return errors.New("storage: partial request not satisfied")
|
|
||||||
}
|
|
||||||
|
|
||||||
// With "Content-Encoding": "gzip" aka decompressive transcoding, GCS serves
|
|
||||||
// back the whole file regardless of the range count passed in as per:
|
|
||||||
// https://cloud.google.com/storage/docs/transcoding#range,
|
|
||||||
// thus we have to manually move the body forward by seen bytes.
|
|
||||||
if decompressiveTranscoding(res) && seen > 0 {
|
|
||||||
_, _ = io.CopyN(ioutil.Discard, res.Body, seen)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a generation hasn't been specified, and this is the first response we get, let's record the
|
|
||||||
// generation. In future requests we'll use this generation as a precondition to avoid data races.
|
|
||||||
if gen < 0 && res.Header.Get("X-Goog-Generation") != "" {
|
|
||||||
gen64, err := strconv.ParseInt(res.Header.Get("X-Goog-Generation"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
gen = gen64
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := reopen(0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
size int64 // total size of object, even if a range was requested.
|
|
||||||
checkCRC bool
|
|
||||||
crc uint32
|
|
||||||
startOffset int64 // non-zero if range request.
|
|
||||||
)
|
|
||||||
if res.StatusCode == http.StatusPartialContent {
|
|
||||||
cr := strings.TrimSpace(res.Header.Get("Content-Range"))
|
|
||||||
if !strings.HasPrefix(cr, "bytes ") || !strings.Contains(cr, "/") {
|
|
||||||
return nil, fmt.Errorf("storage: invalid Content-Range %q", cr)
|
|
||||||
}
|
|
||||||
size, err = strconv.ParseInt(cr[strings.LastIndex(cr, "/")+1:], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("storage: invalid Content-Range %q", cr)
|
|
||||||
}
|
|
||||||
|
|
||||||
dashIndex := strings.Index(cr, "-")
|
|
||||||
if dashIndex >= 0 {
|
|
||||||
startOffset, err = strconv.ParseInt(cr[len("bytes="):dashIndex], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("storage: invalid Content-Range %q: %v", cr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size = res.ContentLength
|
|
||||||
// Check the CRC iff all of the following hold:
|
|
||||||
// - We asked for content (length != 0).
|
|
||||||
// - We got all the content (status != PartialContent).
|
|
||||||
// - The server sent a CRC header.
|
|
||||||
// - The Go http stack did not uncompress the file.
|
|
||||||
// - We were not served compressed data that was uncompressed on download.
|
|
||||||
// The problem with the last two cases is that the CRC will not match -- GCS
|
|
||||||
// computes it on the compressed contents, but we compute it on the
|
|
||||||
// uncompressed contents.
|
|
||||||
if length != 0 && !res.Uncompressed && !uncompressedByServer(res) {
|
|
||||||
crc, checkCRC = parseCRC32c(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remain := res.ContentLength
|
|
||||||
body := res.Body
|
|
||||||
if length == 0 {
|
|
||||||
remain = 0
|
|
||||||
body.Close()
|
|
||||||
body = emptyBody
|
|
||||||
}
|
|
||||||
var metaGen int64
|
|
||||||
if res.Header.Get("X-Goog-Metageneration") != "" {
|
|
||||||
metaGen, err = strconv.ParseInt(res.Header.Get("X-Goog-Metageneration"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lm time.Time
|
|
||||||
if res.Header.Get("Last-Modified") != "" {
|
|
||||||
lm, err = http.ParseTime(res.Header.Get("Last-Modified"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attrs := ReaderObjectAttrs{
|
|
||||||
Size: size,
|
|
||||||
ContentType: res.Header.Get("Content-Type"),
|
|
||||||
ContentEncoding: res.Header.Get("Content-Encoding"),
|
|
||||||
CacheControl: res.Header.Get("Cache-Control"),
|
|
||||||
LastModified: lm,
|
|
||||||
StartOffset: startOffset,
|
|
||||||
Generation: gen,
|
|
||||||
Metageneration: metaGen,
|
|
||||||
}
|
|
||||||
return &Reader{
|
|
||||||
Attrs: attrs,
|
|
||||||
body: body,
|
|
||||||
size: size,
|
|
||||||
remain: remain,
|
|
||||||
wantCRC: crc,
|
|
||||||
checkCRC: checkCRC,
|
|
||||||
reopen: reopen,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// decompressiveTranscoding returns true if the request was served decompressed
|
|
||||||
// and different than its original storage form. This happens when the "Content-Encoding"
|
|
||||||
// header is "gzip".
|
|
||||||
// See:
|
|
||||||
// * https://cloud.google.com/storage/docs/transcoding#transcoding_and_gzip
|
|
||||||
// * https://github.com/googleapis/google-cloud-go/issues/1800
|
|
||||||
func decompressiveTranscoding(res *http.Response) bool {
|
|
||||||
// Decompressive Transcoding.
|
|
||||||
return res.Header.Get("Content-Encoding") == "gzip" ||
|
|
||||||
res.Header.Get("X-Goog-Stored-Content-Encoding") == "gzip"
|
|
||||||
}
|
|
||||||
|
|
||||||
func uncompressedByServer(res *http.Response) bool {
|
|
||||||
// If the data is stored as gzip but is not encoded as gzip, then it
|
|
||||||
// was uncompressed by the server.
|
|
||||||
return res.Header.Get("X-Goog-Stored-Content-Encoding") == "gzip" &&
|
|
||||||
res.Header.Get("Content-Encoding") != "gzip"
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseCRC32c(res *http.Response) (uint32, bool) {
|
|
||||||
const prefix = "crc32c="
|
|
||||||
for _, spec := range res.Header["X-Goog-Hash"] {
|
|
||||||
if strings.HasPrefix(spec, prefix) {
|
|
||||||
c, err := decodeUint32(spec[len(prefix):])
|
|
||||||
if err == nil {
|
|
||||||
return c, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
var emptyBody = ioutil.NopCloser(strings.NewReader(""))
|
|
||||||
|
|
||||||
// Reader reads a Cloud Storage object.
|
|
||||||
// It implements io.Reader.
|
|
||||||
//
|
|
||||||
// Typically, a Reader computes the CRC of the downloaded content and compares it to
|
|
||||||
// the stored CRC, returning an error from Read if there is a mismatch. This integrity check
|
|
||||||
// is skipped if transcoding occurs. See https://cloud.google.com/storage/docs/transcoding.
|
|
||||||
type Reader struct {
|
|
||||||
Attrs ReaderObjectAttrs
|
|
||||||
body io.ReadCloser
|
|
||||||
seen, remain, size int64
|
|
||||||
checkCRC bool // should we check the CRC?
|
|
||||||
wantCRC uint32 // the CRC32c value the server sent in the header
|
|
||||||
gotCRC uint32 // running crc
|
|
||||||
reopen func(seen int64) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the Reader. It must be called when done reading.
|
|
||||||
func (r *Reader) Close() error {
|
|
||||||
return r.body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reader) Read(p []byte) (int, error) {
|
|
||||||
n, err := r.readWithRetry(p)
|
|
||||||
if r.remain != -1 {
|
|
||||||
r.remain -= int64(n)
|
|
||||||
}
|
|
||||||
if r.checkCRC {
|
|
||||||
r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n])
|
|
||||||
// Check CRC here. It would be natural to check it in Close, but
|
|
||||||
// everybody defers Close on the assumption that it doesn't return
|
|
||||||
// anything worth looking at.
|
|
||||||
if err == io.EOF {
|
|
||||||
if r.gotCRC != r.wantCRC {
|
|
||||||
return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d",
|
|
||||||
r.gotCRC, r.wantCRC)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reader) readWithRetry(p []byte) (int, error) {
|
|
||||||
n := 0
|
|
||||||
for len(p[n:]) > 0 {
|
|
||||||
m, err := r.body.Read(p[n:])
|
|
||||||
n += m
|
|
||||||
r.seen += int64(m)
|
|
||||||
if !shouldRetryRead(err) {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
// Read failed, but we will try again. Send a ranged read request that takes
|
|
||||||
// into account the number of bytes we've already seen.
|
|
||||||
res, err := r.reopen(r.seen)
|
|
||||||
if err != nil {
|
|
||||||
// reopen already retries
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
r.body.Close()
|
|
||||||
r.body = res.Body
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldRetryRead(err error) bool {
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return strings.HasSuffix(err.Error(), "INTERNAL_ERROR") && strings.Contains(reflect.TypeOf(err).String(), "http2")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns the size of the object in bytes.
|
|
||||||
// The returned value is always the same and is not affected by
|
|
||||||
// calls to Read or Close.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.Size.
|
|
||||||
func (r *Reader) Size() int64 {
|
|
||||||
return r.Attrs.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remain returns the number of bytes left to read, or -1 if unknown.
|
|
||||||
func (r *Reader) Remain() int64 {
|
|
||||||
return r.remain
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContentType returns the content type of the object.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.ContentType.
|
|
||||||
func (r *Reader) ContentType() string {
|
|
||||||
return r.Attrs.ContentType
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContentEncoding returns the content encoding of the object.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.ContentEncoding.
|
|
||||||
func (r *Reader) ContentEncoding() string {
|
|
||||||
return r.Attrs.ContentEncoding
|
|
||||||
}
|
|
||||||
|
|
||||||
// CacheControl returns the cache control of the object.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.CacheControl.
|
|
||||||
func (r *Reader) CacheControl() string {
|
|
||||||
return r.Attrs.CacheControl
|
|
||||||
}
|
|
||||||
|
|
||||||
// LastModified returns the value of the Last-Modified header.
|
|
||||||
//
|
|
||||||
// Deprecated: use Reader.Attrs.LastModified.
|
|
||||||
func (r *Reader) LastModified() (time.Time, error) {
|
|
||||||
return r.Attrs.LastModified, nil
|
|
||||||
}
|
|
1643
vendor/cloud.google.com/go/storage/storage.go
generated
vendored
1643
vendor/cloud.google.com/go/storage/storage.go
generated
vendored
File diff suppressed because it is too large
Load diff
30067
vendor/cloud.google.com/go/storage/storage.replay
generated
vendored
30067
vendor/cloud.google.com/go/storage/storage.replay
generated
vendored
File diff suppressed because one or more lines are too long
268
vendor/cloud.google.com/go/storage/writer.go
generated
vendored
268
vendor/cloud.google.com/go/storage/writer.go
generated
vendored
|
@ -1,268 +0,0 @@
|
||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
raw "google.golang.org/api/storage/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Writer writes a Cloud Storage object.
|
|
||||||
type Writer struct {
|
|
||||||
// ObjectAttrs are optional attributes to set on the object. Any attributes
|
|
||||||
// must be initialized before the first Write call. Nil or zero-valued
|
|
||||||
// attributes are ignored.
|
|
||||||
ObjectAttrs
|
|
||||||
|
|
||||||
// SendCRC specifies whether to transmit a CRC32C field. It should be set
|
|
||||||
// to true in addition to setting the Writer's CRC32C field, because zero
|
|
||||||
// is a valid CRC and normally a zero would not be transmitted.
|
|
||||||
// If a CRC32C is sent, and the data written does not match the checksum,
|
|
||||||
// the write will be rejected.
|
|
||||||
SendCRC32C bool
|
|
||||||
|
|
||||||
// ChunkSize controls the maximum number of bytes of the object that the
|
|
||||||
// Writer will attempt to send to the server in a single request. Objects
|
|
||||||
// smaller than the size will be sent in a single request, while larger
|
|
||||||
// objects will be split over multiple requests. The size will be rounded up
|
|
||||||
// to the nearest multiple of 256K.
|
|
||||||
//
|
|
||||||
// ChunkSize will default to a reasonable value. If you perform many
|
|
||||||
// concurrent writes of small objects (under ~8MB), you may wish set ChunkSize
|
|
||||||
// to a value that matches your objects' sizes to avoid consuming large
|
|
||||||
// amounts of memory. See
|
|
||||||
// https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#size
|
|
||||||
// for more information about performance trade-offs related to ChunkSize.
|
|
||||||
//
|
|
||||||
// If ChunkSize is set to zero, chunking will be disabled and the object will
|
|
||||||
// be uploaded in a single request without the use of a buffer. This will
|
|
||||||
// further reduce memory used during uploads, but will also prevent the writer
|
|
||||||
// from retrying in case of a transient error from the server, since a buffer
|
|
||||||
// is required in order to retry the failed request.
|
|
||||||
//
|
|
||||||
// ChunkSize must be set before the first Write call.
|
|
||||||
ChunkSize int
|
|
||||||
|
|
||||||
// ProgressFunc can be used to monitor the progress of a large write.
|
|
||||||
// operation. If ProgressFunc is not nil and writing requires multiple
|
|
||||||
// calls to the underlying service (see
|
|
||||||
// https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload),
|
|
||||||
// then ProgressFunc will be invoked after each call with the number of bytes of
|
|
||||||
// content copied so far.
|
|
||||||
//
|
|
||||||
// ProgressFunc should return quickly without blocking.
|
|
||||||
ProgressFunc func(int64)
|
|
||||||
|
|
||||||
ctx context.Context
|
|
||||||
o *ObjectHandle
|
|
||||||
|
|
||||||
opened bool
|
|
||||||
pw *io.PipeWriter
|
|
||||||
|
|
||||||
donec chan struct{} // closed after err and obj are set.
|
|
||||||
obj *ObjectAttrs
|
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Writer) open() error {
|
|
||||||
attrs := w.ObjectAttrs
|
|
||||||
// Check the developer didn't change the object Name (this is unfortunate, but
|
|
||||||
// we don't want to store an object under the wrong name).
|
|
||||||
if attrs.Name != w.o.object {
|
|
||||||
return fmt.Errorf("storage: Writer.Name %q does not match object name %q", attrs.Name, w.o.object)
|
|
||||||
}
|
|
||||||
if !utf8.ValidString(attrs.Name) {
|
|
||||||
return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name)
|
|
||||||
}
|
|
||||||
if attrs.KMSKeyName != "" && w.o.encryptionKey != nil {
|
|
||||||
return errors.New("storage: cannot use KMSKeyName with a customer-supplied encryption key")
|
|
||||||
}
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
w.pw = pw
|
|
||||||
w.opened = true
|
|
||||||
|
|
||||||
go w.monitorCancel()
|
|
||||||
|
|
||||||
if w.ChunkSize < 0 {
|
|
||||||
return errors.New("storage: Writer.ChunkSize must be non-negative")
|
|
||||||
}
|
|
||||||
mediaOpts := []googleapi.MediaOption{
|
|
||||||
googleapi.ChunkSize(w.ChunkSize),
|
|
||||||
}
|
|
||||||
if c := attrs.ContentType; c != "" {
|
|
||||||
mediaOpts = append(mediaOpts, googleapi.ContentType(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer close(w.donec)
|
|
||||||
|
|
||||||
rawObj := attrs.toRawObject(w.o.bucket)
|
|
||||||
if w.SendCRC32C {
|
|
||||||
rawObj.Crc32c = encodeUint32(attrs.CRC32C)
|
|
||||||
}
|
|
||||||
if w.MD5 != nil {
|
|
||||||
rawObj.Md5Hash = base64.StdEncoding.EncodeToString(w.MD5)
|
|
||||||
}
|
|
||||||
if w.o.c.envHost != "" {
|
|
||||||
w.o.c.raw.BasePath = fmt.Sprintf("%s://%s", w.o.c.scheme, w.o.c.envHost)
|
|
||||||
}
|
|
||||||
call := w.o.c.raw.Objects.Insert(w.o.bucket, rawObj).
|
|
||||||
Media(pr, mediaOpts...).
|
|
||||||
Projection("full").
|
|
||||||
Context(w.ctx).
|
|
||||||
Name(w.o.object)
|
|
||||||
|
|
||||||
if w.ProgressFunc != nil {
|
|
||||||
call.ProgressUpdater(func(n, _ int64) { w.ProgressFunc(n) })
|
|
||||||
}
|
|
||||||
if attrs.KMSKeyName != "" {
|
|
||||||
call.KmsKeyName(attrs.KMSKeyName)
|
|
||||||
}
|
|
||||||
if attrs.PredefinedACL != "" {
|
|
||||||
call.PredefinedAcl(attrs.PredefinedACL)
|
|
||||||
}
|
|
||||||
if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil {
|
|
||||||
w.mu.Lock()
|
|
||||||
w.err = err
|
|
||||||
w.mu.Unlock()
|
|
||||||
pr.CloseWithError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var resp *raw.Object
|
|
||||||
err := applyConds("NewWriter", w.o.gen, w.o.conds, call)
|
|
||||||
if err == nil {
|
|
||||||
if w.o.userProject != "" {
|
|
||||||
call.UserProject(w.o.userProject)
|
|
||||||
}
|
|
||||||
setClientHeader(call.Header())
|
|
||||||
|
|
||||||
// The internals that perform call.Do automatically retry both the initial
|
|
||||||
// call to set up the upload as well as calls to upload individual chunks
|
|
||||||
// for a resumable upload (as long as the chunk size is non-zero). Hence
|
|
||||||
// there is no need to add retries here.
|
|
||||||
resp, err = call.Do()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
w.mu.Lock()
|
|
||||||
w.err = err
|
|
||||||
w.mu.Unlock()
|
|
||||||
pr.CloseWithError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.obj = newObject(resp)
|
|
||||||
}()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write appends to w. It implements the io.Writer interface.
|
|
||||||
//
|
|
||||||
// Since writes happen asynchronously, Write may return a nil
|
|
||||||
// error even though the write failed (or will fail). Always
|
|
||||||
// use the error returned from Writer.Close to determine if
|
|
||||||
// the upload was successful.
|
|
||||||
//
|
|
||||||
// Writes will be retried on transient errors from the server, unless
|
|
||||||
// Writer.ChunkSize has been set to zero.
|
|
||||||
func (w *Writer) Write(p []byte) (n int, err error) {
|
|
||||||
w.mu.Lock()
|
|
||||||
werr := w.err
|
|
||||||
w.mu.Unlock()
|
|
||||||
if werr != nil {
|
|
||||||
return 0, werr
|
|
||||||
}
|
|
||||||
if !w.opened {
|
|
||||||
if err := w.open(); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n, err = w.pw.Write(p)
|
|
||||||
if err != nil {
|
|
||||||
w.mu.Lock()
|
|
||||||
werr := w.err
|
|
||||||
w.mu.Unlock()
|
|
||||||
// Preserve existing functionality that when context is canceled, Write will return
|
|
||||||
// context.Canceled instead of "io: read/write on closed pipe". This hides the
|
|
||||||
// pipe implementation detail from users and makes Write seem as though it's an RPC.
|
|
||||||
if werr == context.Canceled || werr == context.DeadlineExceeded {
|
|
||||||
return n, werr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close completes the write operation and flushes any buffered data.
|
|
||||||
// If Close doesn't return an error, metadata about the written object
|
|
||||||
// can be retrieved by calling Attrs.
|
|
||||||
func (w *Writer) Close() error {
|
|
||||||
if !w.opened {
|
|
||||||
if err := w.open(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closing either the read or write causes the entire pipe to close.
|
|
||||||
if err := w.pw.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
<-w.donec
|
|
||||||
w.mu.Lock()
|
|
||||||
defer w.mu.Unlock()
|
|
||||||
return w.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitorCancel is intended to be used as a background goroutine. It monitors the
|
|
||||||
// context, and when it observes that the context has been canceled, it manually
|
|
||||||
// closes things that do not take a context.
|
|
||||||
func (w *Writer) monitorCancel() {
|
|
||||||
select {
|
|
||||||
case <-w.ctx.Done():
|
|
||||||
w.mu.Lock()
|
|
||||||
werr := w.ctx.Err()
|
|
||||||
w.err = werr
|
|
||||||
w.mu.Unlock()
|
|
||||||
|
|
||||||
// Closing either the read or write causes the entire pipe to close.
|
|
||||||
w.CloseWithError(werr)
|
|
||||||
case <-w.donec:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseWithError aborts the write operation with the provided error.
|
|
||||||
// CloseWithError always returns nil.
|
|
||||||
//
|
|
||||||
// Deprecated: cancel the context passed to NewWriter instead.
|
|
||||||
func (w *Writer) CloseWithError(err error) error {
|
|
||||||
if !w.opened {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return w.pw.CloseWithError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attrs returns metadata about a successfully-written object.
|
|
||||||
// It's only valid to call it after Close returns nil.
|
|
||||||
func (w *Writer) Attrs() *ObjectAttrs {
|
|
||||||
return w.obj
|
|
||||||
}
|
|
236
vendor/cloud.google.com/go/testing.md
generated
vendored
236
vendor/cloud.google.com/go/testing.md
generated
vendored
|
@ -1,236 +0,0 @@
|
||||||
# Testing Code that depends on Go Client Libraries
|
|
||||||
|
|
||||||
The Go client libraries generated as a part of `cloud.google.com/go` all take
|
|
||||||
the approach of returning concrete types instead of interfaces. That way, new
|
|
||||||
fields and methods can be added to the libraries without breaking users. This
|
|
||||||
document will go over some patterns that can be used to test code that depends
|
|
||||||
on the Go client libraries.
|
|
||||||
|
|
||||||
## Testing gRPC services using fakes
|
|
||||||
|
|
||||||
*Note*: You can see the full
|
|
||||||
[example code using a fake here](https://github.com/googleapis/google-cloud-go/tree/master/internal/examples/fake).
|
|
||||||
|
|
||||||
The clients found in `cloud.google.com/go` are gRPC based, with a couple of
|
|
||||||
notable exceptions being the [`storage`](https://pkg.go.dev/cloud.google.com/go/storage)
|
|
||||||
and [`bigquery`](https://pkg.go.dev/cloud.google.com/go/bigquery) clients.
|
|
||||||
Interactions with gRPC services can be faked by serving up your own in-memory
|
|
||||||
server within your test. One benefit of using this approach is that you don’t
|
|
||||||
need to define an interface in your runtime code; you can keep using
|
|
||||||
concrete struct types. You instead define a fake server in your test code. For
|
|
||||||
example, take a look at the following function:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
translate "cloud.google.com/go/translate/apiv3"
|
|
||||||
"github.com/googleapis/gax-go/v2"
|
|
||||||
translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TranslateTextWithConcreteClient(client *translate.TranslationClient, text string, targetLang string) (string, error) {
|
|
||||||
ctx := context.Background()
|
|
||||||
log.Printf("Translating %q to %q", text, targetLang)
|
|
||||||
req := &translatepb.TranslateTextRequest{
|
|
||||||
Parent: fmt.Sprintf("projects/%s/locations/global", os.Getenv("GOOGLE_CLOUD_PROJECT")),
|
|
||||||
TargetLanguageCode: "en-US",
|
|
||||||
Contents: []string{text},
|
|
||||||
}
|
|
||||||
resp, err := client.TranslateText(ctx, req)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("unable to translate text: %v", err)
|
|
||||||
}
|
|
||||||
translations := resp.GetTranslations()
|
|
||||||
if len(translations) != 1 {
|
|
||||||
return "", fmt.Errorf("expected only one result, got %d", len(translations))
|
|
||||||
}
|
|
||||||
return translations[0].TranslatedText, nil
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here is an example of what a fake server implementation would look like for
|
|
||||||
faking the interactions above:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type fakeTranslationServer struct {
|
|
||||||
translatepb.UnimplementedTranslationServiceServer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeTranslationServer) TranslateText(ctx context.Context, req *translatepb.TranslateTextRequest) (*translatepb.TranslateTextResponse, error) {
|
|
||||||
resp := &translatepb.TranslateTextResponse{
|
|
||||||
Translations: []*translatepb.Translation{
|
|
||||||
&translatepb.Translation{
|
|
||||||
TranslatedText: "Hello World",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
All of the generated protobuf code found in [google.golang.org/genproto](https://pkg.go.dev/google.golang.org/genproto)
|
|
||||||
contains a similar `package.UnimplmentedFooServer` type that is useful for
|
|
||||||
creating fakes. By embedding the unimplemented server in the
|
|
||||||
`fakeTranslationServer`, the fake will “inherit” all of the RPCs the server
|
|
||||||
exposes. Then, by providing our own `fakeTranslationServer.TranslateText`
|
|
||||||
method you can “override” the default unimplemented behavior of the one RPC that
|
|
||||||
you would like to be faked.
|
|
||||||
|
|
||||||
The test itself does require a little bit of setup: start up a `net.Listener`,
|
|
||||||
register the server, and tell the client library to call the server:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
translate "cloud.google.com/go/translate/apiv3"
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTranslateTextWithConcreteClient(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
// Setup the fake server.
|
|
||||||
fakeTranslationServer := &fakeTranslationServer{}
|
|
||||||
l, err := net.Listen("tcp", "localhost:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
gsrv := grpc.NewServer()
|
|
||||||
translatepb.RegisterTranslationServiceServer(gsrv, fakeTranslationServer)
|
|
||||||
fakeServerAddr := l.Addr().String()
|
|
||||||
go func() {
|
|
||||||
if err := gsrv.Serve(l); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Create a client.
|
|
||||||
client, err := translate.NewTranslationClient(ctx,
|
|
||||||
option.WithEndpoint(fakeServerAddr),
|
|
||||||
option.WithoutAuthentication(),
|
|
||||||
option.WithGRPCDialOption(grpc.WithInsecure()),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the test.
|
|
||||||
text, err := TranslateTextWithConcreteClient(client, "Hola Mundo", "en-US")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if text != "Hello World" {
|
|
||||||
t.Fatalf("got %q, want Hello World", text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing using mocks
|
|
||||||
|
|
||||||
*Note*: You can see the full
|
|
||||||
[example code using a mock here](https://github.com/googleapis/google-cloud-go/tree/master/internal/examples/mock).
|
|
||||||
|
|
||||||
When mocking code you need to work with interfaces. Let’s create an interface
|
|
||||||
for the `cloud.google.com/go/translate/apiv3` client used in the
|
|
||||||
`TranslateTextWithConcreteClient` function mentioned in the previous section.
|
|
||||||
The `translate.Client` has over a dozen methods but this code only uses one of
|
|
||||||
them. Here is an interface that satisfies the interactions of the
|
|
||||||
`translate.Client` in this function.
|
|
||||||
|
|
||||||
```go
|
|
||||||
type TranslationClient interface {
|
|
||||||
TranslateText(ctx context.Context, req *translatepb.TranslateTextRequest, opts ...gax.CallOption) (*translatepb.TranslateTextResponse, error)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now that we have an interface that satisfies the method being used we can
|
|
||||||
rewrite the function signature to take the interface instead of the concrete
|
|
||||||
type.
|
|
||||||
|
|
||||||
```go
|
|
||||||
func TranslateTextWithInterfaceClient(client TranslationClient, text string, targetLang string) (string, error) {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This allows a real `translate.Client` to be passed to the method in production
|
|
||||||
and for a mock implementation to be passed in during testing. This pattern can
|
|
||||||
be applied to any Go code, not just `cloud.google.com/go`. This is because
|
|
||||||
interfaces in Go are implicitly satisfied. Structs in the client libraries can
|
|
||||||
implicitly implement interfaces defined in your codebase. Let’s take a look at
|
|
||||||
what it might look like to define a lightweight mock for the `TranslationClient`
|
|
||||||
interface.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/googleapis/gax-go/v2"
|
|
||||||
translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mockClient struct{}
|
|
||||||
|
|
||||||
func (*mockClient) TranslateText(_ context.Context, req *translatepb.TranslateTextRequest, opts ...gax.CallOption) (*translatepb.TranslateTextResponse, error) {
|
|
||||||
resp := &translatepb.TranslateTextResponse{
|
|
||||||
Translations: []*translatepb.Translation{
|
|
||||||
&translatepb.Translation{
|
|
||||||
TranslatedText: "Hello World",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTranslateTextWithAbstractClient(t *testing.T) {
|
|
||||||
client := &mockClient{}
|
|
||||||
text, err := TranslateTextWithInterfaceClient(client, "Hola Mundo", "en-US")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if text != "Hello World" {
|
|
||||||
t.Fatalf("got %q, want Hello World", text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you prefer to not write your own mocks there are mocking frameworks such as
|
|
||||||
[golang/mock](https://github.com/golang/mock) which can generate mocks for you
|
|
||||||
from an interface. As a word of caution though, try to not
|
|
||||||
[overuse mocks](https://testing.googleblog.com/2013/05/testing-on-toilet-dont-overuse-mocks.html).
|
|
||||||
|
|
||||||
## Testing using emulators
|
|
||||||
|
|
||||||
Some of the client libraries provided in `cloud.google.com/go` support running
|
|
||||||
against a service emulator. The concept is similar to that of using fakes,
|
|
||||||
mentioned above, but the server is managed for you. You just need to start it up
|
|
||||||
and instruct the client library to talk to the emulator by setting a service
|
|
||||||
specific emulator environment variable. Current services/environment-variables
|
|
||||||
are:
|
|
||||||
|
|
||||||
- bigtable: `BIGTABLE_EMULATOR_HOST`
|
|
||||||
- datastore: `DATASTORE_EMULATOR_HOST`
|
|
||||||
- firestore: `FIRESTORE_EMULATOR_HOST`
|
|
||||||
- pubsub: `PUBSUB_EMULATOR_HOST`
|
|
||||||
- spanner: `SPANNER_EMULATOR_HOST`
|
|
||||||
- storage: `STORAGE_EMULATOR_HOST`
|
|
||||||
- Although the storage client supports an emulator environment variable there is no official emulator provided by gcloud.
|
|
||||||
|
|
||||||
For more information on emulators please refer to the
|
|
||||||
[gcloud documentation](https://cloud.google.com/sdk/gcloud/reference/beta/emulators).
|
|
31
vendor/cloud.google.com/go/tools.go
generated
vendored
31
vendor/cloud.google.com/go/tools.go
generated
vendored
|
@ -1,31 +0,0 @@
|
||||||
// +build tools
|
|
||||||
|
|
||||||
// Copyright 2018 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// This package exists to cause `go mod` and `go get` to believe these tools
|
|
||||||
// are dependencies, even though they are not runtime dependencies of any
|
|
||||||
// package (these are tools used by our CI builds). This means they will appear
|
|
||||||
// in our `go.mod` file, but will not be a part of the build. Also, since the
|
|
||||||
// build target is something non-existent, these should not be included in any
|
|
||||||
// binaries.
|
|
||||||
|
|
||||||
package cloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/golang/protobuf/protoc-gen-go"
|
|
||||||
_ "github.com/jstemmer/go-junit-report"
|
|
||||||
_ "golang.org/x/lint/golint"
|
|
||||||
_ "golang.org/x/tools/cmd/goimports"
|
|
||||||
)
|
|
22
vendor/github.com/VictoriaMetrics/fastcache/LICENSE
generated
vendored
22
vendor/github.com/VictoriaMetrics/fastcache/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2018 VictoriaMetrics
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
116
vendor/github.com/VictoriaMetrics/fastcache/README.md
generated
vendored
116
vendor/github.com/VictoriaMetrics/fastcache/README.md
generated
vendored
|
@ -1,116 +0,0 @@
|
||||||
[![Build Status](https://github.com/VictoriaMetrics/fastcache/workflows/main/badge.svg)](https://github.com/VictoriaMetrics/fastcache/actions)
|
|
||||||
[![GoDoc](https://godoc.org/github.com/VictoriaMetrics/fastcache?status.svg)](http://godoc.org/github.com/VictoriaMetrics/fastcache)
|
|
||||||
[![Go Report](https://goreportcard.com/badge/github.com/VictoriaMetrics/fastcache)](https://goreportcard.com/report/github.com/VictoriaMetrics/fastcache)
|
|
||||||
[![codecov](https://codecov.io/gh/VictoriaMetrics/fastcache/branch/master/graph/badge.svg)](https://codecov.io/gh/VictoriaMetrics/fastcache)
|
|
||||||
|
|
||||||
# fastcache - fast thread-safe inmemory cache for big number of entries in Go
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* Fast. Performance scales on multi-core CPUs. See benchmark results below.
|
|
||||||
* Thread-safe. Concurrent goroutines may read and write into a single
|
|
||||||
cache instance.
|
|
||||||
* The fastcache is designed for storing big number of entries without
|
|
||||||
[GC overhead](https://syslog.ravelin.com/further-dangers-of-large-heaps-in-go-7a267b57d487).
|
|
||||||
* Fastcache automatically evicts old entries when reaching the maximum cache size
|
|
||||||
set on its creation.
|
|
||||||
* [Simple API](http://godoc.org/github.com/VictoriaMetrics/fastcache).
|
|
||||||
* Simple source code.
|
|
||||||
* Cache may be [saved to file](https://godoc.org/github.com/VictoriaMetrics/fastcache#Cache.SaveToFile)
|
|
||||||
and [loaded from file](https://godoc.org/github.com/VictoriaMetrics/fastcache#LoadFromFile).
|
|
||||||
* Works on [Google AppEngine](https://cloud.google.com/appengine/docs/go/).
|
|
||||||
|
|
||||||
|
|
||||||
### Benchmarks
|
|
||||||
|
|
||||||
`Fastcache` performance is compared with [BigCache](https://github.com/allegro/bigcache), standard Go map
|
|
||||||
and [sync.Map](https://golang.org/pkg/sync/#Map).
|
|
||||||
|
|
||||||
```
|
|
||||||
GOMAXPROCS=4 go test github.com/VictoriaMetrics/fastcache -bench='Set|Get' -benchtime=10s
|
|
||||||
goos: linux
|
|
||||||
goarch: amd64
|
|
||||||
pkg: github.com/VictoriaMetrics/fastcache
|
|
||||||
BenchmarkBigCacheSet-4 2000 10566656 ns/op 6.20 MB/s 4660369 B/op 6 allocs/op
|
|
||||||
BenchmarkBigCacheGet-4 2000 6902694 ns/op 9.49 MB/s 684169 B/op 131076 allocs/op
|
|
||||||
BenchmarkBigCacheSetGet-4 1000 17579118 ns/op 7.46 MB/s 5046744 B/op 131083 allocs/op
|
|
||||||
BenchmarkCacheSet-4 5000 3808874 ns/op 17.21 MB/s 1142 B/op 2 allocs/op
|
|
||||||
BenchmarkCacheGet-4 5000 3293849 ns/op 19.90 MB/s 1140 B/op 2 allocs/op
|
|
||||||
BenchmarkCacheSetGet-4 2000 8456061 ns/op 15.50 MB/s 2857 B/op 5 allocs/op
|
|
||||||
BenchmarkStdMapSet-4 2000 10559382 ns/op 6.21 MB/s 268413 B/op 65537 allocs/op
|
|
||||||
BenchmarkStdMapGet-4 5000 2687404 ns/op 24.39 MB/s 2558 B/op 13 allocs/op
|
|
||||||
BenchmarkStdMapSetGet-4 100 154641257 ns/op 0.85 MB/s 387405 B/op 65558 allocs/op
|
|
||||||
BenchmarkSyncMapSet-4 500 24703219 ns/op 2.65 MB/s 3426543 B/op 262411 allocs/op
|
|
||||||
BenchmarkSyncMapGet-4 5000 2265892 ns/op 28.92 MB/s 2545 B/op 79 allocs/op
|
|
||||||
BenchmarkSyncMapSetGet-4 1000 14595535 ns/op 8.98 MB/s 3417190 B/op 262277 allocs/op
|
|
||||||
```
|
|
||||||
|
|
||||||
`MB/s` column here actually means `millions of operations per second`.
|
|
||||||
As you can see, `fastcache` is faster than the `BigCache` in all the cases.
|
|
||||||
`fastcache` is faster than the standard Go map and `sync.Map` on workloads
|
|
||||||
with inserts.
|
|
||||||
|
|
||||||
|
|
||||||
### Limitations
|
|
||||||
|
|
||||||
* Keys and values must be byte slices. Other types must be marshaled before
|
|
||||||
storing them in the cache.
|
|
||||||
* Big entries with sizes exceeding 64KB must be stored via [distinct API](http://godoc.org/github.com/VictoriaMetrics/fastcache#Cache.SetBig).
|
|
||||||
* There is no cache expiration. Entries are evicted from the cache only
|
|
||||||
on cache size overflow. Entry deadline may be stored inside the value in order
|
|
||||||
to implement cache expiration.
|
|
||||||
|
|
||||||
|
|
||||||
### Architecture details
|
|
||||||
|
|
||||||
The cache uses ideas from [BigCache](https://github.com/allegro/bigcache):
|
|
||||||
|
|
||||||
* The cache consists of many buckets, each with its own lock.
|
|
||||||
This helps scaling the performance on multi-core CPUs, since multiple
|
|
||||||
CPUs may concurrently access distinct buckets.
|
|
||||||
* Each bucket consists of a `hash(key) -> (key, value) position` map
|
|
||||||
and 64KB-sized byte slices (chunks) holding encoded `(key, value)` entries.
|
|
||||||
Each bucket contains only `O(chunksCount)` pointers. For instance, 64GB cache
|
|
||||||
would contain ~1M pointers, while similarly-sized `map[string][]byte`
|
|
||||||
would contain ~1B pointers for short keys and values. This would lead to
|
|
||||||
[huge GC overhead](https://syslog.ravelin.com/further-dangers-of-large-heaps-in-go-7a267b57d487).
|
|
||||||
|
|
||||||
64KB-sized chunks reduce memory fragmentation and the total memory usage comparing
|
|
||||||
to a single big chunk per bucket.
|
|
||||||
Chunks are allocated off-heap if possible. This reduces total memory usage because
|
|
||||||
GC collects unused memory more frequently without the need in `GOGC` tweaking.
|
|
||||||
|
|
||||||
|
|
||||||
### Users
|
|
||||||
|
|
||||||
* `Fastcache` has been extracted from [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) sources.
|
|
||||||
See [this article](https://medium.com/devopslinks/victoriametrics-creating-the-best-remote-storage-for-prometheus-5d92d66787ac)
|
|
||||||
for more info about `VictoriaMetrics`.
|
|
||||||
|
|
||||||
|
|
||||||
### FAQ
|
|
||||||
|
|
||||||
#### What is the difference between `fastcache` and other similar caches like [BigCache](https://github.com/allegro/bigcache) or [FreeCache](https://github.com/coocood/freecache)?
|
|
||||||
|
|
||||||
* `Fastcache` is faster. See benchmark results above.
|
|
||||||
* `Fastcache` uses less memory due to lower heap fragmentation. This allows
|
|
||||||
saving many GBs of memory on multi-GB caches.
|
|
||||||
* `Fastcache` API [is simpler](http://godoc.org/github.com/VictoriaMetrics/fastcache).
|
|
||||||
The API is designed to be used in zero-allocation mode.
|
|
||||||
|
|
||||||
|
|
||||||
#### Why `fastcache` doesn't support cache expiration?
|
|
||||||
|
|
||||||
Because we don't need cache expiration in [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics).
|
|
||||||
Cached entries inside `VictoriaMetrics` never expire. They are automatically evicted on cache size overflow.
|
|
||||||
|
|
||||||
It is easy to implement cache expiration on top of `fastcache` by caching values
|
|
||||||
with marshaled deadlines and verifying deadlines after reading these values
|
|
||||||
from the cache.
|
|
||||||
|
|
||||||
|
|
||||||
#### Why `fastcache` doesn't support advanced features such as [thundering herd protection](https://en.wikipedia.org/wiki/Thundering_herd_problem) or callbacks on entries' eviction?
|
|
||||||
|
|
||||||
Because these features would complicate the code and would make it slower.
|
|
||||||
`Fastcache` source code is simple - just copy-paste it and implement the feature you want
|
|
||||||
on top of it.
|
|
152
vendor/github.com/VictoriaMetrics/fastcache/bigcache.go
generated
vendored
152
vendor/github.com/VictoriaMetrics/fastcache/bigcache.go
generated
vendored
|
@ -1,152 +0,0 @@
|
||||||
package fastcache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
xxhash "github.com/cespare/xxhash/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// maxSubvalueLen is the maximum size of subvalue chunk.
|
|
||||||
//
|
|
||||||
// - 16 bytes are for subkey encoding
|
|
||||||
// - 4 bytes are for len(key)+len(value) encoding inside fastcache
|
|
||||||
// - 1 byte is implementation detail of fastcache
|
|
||||||
const maxSubvalueLen = chunkSize - 16 - 4 - 1
|
|
||||||
|
|
||||||
// maxKeyLen is the maximum size of key.
|
|
||||||
//
|
|
||||||
// - 16 bytes are for (hash + valueLen)
|
|
||||||
// - 4 bytes are for len(key)+len(subkey)
|
|
||||||
// - 1 byte is implementation detail of fastcache
|
|
||||||
const maxKeyLen = chunkSize - 16 - 4 - 1
|
|
||||||
|
|
||||||
// SetBig sets (k, v) to c where len(v) may exceed 64KB.
|
|
||||||
//
|
|
||||||
// GetBig must be used for reading stored values.
|
|
||||||
//
|
|
||||||
// The stored entry may be evicted at any time either due to cache
|
|
||||||
// overflow or due to unlikely hash collision.
|
|
||||||
// Pass higher maxBytes value to New if the added items disappear
|
|
||||||
// frequently.
|
|
||||||
//
|
|
||||||
// It is safe to store entries smaller than 64KB with SetBig.
|
|
||||||
//
|
|
||||||
// k and v contents may be modified after returning from SetBig.
|
|
||||||
func (c *Cache) SetBig(k, v []byte) {
|
|
||||||
atomic.AddUint64(&c.bigStats.SetBigCalls, 1)
|
|
||||||
if len(k) > maxKeyLen {
|
|
||||||
atomic.AddUint64(&c.bigStats.TooBigKeyErrors, 1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
valueLen := len(v)
|
|
||||||
valueHash := xxhash.Sum64(v)
|
|
||||||
|
|
||||||
// Split v into chunks with up to 64Kb each.
|
|
||||||
subkey := getSubkeyBuf()
|
|
||||||
var i uint64
|
|
||||||
for len(v) > 0 {
|
|
||||||
subkey.B = marshalUint64(subkey.B[:0], valueHash)
|
|
||||||
subkey.B = marshalUint64(subkey.B, uint64(i))
|
|
||||||
i++
|
|
||||||
subvalueLen := maxSubvalueLen
|
|
||||||
if len(v) < subvalueLen {
|
|
||||||
subvalueLen = len(v)
|
|
||||||
}
|
|
||||||
subvalue := v[:subvalueLen]
|
|
||||||
v = v[subvalueLen:]
|
|
||||||
c.Set(subkey.B, subvalue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write metavalue, which consists of valueHash and valueLen.
|
|
||||||
subkey.B = marshalUint64(subkey.B[:0], valueHash)
|
|
||||||
subkey.B = marshalUint64(subkey.B, uint64(valueLen))
|
|
||||||
c.Set(k, subkey.B)
|
|
||||||
putSubkeyBuf(subkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBig searches for the value for the given k, appends it to dst
|
|
||||||
// and returns the result.
|
|
||||||
//
|
|
||||||
// GetBig returns only values stored via SetBig. It doesn't work
|
|
||||||
// with values stored via other methods.
|
|
||||||
//
|
|
||||||
// k contents may be modified after returning from GetBig.
|
|
||||||
func (c *Cache) GetBig(dst, k []byte) []byte {
|
|
||||||
atomic.AddUint64(&c.bigStats.GetBigCalls, 1)
|
|
||||||
subkey := getSubkeyBuf()
|
|
||||||
defer putSubkeyBuf(subkey)
|
|
||||||
|
|
||||||
// Read and parse metavalue
|
|
||||||
subkey.B = c.Get(subkey.B[:0], k)
|
|
||||||
if len(subkey.B) == 0 {
|
|
||||||
// Nothing found.
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
if len(subkey.B) != 16 {
|
|
||||||
atomic.AddUint64(&c.bigStats.InvalidMetavalueErrors, 1)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
valueHash := unmarshalUint64(subkey.B)
|
|
||||||
valueLen := unmarshalUint64(subkey.B[8:])
|
|
||||||
|
|
||||||
// Collect result from chunks.
|
|
||||||
dstLen := len(dst)
|
|
||||||
if n := dstLen + int(valueLen) - cap(dst); n > 0 {
|
|
||||||
dst = append(dst[:cap(dst)], make([]byte, n)...)
|
|
||||||
}
|
|
||||||
dst = dst[:dstLen]
|
|
||||||
var i uint64
|
|
||||||
for uint64(len(dst)-dstLen) < valueLen {
|
|
||||||
subkey.B = marshalUint64(subkey.B[:0], valueHash)
|
|
||||||
subkey.B = marshalUint64(subkey.B, uint64(i))
|
|
||||||
i++
|
|
||||||
dstNew := c.Get(dst, subkey.B)
|
|
||||||
if len(dstNew) == len(dst) {
|
|
||||||
// Cannot find subvalue
|
|
||||||
return dst[:dstLen]
|
|
||||||
}
|
|
||||||
dst = dstNew
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the obtained value.
|
|
||||||
v := dst[dstLen:]
|
|
||||||
if uint64(len(v)) != valueLen {
|
|
||||||
atomic.AddUint64(&c.bigStats.InvalidValueLenErrors, 1)
|
|
||||||
return dst[:dstLen]
|
|
||||||
}
|
|
||||||
h := xxhash.Sum64(v)
|
|
||||||
if h != valueHash {
|
|
||||||
atomic.AddUint64(&c.bigStats.InvalidValueHashErrors, 1)
|
|
||||||
return dst[:dstLen]
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSubkeyBuf() *bytesBuf {
|
|
||||||
v := subkeyPool.Get()
|
|
||||||
if v == nil {
|
|
||||||
return &bytesBuf{}
|
|
||||||
}
|
|
||||||
return v.(*bytesBuf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func putSubkeyBuf(bb *bytesBuf) {
|
|
||||||
bb.B = bb.B[:0]
|
|
||||||
subkeyPool.Put(bb)
|
|
||||||
}
|
|
||||||
|
|
||||||
var subkeyPool sync.Pool
|
|
||||||
|
|
||||||
type bytesBuf struct {
|
|
||||||
B []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalUint64(dst []byte, u uint64) []byte {
|
|
||||||
return append(dst, byte(u>>56), byte(u>>48), byte(u>>40), byte(u>>32), byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalUint64(src []byte) uint64 {
|
|
||||||
_ = src[7]
|
|
||||||
return uint64(src[0])<<56 | uint64(src[1])<<48 | uint64(src[2])<<40 | uint64(src[3])<<32 | uint64(src[4])<<24 | uint64(src[5])<<16 | uint64(src[6])<<8 | uint64(src[7])
|
|
||||||
}
|
|
415
vendor/github.com/VictoriaMetrics/fastcache/fastcache.go
generated
vendored
415
vendor/github.com/VictoriaMetrics/fastcache/fastcache.go
generated
vendored
|
@ -1,415 +0,0 @@
|
||||||
// Package fastcache implements fast in-memory cache.
|
|
||||||
//
|
|
||||||
// The package has been extracted from https://victoriametrics.com/
|
|
||||||
package fastcache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
xxhash "github.com/cespare/xxhash/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const bucketsCount = 512
|
|
||||||
|
|
||||||
const chunkSize = 64 * 1024
|
|
||||||
|
|
||||||
const bucketSizeBits = 40
|
|
||||||
|
|
||||||
const genSizeBits = 64 - bucketSizeBits
|
|
||||||
|
|
||||||
const maxGen = 1<<genSizeBits - 1
|
|
||||||
|
|
||||||
const maxBucketSize uint64 = 1 << bucketSizeBits
|
|
||||||
|
|
||||||
// Stats represents cache stats.
|
|
||||||
//
|
|
||||||
// Use Cache.UpdateStats for obtaining fresh stats from the cache.
|
|
||||||
type Stats struct {
|
|
||||||
// GetCalls is the number of Get calls.
|
|
||||||
GetCalls uint64
|
|
||||||
|
|
||||||
// SetCalls is the number of Set calls.
|
|
||||||
SetCalls uint64
|
|
||||||
|
|
||||||
// Misses is the number of cache misses.
|
|
||||||
Misses uint64
|
|
||||||
|
|
||||||
// Collisions is the number of cache collisions.
|
|
||||||
//
|
|
||||||
// Usually the number of collisions must be close to zero.
|
|
||||||
// High number of collisions suggest something wrong with cache.
|
|
||||||
Collisions uint64
|
|
||||||
|
|
||||||
// Corruptions is the number of detected corruptions of the cache.
|
|
||||||
//
|
|
||||||
// Corruptions may occur when corrupted cache is loaded from file.
|
|
||||||
Corruptions uint64
|
|
||||||
|
|
||||||
// EntriesCount is the current number of entries in the cache.
|
|
||||||
EntriesCount uint64
|
|
||||||
|
|
||||||
// BytesSize is the current size of the cache in bytes.
|
|
||||||
BytesSize uint64
|
|
||||||
|
|
||||||
// BigStats contains stats for GetBig/SetBig methods.
|
|
||||||
BigStats
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset resets s, so it may be re-used again in Cache.UpdateStats.
|
|
||||||
func (s *Stats) Reset() {
|
|
||||||
*s = Stats{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BigStats contains stats for GetBig/SetBig methods.
|
|
||||||
type BigStats struct {
|
|
||||||
// GetBigCalls is the number of GetBig calls.
|
|
||||||
GetBigCalls uint64
|
|
||||||
|
|
||||||
// SetBigCalls is the number of SetBig calls.
|
|
||||||
SetBigCalls uint64
|
|
||||||
|
|
||||||
// TooBigKeyErrors is the number of calls to SetBig with too big key.
|
|
||||||
TooBigKeyErrors uint64
|
|
||||||
|
|
||||||
// InvalidMetavalueErrors is the number of calls to GetBig resulting
|
|
||||||
// to invalid metavalue.
|
|
||||||
InvalidMetavalueErrors uint64
|
|
||||||
|
|
||||||
// InvalidValueLenErrors is the number of calls to GetBig resulting
|
|
||||||
// to a chunk with invalid length.
|
|
||||||
InvalidValueLenErrors uint64
|
|
||||||
|
|
||||||
// InvalidValueHashErrors is the number of calls to GetBig resulting
|
|
||||||
// to a chunk with invalid hash value.
|
|
||||||
InvalidValueHashErrors uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bs *BigStats) reset() {
|
|
||||||
atomic.StoreUint64(&bs.GetBigCalls, 0)
|
|
||||||
atomic.StoreUint64(&bs.SetBigCalls, 0)
|
|
||||||
atomic.StoreUint64(&bs.TooBigKeyErrors, 0)
|
|
||||||
atomic.StoreUint64(&bs.InvalidMetavalueErrors, 0)
|
|
||||||
atomic.StoreUint64(&bs.InvalidValueLenErrors, 0)
|
|
||||||
atomic.StoreUint64(&bs.InvalidValueHashErrors, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache is a fast thread-safe inmemory cache optimized for big number
|
|
||||||
// of entries.
|
|
||||||
//
|
|
||||||
// It has much lower impact on GC comparing to a simple `map[string][]byte`.
|
|
||||||
//
|
|
||||||
// Use New or LoadFromFile* for creating new cache instance.
|
|
||||||
// Concurrent goroutines may call any Cache methods on the same cache instance.
|
|
||||||
//
|
|
||||||
// Call Reset when the cache is no longer needed. This reclaims the allocated
|
|
||||||
// memory.
|
|
||||||
type Cache struct {
|
|
||||||
buckets [bucketsCount]bucket
|
|
||||||
|
|
||||||
bigStats BigStats
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns new cache with the given maxBytes capacity in bytes.
|
|
||||||
//
|
|
||||||
// maxBytes must be smaller than the available RAM size for the app,
|
|
||||||
// since the cache holds data in memory.
|
|
||||||
//
|
|
||||||
// If maxBytes is less than 32MB, then the minimum cache capacity is 32MB.
|
|
||||||
func New(maxBytes int) *Cache {
|
|
||||||
if maxBytes <= 0 {
|
|
||||||
panic(fmt.Errorf("maxBytes must be greater than 0; got %d", maxBytes))
|
|
||||||
}
|
|
||||||
var c Cache
|
|
||||||
maxBucketBytes := uint64((maxBytes + bucketsCount - 1) / bucketsCount)
|
|
||||||
for i := range c.buckets[:] {
|
|
||||||
c.buckets[i].Init(maxBucketBytes)
|
|
||||||
}
|
|
||||||
return &c
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set stores (k, v) in the cache.
|
|
||||||
//
|
|
||||||
// Get must be used for reading the stored entry.
|
|
||||||
//
|
|
||||||
// The stored entry may be evicted at any time either due to cache
|
|
||||||
// overflow or due to unlikely hash collision.
|
|
||||||
// Pass higher maxBytes value to New if the added items disappear
|
|
||||||
// frequently.
|
|
||||||
//
|
|
||||||
// (k, v) entries with summary size exceeding 64KB aren't stored in the cache.
|
|
||||||
// SetBig can be used for storing entries exceeding 64KB.
|
|
||||||
//
|
|
||||||
// k and v contents may be modified after returning from Set.
|
|
||||||
func (c *Cache) Set(k, v []byte) {
|
|
||||||
h := xxhash.Sum64(k)
|
|
||||||
idx := h % bucketsCount
|
|
||||||
c.buckets[idx].Set(k, v, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get appends value by the key k to dst and returns the result.
|
|
||||||
//
|
|
||||||
// Get allocates new byte slice for the returned value if dst is nil.
|
|
||||||
//
|
|
||||||
// Get returns only values stored in c via Set.
|
|
||||||
//
|
|
||||||
// k contents may be modified after returning from Get.
|
|
||||||
func (c *Cache) Get(dst, k []byte) []byte {
|
|
||||||
h := xxhash.Sum64(k)
|
|
||||||
idx := h % bucketsCount
|
|
||||||
dst, _ = c.buckets[idx].Get(dst, k, h, true)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasGet works identically to Get, but also returns whether the given key
|
|
||||||
// exists in the cache. This method makes it possible to differentiate between a
|
|
||||||
// stored nil/empty value versus and non-existing value.
|
|
||||||
func (c *Cache) HasGet(dst, k []byte) ([]byte, bool) {
|
|
||||||
h := xxhash.Sum64(k)
|
|
||||||
idx := h % bucketsCount
|
|
||||||
return c.buckets[idx].Get(dst, k, h, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has returns true if entry for the given key k exists in the cache.
|
|
||||||
func (c *Cache) Has(k []byte) bool {
|
|
||||||
h := xxhash.Sum64(k)
|
|
||||||
idx := h % bucketsCount
|
|
||||||
_, ok := c.buckets[idx].Get(nil, k, h, false)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Del deletes value for the given k from the cache.
|
|
||||||
//
|
|
||||||
// k contents may be modified after returning from Del.
|
|
||||||
func (c *Cache) Del(k []byte) {
|
|
||||||
h := xxhash.Sum64(k)
|
|
||||||
idx := h % bucketsCount
|
|
||||||
c.buckets[idx].Del(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset removes all the items from the cache.
|
|
||||||
func (c *Cache) Reset() {
|
|
||||||
for i := range c.buckets[:] {
|
|
||||||
c.buckets[i].Reset()
|
|
||||||
}
|
|
||||||
c.bigStats.reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateStats adds cache stats to s.
|
|
||||||
//
|
|
||||||
// Call s.Reset before calling UpdateStats if s is re-used.
|
|
||||||
func (c *Cache) UpdateStats(s *Stats) {
|
|
||||||
for i := range c.buckets[:] {
|
|
||||||
c.buckets[i].UpdateStats(s)
|
|
||||||
}
|
|
||||||
s.GetBigCalls += atomic.LoadUint64(&c.bigStats.GetBigCalls)
|
|
||||||
s.SetBigCalls += atomic.LoadUint64(&c.bigStats.SetBigCalls)
|
|
||||||
s.TooBigKeyErrors += atomic.LoadUint64(&c.bigStats.TooBigKeyErrors)
|
|
||||||
s.InvalidMetavalueErrors += atomic.LoadUint64(&c.bigStats.InvalidMetavalueErrors)
|
|
||||||
s.InvalidValueLenErrors += atomic.LoadUint64(&c.bigStats.InvalidValueLenErrors)
|
|
||||||
s.InvalidValueHashErrors += atomic.LoadUint64(&c.bigStats.InvalidValueHashErrors)
|
|
||||||
}
|
|
||||||
|
|
||||||
type bucket struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
|
|
||||||
// chunks is a ring buffer with encoded (k, v) pairs.
|
|
||||||
// It consists of 64KB chunks.
|
|
||||||
chunks [][]byte
|
|
||||||
|
|
||||||
// m maps hash(k) to idx of (k, v) pair in chunks.
|
|
||||||
m map[uint64]uint64
|
|
||||||
|
|
||||||
// idx points to chunks for writing the next (k, v) pair.
|
|
||||||
idx uint64
|
|
||||||
|
|
||||||
// gen is the generation of chunks.
|
|
||||||
gen uint64
|
|
||||||
|
|
||||||
getCalls uint64
|
|
||||||
setCalls uint64
|
|
||||||
misses uint64
|
|
||||||
collisions uint64
|
|
||||||
corruptions uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Init(maxBytes uint64) {
|
|
||||||
if maxBytes == 0 {
|
|
||||||
panic(fmt.Errorf("maxBytes cannot be zero"))
|
|
||||||
}
|
|
||||||
if maxBytes >= maxBucketSize {
|
|
||||||
panic(fmt.Errorf("too big maxBytes=%d; should be smaller than %d", maxBytes, maxBucketSize))
|
|
||||||
}
|
|
||||||
maxChunks := (maxBytes + chunkSize - 1) / chunkSize
|
|
||||||
b.chunks = make([][]byte, maxChunks)
|
|
||||||
b.m = make(map[uint64]uint64)
|
|
||||||
b.Reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Reset() {
|
|
||||||
b.mu.Lock()
|
|
||||||
chunks := b.chunks
|
|
||||||
for i := range chunks {
|
|
||||||
putChunk(chunks[i])
|
|
||||||
chunks[i] = nil
|
|
||||||
}
|
|
||||||
bm := b.m
|
|
||||||
for k := range bm {
|
|
||||||
delete(bm, k)
|
|
||||||
}
|
|
||||||
b.idx = 0
|
|
||||||
b.gen = 1
|
|
||||||
atomic.StoreUint64(&b.getCalls, 0)
|
|
||||||
atomic.StoreUint64(&b.setCalls, 0)
|
|
||||||
atomic.StoreUint64(&b.misses, 0)
|
|
||||||
atomic.StoreUint64(&b.collisions, 0)
|
|
||||||
atomic.StoreUint64(&b.corruptions, 0)
|
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Clean() {
|
|
||||||
b.mu.Lock()
|
|
||||||
bGen := b.gen & ((1 << genSizeBits) - 1)
|
|
||||||
bIdx := b.idx
|
|
||||||
bm := b.m
|
|
||||||
for k, v := range bm {
|
|
||||||
gen := v >> bucketSizeBits
|
|
||||||
idx := v & ((1 << bucketSizeBits) - 1)
|
|
||||||
if gen == bGen && idx < bIdx || gen+1 == bGen && idx >= bIdx || gen == maxGen && bGen == 1 && idx >= bIdx {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
delete(bm, k)
|
|
||||||
}
|
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) UpdateStats(s *Stats) {
|
|
||||||
s.GetCalls += atomic.LoadUint64(&b.getCalls)
|
|
||||||
s.SetCalls += atomic.LoadUint64(&b.setCalls)
|
|
||||||
s.Misses += atomic.LoadUint64(&b.misses)
|
|
||||||
s.Collisions += atomic.LoadUint64(&b.collisions)
|
|
||||||
s.Corruptions += atomic.LoadUint64(&b.corruptions)
|
|
||||||
|
|
||||||
b.mu.RLock()
|
|
||||||
s.EntriesCount += uint64(len(b.m))
|
|
||||||
for _, chunk := range b.chunks {
|
|
||||||
s.BytesSize += uint64(cap(chunk))
|
|
||||||
}
|
|
||||||
b.mu.RUnlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Set(k, v []byte, h uint64) {
|
|
||||||
setCalls := atomic.AddUint64(&b.setCalls, 1)
|
|
||||||
if setCalls%(1<<14) == 0 {
|
|
||||||
b.Clean()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(k) >= (1<<16) || len(v) >= (1<<16) {
|
|
||||||
// Too big key or value - its length cannot be encoded
|
|
||||||
// with 2 bytes (see below). Skip the entry.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var kvLenBuf [4]byte
|
|
||||||
kvLenBuf[0] = byte(uint16(len(k)) >> 8)
|
|
||||||
kvLenBuf[1] = byte(len(k))
|
|
||||||
kvLenBuf[2] = byte(uint16(len(v)) >> 8)
|
|
||||||
kvLenBuf[3] = byte(len(v))
|
|
||||||
kvLen := uint64(len(kvLenBuf) + len(k) + len(v))
|
|
||||||
if kvLen >= chunkSize {
|
|
||||||
// Do not store too big keys and values, since they do not
|
|
||||||
// fit a chunk.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b.mu.Lock()
|
|
||||||
idx := b.idx
|
|
||||||
idxNew := idx + kvLen
|
|
||||||
chunkIdx := idx / chunkSize
|
|
||||||
chunkIdxNew := idxNew / chunkSize
|
|
||||||
if chunkIdxNew > chunkIdx {
|
|
||||||
if chunkIdxNew >= uint64(len(b.chunks)) {
|
|
||||||
idx = 0
|
|
||||||
idxNew = kvLen
|
|
||||||
chunkIdx = 0
|
|
||||||
b.gen++
|
|
||||||
if b.gen&((1<<genSizeBits)-1) == 0 {
|
|
||||||
b.gen++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
idx = chunkIdxNew * chunkSize
|
|
||||||
idxNew = idx + kvLen
|
|
||||||
chunkIdx = chunkIdxNew
|
|
||||||
}
|
|
||||||
b.chunks[chunkIdx] = b.chunks[chunkIdx][:0]
|
|
||||||
}
|
|
||||||
chunk := b.chunks[chunkIdx]
|
|
||||||
if chunk == nil {
|
|
||||||
chunk = getChunk()
|
|
||||||
chunk = chunk[:0]
|
|
||||||
}
|
|
||||||
chunk = append(chunk, kvLenBuf[:]...)
|
|
||||||
chunk = append(chunk, k...)
|
|
||||||
chunk = append(chunk, v...)
|
|
||||||
b.chunks[chunkIdx] = chunk
|
|
||||||
b.m[h] = idx | (b.gen << bucketSizeBits)
|
|
||||||
b.idx = idxNew
|
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Get(dst, k []byte, h uint64, returnDst bool) ([]byte, bool) {
|
|
||||||
atomic.AddUint64(&b.getCalls, 1)
|
|
||||||
found := false
|
|
||||||
b.mu.RLock()
|
|
||||||
v := b.m[h]
|
|
||||||
bGen := b.gen & ((1 << genSizeBits) - 1)
|
|
||||||
if v > 0 {
|
|
||||||
gen := v >> bucketSizeBits
|
|
||||||
idx := v & ((1 << bucketSizeBits) - 1)
|
|
||||||
if gen == bGen && idx < b.idx || gen+1 == bGen && idx >= b.idx || gen == maxGen && bGen == 1 && idx >= b.idx {
|
|
||||||
chunkIdx := idx / chunkSize
|
|
||||||
if chunkIdx >= uint64(len(b.chunks)) {
|
|
||||||
// Corrupted data during the load from file. Just skip it.
|
|
||||||
atomic.AddUint64(&b.corruptions, 1)
|
|
||||||
goto end
|
|
||||||
}
|
|
||||||
chunk := b.chunks[chunkIdx]
|
|
||||||
idx %= chunkSize
|
|
||||||
if idx+4 >= chunkSize {
|
|
||||||
// Corrupted data during the load from file. Just skip it.
|
|
||||||
atomic.AddUint64(&b.corruptions, 1)
|
|
||||||
goto end
|
|
||||||
}
|
|
||||||
kvLenBuf := chunk[idx : idx+4]
|
|
||||||
keyLen := (uint64(kvLenBuf[0]) << 8) | uint64(kvLenBuf[1])
|
|
||||||
valLen := (uint64(kvLenBuf[2]) << 8) | uint64(kvLenBuf[3])
|
|
||||||
idx += 4
|
|
||||||
if idx+keyLen+valLen >= chunkSize {
|
|
||||||
// Corrupted data during the load from file. Just skip it.
|
|
||||||
atomic.AddUint64(&b.corruptions, 1)
|
|
||||||
goto end
|
|
||||||
}
|
|
||||||
if string(k) == string(chunk[idx:idx+keyLen]) {
|
|
||||||
idx += keyLen
|
|
||||||
if returnDst {
|
|
||||||
dst = append(dst, chunk[idx:idx+valLen]...)
|
|
||||||
}
|
|
||||||
found = true
|
|
||||||
} else {
|
|
||||||
atomic.AddUint64(&b.collisions, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
b.mu.RUnlock()
|
|
||||||
if !found {
|
|
||||||
atomic.AddUint64(&b.misses, 1)
|
|
||||||
}
|
|
||||||
return dst, found
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Del(h uint64) {
|
|
||||||
b.mu.Lock()
|
|
||||||
delete(b.m, h)
|
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
|
419
vendor/github.com/VictoriaMetrics/fastcache/file.go
generated
vendored
419
vendor/github.com/VictoriaMetrics/fastcache/file.go
generated
vendored
|
@ -1,419 +0,0 @@
|
||||||
package fastcache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/golang/snappy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SaveToFile atomically saves cache data to the given filePath using a single
|
|
||||||
// CPU core.
|
|
||||||
//
|
|
||||||
// SaveToFile may be called concurrently with other operations on the cache.
|
|
||||||
//
|
|
||||||
// The saved data may be loaded with LoadFromFile*.
|
|
||||||
//
|
|
||||||
// See also SaveToFileConcurrent for faster saving to file.
|
|
||||||
func (c *Cache) SaveToFile(filePath string) error {
|
|
||||||
return c.SaveToFileConcurrent(filePath, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveToFileConcurrent saves cache data to the given filePath using concurrency
|
|
||||||
// CPU cores.
|
|
||||||
//
|
|
||||||
// SaveToFileConcurrent may be called concurrently with other operations
|
|
||||||
// on the cache.
|
|
||||||
//
|
|
||||||
// The saved data may be loaded with LoadFromFile*.
|
|
||||||
//
|
|
||||||
// See also SaveToFile.
|
|
||||||
func (c *Cache) SaveToFileConcurrent(filePath string, concurrency int) error {
|
|
||||||
// Create dir if it doesn't exist.
|
|
||||||
dir := filepath.Dir(filePath)
|
|
||||||
if _, err := os.Stat(dir); err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return fmt.Errorf("cannot stat %q: %s", dir, err)
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
||||||
return fmt.Errorf("cannot create dir %q: %s", dir, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save cache data into a temporary directory.
|
|
||||||
tmpDir, err := ioutil.TempDir(dir, "fastcache.tmp.")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot create temporary dir inside %q: %s", dir, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if tmpDir != "" {
|
|
||||||
_ = os.RemoveAll(tmpDir)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
gomaxprocs := runtime.GOMAXPROCS(-1)
|
|
||||||
if concurrency <= 0 || concurrency > gomaxprocs {
|
|
||||||
concurrency = gomaxprocs
|
|
||||||
}
|
|
||||||
if err := c.save(tmpDir, concurrency); err != nil {
|
|
||||||
return fmt.Errorf("cannot save cache data to temporary dir %q: %s", tmpDir, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove old filePath contents, since os.Rename may return
|
|
||||||
// error if filePath dir exists.
|
|
||||||
if err := os.RemoveAll(filePath); err != nil {
|
|
||||||
return fmt.Errorf("cannot remove old contents at %q: %s", filePath, err)
|
|
||||||
}
|
|
||||||
if err := os.Rename(tmpDir, filePath); err != nil {
|
|
||||||
return fmt.Errorf("cannot move temporary dir %q to %q: %s", tmpDir, filePath, err)
|
|
||||||
}
|
|
||||||
tmpDir = ""
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadFromFile loads cache data from the given filePath.
|
|
||||||
//
|
|
||||||
// See SaveToFile* for saving cache data to file.
|
|
||||||
func LoadFromFile(filePath string) (*Cache, error) {
|
|
||||||
return load(filePath, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadFromFileOrNew tries loading cache data from the given filePath.
|
|
||||||
//
|
|
||||||
// The function falls back to creating new cache with the given maxBytes
|
|
||||||
// capacity if error occurs during loading the cache from file.
|
|
||||||
func LoadFromFileOrNew(filePath string, maxBytes int) *Cache {
|
|
||||||
c, err := load(filePath, maxBytes)
|
|
||||||
if err == nil {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
return New(maxBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Cache) save(dir string, workersCount int) error {
|
|
||||||
if err := saveMetadata(c, dir); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save buckets by workersCount concurrent workers.
|
|
||||||
workCh := make(chan int, workersCount)
|
|
||||||
results := make(chan error)
|
|
||||||
for i := 0; i < workersCount; i++ {
|
|
||||||
go func(workerNum int) {
|
|
||||||
results <- saveBuckets(c.buckets[:], workCh, dir, workerNum)
|
|
||||||
}(i)
|
|
||||||
}
|
|
||||||
// Feed workers with work
|
|
||||||
for i := range c.buckets[:] {
|
|
||||||
workCh <- i
|
|
||||||
}
|
|
||||||
close(workCh)
|
|
||||||
|
|
||||||
// Read results.
|
|
||||||
var err error
|
|
||||||
for i := 0; i < workersCount; i++ {
|
|
||||||
result := <-results
|
|
||||||
if result != nil && err == nil {
|
|
||||||
err = result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func load(filePath string, maxBytes int) (*Cache, error) {
|
|
||||||
maxBucketChunks, err := loadMetadata(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if maxBytes > 0 {
|
|
||||||
maxBucketBytes := uint64((maxBytes + bucketsCount - 1) / bucketsCount)
|
|
||||||
expectedBucketChunks := (maxBucketBytes + chunkSize - 1) / chunkSize
|
|
||||||
if maxBucketChunks != expectedBucketChunks {
|
|
||||||
return nil, fmt.Errorf("cache file %s contains maxBytes=%d; want %d", filePath, maxBytes, expectedBucketChunks*chunkSize*bucketsCount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read bucket files from filePath dir.
|
|
||||||
d, err := os.Open(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot open %q: %s", filePath, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = d.Close()
|
|
||||||
}()
|
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot read files from %q: %s", filePath, err)
|
|
||||||
}
|
|
||||||
results := make(chan error)
|
|
||||||
workersCount := 0
|
|
||||||
var c Cache
|
|
||||||
for _, fi := range fis {
|
|
||||||
fn := fi.Name()
|
|
||||||
if fi.IsDir() || !dataFileRegexp.MatchString(fn) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
workersCount++
|
|
||||||
go func(dataPath string) {
|
|
||||||
results <- loadBuckets(c.buckets[:], dataPath, maxBucketChunks)
|
|
||||||
}(filePath + "/" + fn)
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
for i := 0; i < workersCount; i++ {
|
|
||||||
result := <-results
|
|
||||||
if result != nil && err == nil {
|
|
||||||
err = result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Initialize buckets, which could be missing due to incomplete or corrupted files in the cache.
|
|
||||||
// It is better initializing such buckets instead of returning error, since the rest of buckets
|
|
||||||
// contain valid data.
|
|
||||||
for i := range c.buckets[:] {
|
|
||||||
b := &c.buckets[i]
|
|
||||||
if len(b.chunks) == 0 {
|
|
||||||
b.chunks = make([][]byte, maxBucketChunks)
|
|
||||||
b.m = make(map[uint64]uint64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveMetadata(c *Cache, dir string) error {
|
|
||||||
metadataPath := dir + "/metadata.bin"
|
|
||||||
metadataFile, err := os.Create(metadataPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot create %q: %s", metadataPath, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = metadataFile.Close()
|
|
||||||
}()
|
|
||||||
maxBucketChunks := uint64(cap(c.buckets[0].chunks))
|
|
||||||
if err := writeUint64(metadataFile, maxBucketChunks); err != nil {
|
|
||||||
return fmt.Errorf("cannot write maxBucketChunks=%d to %q: %s", maxBucketChunks, metadataPath, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadMetadata(dir string) (uint64, error) {
|
|
||||||
metadataPath := dir + "/metadata.bin"
|
|
||||||
metadataFile, err := os.Open(metadataPath)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("cannot open %q: %s", metadataPath, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = metadataFile.Close()
|
|
||||||
}()
|
|
||||||
maxBucketChunks, err := readUint64(metadataFile)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("cannot read maxBucketChunks from %q: %s", metadataPath, err)
|
|
||||||
}
|
|
||||||
if maxBucketChunks == 0 {
|
|
||||||
return 0, fmt.Errorf("invalid maxBucketChunks=0 read from %q", metadataPath)
|
|
||||||
}
|
|
||||||
return maxBucketChunks, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var dataFileRegexp = regexp.MustCompile(`^data\.\d+\.bin$`)
|
|
||||||
|
|
||||||
func saveBuckets(buckets []bucket, workCh <-chan int, dir string, workerNum int) error {
|
|
||||||
dataPath := fmt.Sprintf("%s/data.%d.bin", dir, workerNum)
|
|
||||||
dataFile, err := os.Create(dataPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot create %q: %s", dataPath, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = dataFile.Close()
|
|
||||||
}()
|
|
||||||
zw := snappy.NewBufferedWriter(dataFile)
|
|
||||||
for bucketNum := range workCh {
|
|
||||||
if err := writeUint64(zw, uint64(bucketNum)); err != nil {
|
|
||||||
return fmt.Errorf("cannot write bucketNum=%d to %q: %s", bucketNum, dataPath, err)
|
|
||||||
}
|
|
||||||
if err := buckets[bucketNum].Save(zw); err != nil {
|
|
||||||
return fmt.Errorf("cannot save bucket[%d] to %q: %s", bucketNum, dataPath, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := zw.Close(); err != nil {
|
|
||||||
return fmt.Errorf("cannot close snappy.Writer for %q: %s", dataPath, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadBuckets(buckets []bucket, dataPath string, maxChunks uint64) error {
|
|
||||||
dataFile, err := os.Open(dataPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot open %q: %s", dataPath, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = dataFile.Close()
|
|
||||||
}()
|
|
||||||
zr := snappy.NewReader(dataFile)
|
|
||||||
for {
|
|
||||||
bucketNum, err := readUint64(zr)
|
|
||||||
if err == io.EOF {
|
|
||||||
// Reached the end of file.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if bucketNum >= uint64(len(buckets)) {
|
|
||||||
return fmt.Errorf("unexpected bucketNum read from %q: %d; must be smaller than %d", dataPath, bucketNum, len(buckets))
|
|
||||||
}
|
|
||||||
if err := buckets[bucketNum].Load(zr, maxChunks); err != nil {
|
|
||||||
return fmt.Errorf("cannot load bucket[%d] from %q: %s", bucketNum, dataPath, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Save(w io.Writer) error {
|
|
||||||
b.Clean()
|
|
||||||
|
|
||||||
b.mu.RLock()
|
|
||||||
defer b.mu.RUnlock()
|
|
||||||
|
|
||||||
// Store b.idx, b.gen and b.m to w.
|
|
||||||
|
|
||||||
bIdx := b.idx
|
|
||||||
bGen := b.gen
|
|
||||||
chunksLen := 0
|
|
||||||
for _, chunk := range b.chunks {
|
|
||||||
if chunk == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
chunksLen++
|
|
||||||
}
|
|
||||||
kvs := make([]byte, 0, 2*8*len(b.m))
|
|
||||||
var u64Buf [8]byte
|
|
||||||
for k, v := range b.m {
|
|
||||||
binary.LittleEndian.PutUint64(u64Buf[:], k)
|
|
||||||
kvs = append(kvs, u64Buf[:]...)
|
|
||||||
binary.LittleEndian.PutUint64(u64Buf[:], v)
|
|
||||||
kvs = append(kvs, u64Buf[:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := writeUint64(w, bIdx); err != nil {
|
|
||||||
return fmt.Errorf("cannot write b.idx: %s", err)
|
|
||||||
}
|
|
||||||
if err := writeUint64(w, bGen); err != nil {
|
|
||||||
return fmt.Errorf("cannot write b.gen: %s", err)
|
|
||||||
}
|
|
||||||
if err := writeUint64(w, uint64(len(kvs))/2/8); err != nil {
|
|
||||||
return fmt.Errorf("cannot write len(b.m): %s", err)
|
|
||||||
}
|
|
||||||
if _, err := w.Write(kvs); err != nil {
|
|
||||||
return fmt.Errorf("cannot write b.m: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store b.chunks to w.
|
|
||||||
if err := writeUint64(w, uint64(chunksLen)); err != nil {
|
|
||||||
return fmt.Errorf("cannot write len(b.chunks): %s", err)
|
|
||||||
}
|
|
||||||
for chunkIdx := 0; chunkIdx < chunksLen; chunkIdx++ {
|
|
||||||
chunk := b.chunks[chunkIdx][:chunkSize]
|
|
||||||
if _, err := w.Write(chunk); err != nil {
|
|
||||||
return fmt.Errorf("cannot write b.chunks[%d]: %s", chunkIdx, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket) Load(r io.Reader, maxChunks uint64) error {
|
|
||||||
if maxChunks == 0 {
|
|
||||||
return fmt.Errorf("the number of chunks per bucket cannot be zero")
|
|
||||||
}
|
|
||||||
bIdx, err := readUint64(r)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read b.idx: %s", err)
|
|
||||||
}
|
|
||||||
bGen, err := readUint64(r)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read b.gen: %s", err)
|
|
||||||
}
|
|
||||||
kvsLen, err := readUint64(r)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read len(b.m): %s", err)
|
|
||||||
}
|
|
||||||
kvsLen *= 2 * 8
|
|
||||||
kvs := make([]byte, kvsLen)
|
|
||||||
if _, err := io.ReadFull(r, kvs); err != nil {
|
|
||||||
return fmt.Errorf("cannot read b.m: %s", err)
|
|
||||||
}
|
|
||||||
m := make(map[uint64]uint64, kvsLen/2/8)
|
|
||||||
for len(kvs) > 0 {
|
|
||||||
k := binary.LittleEndian.Uint64(kvs)
|
|
||||||
kvs = kvs[8:]
|
|
||||||
v := binary.LittleEndian.Uint64(kvs)
|
|
||||||
kvs = kvs[8:]
|
|
||||||
m[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
maxBytes := maxChunks * chunkSize
|
|
||||||
if maxBytes >= maxBucketSize {
|
|
||||||
return fmt.Errorf("too big maxBytes=%d; should be smaller than %d", maxBytes, maxBucketSize)
|
|
||||||
}
|
|
||||||
chunks := make([][]byte, maxChunks)
|
|
||||||
chunksLen, err := readUint64(r)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read len(b.chunks): %s", err)
|
|
||||||
}
|
|
||||||
if chunksLen > uint64(maxChunks) {
|
|
||||||
return fmt.Errorf("chunksLen=%d cannot exceed maxChunks=%d", chunksLen, maxChunks)
|
|
||||||
}
|
|
||||||
currChunkIdx := bIdx / chunkSize
|
|
||||||
if currChunkIdx > 0 && currChunkIdx >= chunksLen {
|
|
||||||
return fmt.Errorf("too big bIdx=%d; should be smaller than %d", bIdx, chunksLen*chunkSize)
|
|
||||||
}
|
|
||||||
for chunkIdx := uint64(0); chunkIdx < chunksLen; chunkIdx++ {
|
|
||||||
chunk := getChunk()
|
|
||||||
chunks[chunkIdx] = chunk
|
|
||||||
if _, err := io.ReadFull(r, chunk); err != nil {
|
|
||||||
// Free up allocated chunks before returning the error.
|
|
||||||
for _, chunk := range chunks {
|
|
||||||
if chunk != nil {
|
|
||||||
putChunk(chunk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot read b.chunks[%d]: %s", chunkIdx, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Adjust len for the chunk pointed by currChunkIdx.
|
|
||||||
if chunksLen > 0 {
|
|
||||||
chunkLen := bIdx % chunkSize
|
|
||||||
chunks[currChunkIdx] = chunks[currChunkIdx][:chunkLen]
|
|
||||||
}
|
|
||||||
|
|
||||||
b.mu.Lock()
|
|
||||||
for _, chunk := range b.chunks {
|
|
||||||
putChunk(chunk)
|
|
||||||
}
|
|
||||||
b.chunks = chunks
|
|
||||||
b.m = m
|
|
||||||
b.idx = bIdx
|
|
||||||
b.gen = bGen
|
|
||||||
b.mu.Unlock()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeUint64(w io.Writer, u uint64) error {
|
|
||||||
var u64Buf [8]byte
|
|
||||||
binary.LittleEndian.PutUint64(u64Buf[:], u)
|
|
||||||
_, err := w.Write(u64Buf[:])
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func readUint64(r io.Reader) (uint64, error) {
|
|
||||||
var u64Buf [8]byte
|
|
||||||
if _, err := io.ReadFull(r, u64Buf[:]); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
u := binary.LittleEndian.Uint64(u64Buf[:])
|
|
||||||
return u, nil
|
|
||||||
}
|
|
9
vendor/github.com/VictoriaMetrics/fastcache/go.mod
generated
vendored
9
vendor/github.com/VictoriaMetrics/fastcache/go.mod
generated
vendored
|
@ -1,9 +0,0 @@
|
||||||
module github.com/VictoriaMetrics/fastcache
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/golang/snappy v0.0.1
|
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
|
||||||
)
|
|
14
vendor/github.com/VictoriaMetrics/fastcache/go.sum
generated
vendored
14
vendor/github.com/VictoriaMetrics/fastcache/go.sum
generated
vendored
|
@ -1,14 +0,0 @@
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
|
||||||
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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
11
vendor/github.com/VictoriaMetrics/fastcache/malloc_heap.go
generated
vendored
11
vendor/github.com/VictoriaMetrics/fastcache/malloc_heap.go
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
// +build appengine windows
|
|
||||||
|
|
||||||
package fastcache
|
|
||||||
|
|
||||||
func getChunk() []byte {
|
|
||||||
return make([]byte, chunkSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
func putChunk(chunk []byte) {
|
|
||||||
// No-op.
|
|
||||||
}
|
|
52
vendor/github.com/VictoriaMetrics/fastcache/malloc_mmap.go
generated
vendored
52
vendor/github.com/VictoriaMetrics/fastcache/malloc_mmap.go
generated
vendored
|
@ -1,52 +0,0 @@
|
||||||
// +build !appengine,!windows
|
|
||||||
|
|
||||||
package fastcache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const chunksPerAlloc = 1024
|
|
||||||
|
|
||||||
var (
|
|
||||||
freeChunks []*[chunkSize]byte
|
|
||||||
freeChunksLock sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
func getChunk() []byte {
|
|
||||||
freeChunksLock.Lock()
|
|
||||||
if len(freeChunks) == 0 {
|
|
||||||
// Allocate offheap memory, so GOGC won't take into account cache size.
|
|
||||||
// This should reduce free memory waste.
|
|
||||||
data, err := syscall.Mmap(-1, 0, chunkSize*chunksPerAlloc, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("cannot allocate %d bytes via mmap: %s", chunkSize*chunksPerAlloc, err))
|
|
||||||
}
|
|
||||||
for len(data) > 0 {
|
|
||||||
p := (*[chunkSize]byte)(unsafe.Pointer(&data[0]))
|
|
||||||
freeChunks = append(freeChunks, p)
|
|
||||||
data = data[chunkSize:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n := len(freeChunks) - 1
|
|
||||||
p := freeChunks[n]
|
|
||||||
freeChunks[n] = nil
|
|
||||||
freeChunks = freeChunks[:n]
|
|
||||||
freeChunksLock.Unlock()
|
|
||||||
return p[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func putChunk(chunk []byte) {
|
|
||||||
if chunk == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
chunk = chunk[:chunkSize]
|
|
||||||
p := (*[chunkSize]byte)(unsafe.Pointer(&chunk[0]))
|
|
||||||
|
|
||||||
freeChunksLock.Lock()
|
|
||||||
freeChunks = append(freeChunks, p)
|
|
||||||
freeChunksLock.Unlock()
|
|
||||||
}
|
|
3
vendor/github.com/VictoriaMetrics/fasthttp/.gitignore
generated
vendored
3
vendor/github.com/VictoriaMetrics/fasthttp/.gitignore
generated
vendored
|
@ -1,3 +0,0 @@
|
||||||
tags
|
|
||||||
*.pprof
|
|
||||||
*.fasthttp.gz
|
|
16
vendor/github.com/VictoriaMetrics/fasthttp/.travis.yml
generated
vendored
16
vendor/github.com/VictoriaMetrics/fasthttp/.travis.yml
generated
vendored
|
@ -1,16 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.9.x
|
|
||||||
- 1.8.x
|
|
||||||
|
|
||||||
script:
|
|
||||||
# build test for supported platforms
|
|
||||||
- GOOS=linux go build
|
|
||||||
- GOOS=darwin go build
|
|
||||||
- GOOS=freebsd go build
|
|
||||||
- GOOS=windows go build
|
|
||||||
- GOARCH=386 go build
|
|
||||||
|
|
||||||
# run tests on a standard platform
|
|
||||||
- go test -v ./...
|
|
22
vendor/github.com/VictoriaMetrics/fasthttp/LICENSE
generated
vendored
22
vendor/github.com/VictoriaMetrics/fasthttp/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2015-2016 Aliaksandr Valialkin, VertaMedia
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
5
vendor/github.com/VictoriaMetrics/fasthttp/README.md
generated
vendored
5
vendor/github.com/VictoriaMetrics/fasthttp/README.md
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
Private copy of [fasthttp](https://github.com/valyala/fasthttp) for VictoriaMetrics usage.
|
|
||||||
|
|
||||||
It contains only the functionality required for [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics).
|
|
||||||
|
|
||||||
Do not use it in your own projects!
|
|
4
vendor/github.com/VictoriaMetrics/fasthttp/TODO
generated
vendored
4
vendor/github.com/VictoriaMetrics/fasthttp/TODO
generated
vendored
|
@ -1,4 +0,0 @@
|
||||||
- SessionClient with referer and cookies support.
|
|
||||||
- ProxyHandler similar to FSHandler.
|
|
||||||
- WebSockets. See https://tools.ietf.org/html/rfc6455 .
|
|
||||||
- HTTP/2.0. See https://tools.ietf.org/html/rfc7540 .
|
|
517
vendor/github.com/VictoriaMetrics/fasthttp/args.go
generated
vendored
517
vendor/github.com/VictoriaMetrics/fasthttp/args.go
generated
vendored
|
@ -1,517 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AcquireArgs returns an empty Args object from the pool.
|
|
||||||
//
|
|
||||||
// The returned Args may be returned to the pool with ReleaseArgs
|
|
||||||
// when no longer needed. This allows reducing GC load.
|
|
||||||
func AcquireArgs() *Args {
|
|
||||||
return argsPool.Get().(*Args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReleaseArgs returns the object acquired via AquireArgs to the pool.
|
|
||||||
//
|
|
||||||
// Do not access the released Args object, otherwise data races may occur.
|
|
||||||
func ReleaseArgs(a *Args) {
|
|
||||||
a.Reset()
|
|
||||||
argsPool.Put(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
var argsPool = &sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return &Args{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Args represents query arguments.
|
|
||||||
//
|
|
||||||
// It is forbidden copying Args instances. Create new instances instead
|
|
||||||
// and use CopyTo().
|
|
||||||
//
|
|
||||||
// Args instance MUST NOT be used from concurrently running goroutines.
|
|
||||||
type Args struct {
|
|
||||||
noCopy noCopy
|
|
||||||
|
|
||||||
args []argsKV
|
|
||||||
buf []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type argsKV struct {
|
|
||||||
key []byte
|
|
||||||
value []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset clears query args.
|
|
||||||
func (a *Args) Reset() {
|
|
||||||
a.args = a.args[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyTo copies all args to dst.
|
|
||||||
func (a *Args) CopyTo(dst *Args) {
|
|
||||||
dst.Reset()
|
|
||||||
dst.args = copyArgs(dst.args, a.args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitAll calls f for each existing arg.
|
|
||||||
//
|
|
||||||
// f must not retain references to key and value after returning.
|
|
||||||
// Make key and/or value copies if you need storing them after returning.
|
|
||||||
func (a *Args) VisitAll(f func(key, value []byte)) {
|
|
||||||
visitArgs(a.args, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of query args.
|
|
||||||
func (a *Args) Len() int {
|
|
||||||
return len(a.args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses the given string containing query args.
|
|
||||||
func (a *Args) Parse(s string) {
|
|
||||||
a.buf = append(a.buf[:0], s...)
|
|
||||||
a.ParseBytes(a.buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseBytes parses the given b containing query args.
|
|
||||||
func (a *Args) ParseBytes(b []byte) {
|
|
||||||
a.Reset()
|
|
||||||
|
|
||||||
var s argsScanner
|
|
||||||
s.b = b
|
|
||||||
|
|
||||||
var kv *argsKV
|
|
||||||
a.args, kv = allocArg(a.args)
|
|
||||||
for s.next(kv) {
|
|
||||||
if len(kv.key) > 0 || len(kv.value) > 0 {
|
|
||||||
a.args, kv = allocArg(a.args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a.args = releaseArg(a.args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of query args.
|
|
||||||
func (a *Args) String() string {
|
|
||||||
return string(a.QueryString())
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryString returns query string for the args.
|
|
||||||
//
|
|
||||||
// The returned value is valid until the next call to Args methods.
|
|
||||||
func (a *Args) QueryString() []byte {
|
|
||||||
a.buf = a.AppendBytes(a.buf[:0])
|
|
||||||
return a.buf
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendBytes appends query string to dst and returns the extended dst.
|
|
||||||
func (a *Args) AppendBytes(dst []byte) []byte {
|
|
||||||
for i, n := 0, len(a.args); i < n; i++ {
|
|
||||||
kv := &a.args[i]
|
|
||||||
dst = AppendQuotedArg(dst, kv.key)
|
|
||||||
if len(kv.value) > 0 {
|
|
||||||
dst = append(dst, '=')
|
|
||||||
dst = AppendQuotedArg(dst, kv.value)
|
|
||||||
}
|
|
||||||
if i+1 < n {
|
|
||||||
dst = append(dst, '&')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes query string to w.
|
|
||||||
//
|
|
||||||
// WriteTo implements io.WriterTo interface.
|
|
||||||
func (a *Args) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
n, err := w.Write(a.QueryString())
|
|
||||||
return int64(n), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Del deletes argument with the given key from query args.
|
|
||||||
func (a *Args) Del(key string) {
|
|
||||||
a.args = delAllArgs(a.args, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelBytes deletes argument with the given key from query args.
|
|
||||||
func (a *Args) DelBytes(key []byte) {
|
|
||||||
a.args = delAllArgs(a.args, b2s(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds 'key=value' argument.
|
|
||||||
//
|
|
||||||
// Multiple values for the same key may be added.
|
|
||||||
func (a *Args) Add(key, value string) {
|
|
||||||
a.args = appendArg(a.args, key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddBytesK adds 'key=value' argument.
|
|
||||||
//
|
|
||||||
// Multiple values for the same key may be added.
|
|
||||||
func (a *Args) AddBytesK(key []byte, value string) {
|
|
||||||
a.args = appendArg(a.args, b2s(key), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddBytesV adds 'key=value' argument.
|
|
||||||
//
|
|
||||||
// Multiple values for the same key may be added.
|
|
||||||
func (a *Args) AddBytesV(key string, value []byte) {
|
|
||||||
a.args = appendArg(a.args, key, b2s(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddBytesKV adds 'key=value' argument.
|
|
||||||
//
|
|
||||||
// Multiple values for the same key may be added.
|
|
||||||
func (a *Args) AddBytesKV(key, value []byte) {
|
|
||||||
a.args = appendArg(a.args, b2s(key), b2s(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets 'key=value' argument.
|
|
||||||
func (a *Args) Set(key, value string) {
|
|
||||||
a.args = setArg(a.args, key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBytesK sets 'key=value' argument.
|
|
||||||
func (a *Args) SetBytesK(key []byte, value string) {
|
|
||||||
a.args = setArg(a.args, b2s(key), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBytesV sets 'key=value' argument.
|
|
||||||
func (a *Args) SetBytesV(key string, value []byte) {
|
|
||||||
a.args = setArg(a.args, key, b2s(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBytesKV sets 'key=value' argument.
|
|
||||||
func (a *Args) SetBytesKV(key, value []byte) {
|
|
||||||
a.args = setArgBytes(a.args, key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peek returns query arg value for the given key.
|
|
||||||
//
|
|
||||||
// Returned value is valid until the next Args call.
|
|
||||||
func (a *Args) Peek(key string) []byte {
|
|
||||||
return peekArgStr(a.args, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeekBytes returns query arg value for the given key.
|
|
||||||
//
|
|
||||||
// Returned value is valid until the next Args call.
|
|
||||||
func (a *Args) PeekBytes(key []byte) []byte {
|
|
||||||
return peekArgBytes(a.args, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeekMulti returns all the arg values for the given key.
|
|
||||||
func (a *Args) PeekMulti(key string) [][]byte {
|
|
||||||
var values [][]byte
|
|
||||||
a.VisitAll(func(k, v []byte) {
|
|
||||||
if string(k) == key {
|
|
||||||
values = append(values, v)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeekMultiBytes returns all the arg values for the given key.
|
|
||||||
func (a *Args) PeekMultiBytes(key []byte) [][]byte {
|
|
||||||
return a.PeekMulti(b2s(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has returns true if the given key exists in Args.
|
|
||||||
func (a *Args) Has(key string) bool {
|
|
||||||
return hasArg(a.args, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasBytes returns true if the given key exists in Args.
|
|
||||||
func (a *Args) HasBytes(key []byte) bool {
|
|
||||||
return hasArg(a.args, b2s(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrNoArgValue is returned when Args value with the given key is missing.
|
|
||||||
var ErrNoArgValue = errors.New("no Args value for the given key")
|
|
||||||
|
|
||||||
// GetUint returns uint value for the given key.
|
|
||||||
func (a *Args) GetUint(key string) (int, error) {
|
|
||||||
value := a.Peek(key)
|
|
||||||
if len(value) == 0 {
|
|
||||||
return -1, ErrNoArgValue
|
|
||||||
}
|
|
||||||
return ParseUint(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUint sets uint value for the given key.
|
|
||||||
func (a *Args) SetUint(key string, value int) {
|
|
||||||
bb := AcquireByteBuffer()
|
|
||||||
bb.B = AppendUint(bb.B[:0], value)
|
|
||||||
a.SetBytesV(key, bb.B)
|
|
||||||
ReleaseByteBuffer(bb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUintBytes sets uint value for the given key.
|
|
||||||
func (a *Args) SetUintBytes(key []byte, value int) {
|
|
||||||
a.SetUint(b2s(key), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUintOrZero returns uint value for the given key.
|
|
||||||
//
|
|
||||||
// Zero (0) is returned on error.
|
|
||||||
func (a *Args) GetUintOrZero(key string) int {
|
|
||||||
n, err := a.GetUint(key)
|
|
||||||
if err != nil {
|
|
||||||
n = 0
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUfloat returns ufloat value for the given key.
|
|
||||||
func (a *Args) GetUfloat(key string) (float64, error) {
|
|
||||||
value := a.Peek(key)
|
|
||||||
if len(value) == 0 {
|
|
||||||
return -1, ErrNoArgValue
|
|
||||||
}
|
|
||||||
return ParseUfloat(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUfloatOrZero returns ufloat value for the given key.
|
|
||||||
//
|
|
||||||
// Zero (0) is returned on error.
|
|
||||||
func (a *Args) GetUfloatOrZero(key string) float64 {
|
|
||||||
f, err := a.GetUfloat(key)
|
|
||||||
if err != nil {
|
|
||||||
f = 0
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBool returns boolean value for the given key.
|
|
||||||
//
|
|
||||||
// true is returned for '1', 'y' and 'yes' values,
|
|
||||||
// otherwise false is returned.
|
|
||||||
func (a *Args) GetBool(key string) bool {
|
|
||||||
switch string(a.Peek(key)) {
|
|
||||||
case "1", "y", "yes":
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func visitArgs(args []argsKV, f func(k, v []byte)) {
|
|
||||||
for i, n := 0, len(args); i < n; i++ {
|
|
||||||
kv := &args[i]
|
|
||||||
f(kv.key, kv.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyArgs(dst, src []argsKV) []argsKV {
|
|
||||||
if cap(dst) < len(src) {
|
|
||||||
tmp := make([]argsKV, len(src))
|
|
||||||
copy(tmp, dst)
|
|
||||||
dst = tmp
|
|
||||||
}
|
|
||||||
n := len(src)
|
|
||||||
dst = dst[:n]
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
dstKV := &dst[i]
|
|
||||||
srcKV := &src[i]
|
|
||||||
dstKV.key = append(dstKV.key[:0], srcKV.key...)
|
|
||||||
dstKV.value = append(dstKV.value[:0], srcKV.value...)
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func delAllArgsBytes(args []argsKV, key []byte) []argsKV {
|
|
||||||
return delAllArgs(args, b2s(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
func delAllArgs(args []argsKV, key string) []argsKV {
|
|
||||||
for i, n := 0, len(args); i < n; i++ {
|
|
||||||
kv := &args[i]
|
|
||||||
if key == string(kv.key) {
|
|
||||||
tmp := *kv
|
|
||||||
copy(args[i:], args[i+1:])
|
|
||||||
n--
|
|
||||||
args[n] = tmp
|
|
||||||
args = args[:n]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func setArgBytes(h []argsKV, key, value []byte) []argsKV {
|
|
||||||
return setArg(h, b2s(key), b2s(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
func setArg(h []argsKV, key, value string) []argsKV {
|
|
||||||
n := len(h)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
kv := &h[i]
|
|
||||||
if key == string(kv.key) {
|
|
||||||
kv.value = append(kv.value[:0], value...)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return appendArg(h, key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendArgBytes(h []argsKV, key, value []byte) []argsKV {
|
|
||||||
return appendArg(h, b2s(key), b2s(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendArg(args []argsKV, key, value string) []argsKV {
|
|
||||||
var kv *argsKV
|
|
||||||
args, kv = allocArg(args)
|
|
||||||
kv.key = append(kv.key[:0], key...)
|
|
||||||
kv.value = append(kv.value[:0], value...)
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func allocArg(h []argsKV) ([]argsKV, *argsKV) {
|
|
||||||
n := len(h)
|
|
||||||
if cap(h) > n {
|
|
||||||
h = h[:n+1]
|
|
||||||
} else {
|
|
||||||
h = append(h, argsKV{})
|
|
||||||
}
|
|
||||||
return h, &h[n]
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseArg(h []argsKV) []argsKV {
|
|
||||||
return h[:len(h)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasArg(h []argsKV, key string) bool {
|
|
||||||
for i, n := 0, len(h); i < n; i++ {
|
|
||||||
kv := &h[i]
|
|
||||||
if key == string(kv.key) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func peekArgBytes(h []argsKV, k []byte) []byte {
|
|
||||||
for i, n := 0, len(h); i < n; i++ {
|
|
||||||
kv := &h[i]
|
|
||||||
if bytes.Equal(kv.key, k) {
|
|
||||||
return kv.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func peekArgStr(h []argsKV, k string) []byte {
|
|
||||||
for i, n := 0, len(h); i < n; i++ {
|
|
||||||
kv := &h[i]
|
|
||||||
if string(kv.key) == k {
|
|
||||||
return kv.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type argsScanner struct {
|
|
||||||
b []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *argsScanner) next(kv *argsKV) bool {
|
|
||||||
if len(s.b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
isKey := true
|
|
||||||
k := 0
|
|
||||||
for i, c := range s.b {
|
|
||||||
switch c {
|
|
||||||
case '=':
|
|
||||||
if isKey {
|
|
||||||
isKey = false
|
|
||||||
kv.key = decodeArgAppend(kv.key[:0], s.b[:i])
|
|
||||||
k = i + 1
|
|
||||||
}
|
|
||||||
case '&':
|
|
||||||
if isKey {
|
|
||||||
kv.key = decodeArgAppend(kv.key[:0], s.b[:i])
|
|
||||||
kv.value = kv.value[:0]
|
|
||||||
} else {
|
|
||||||
kv.value = decodeArgAppend(kv.value[:0], s.b[k:i])
|
|
||||||
}
|
|
||||||
s.b = s.b[i+1:]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if isKey {
|
|
||||||
kv.key = decodeArgAppend(kv.key[:0], s.b)
|
|
||||||
kv.value = kv.value[:0]
|
|
||||||
} else {
|
|
||||||
kv.value = decodeArgAppend(kv.value[:0], s.b[k:])
|
|
||||||
}
|
|
||||||
s.b = s.b[len(s.b):]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeArgAppend(dst, src []byte) []byte {
|
|
||||||
if bytes.IndexByte(src, '%') < 0 && bytes.IndexByte(src, '+') < 0 {
|
|
||||||
// fast path: src doesn't contain encoded chars
|
|
||||||
return append(dst, src...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slow path
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
c := src[i]
|
|
||||||
if c == '%' {
|
|
||||||
if i+2 >= len(src) {
|
|
||||||
return append(dst, src[i:]...)
|
|
||||||
}
|
|
||||||
x2 := hex2intTable[src[i+2]]
|
|
||||||
x1 := hex2intTable[src[i+1]]
|
|
||||||
if x1 == 16 || x2 == 16 {
|
|
||||||
dst = append(dst, '%')
|
|
||||||
} else {
|
|
||||||
dst = append(dst, x1<<4|x2)
|
|
||||||
i += 2
|
|
||||||
}
|
|
||||||
} else if c == '+' {
|
|
||||||
dst = append(dst, ' ')
|
|
||||||
} else {
|
|
||||||
dst = append(dst, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// decodeArgAppendNoPlus is almost identical to decodeArgAppend, but it doesn't
|
|
||||||
// substitute '+' with ' '.
|
|
||||||
//
|
|
||||||
// The function is copy-pasted from decodeArgAppend due to the preformance
|
|
||||||
// reasons only.
|
|
||||||
func decodeArgAppendNoPlus(dst, src []byte) []byte {
|
|
||||||
if bytes.IndexByte(src, '%') < 0 {
|
|
||||||
// fast path: src doesn't contain encoded chars
|
|
||||||
return append(dst, src...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slow path
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
c := src[i]
|
|
||||||
if c == '%' {
|
|
||||||
if i+2 >= len(src) {
|
|
||||||
return append(dst, src[i:]...)
|
|
||||||
}
|
|
||||||
x2 := hex2intTable[src[i+2]]
|
|
||||||
x1 := hex2intTable[src[i+1]]
|
|
||||||
if x1 == 16 || x2 == 16 {
|
|
||||||
dst = append(dst, '%')
|
|
||||||
} else {
|
|
||||||
dst = append(dst, x1<<4|x2)
|
|
||||||
i += 2
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dst = append(dst, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
64
vendor/github.com/VictoriaMetrics/fasthttp/bytebuffer.go
generated
vendored
64
vendor/github.com/VictoriaMetrics/fasthttp/bytebuffer.go
generated
vendored
|
@ -1,64 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/valyala/bytebufferpool"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ByteBuffer provides byte buffer, which can be used with fasthttp API
|
|
||||||
// in order to minimize memory allocations.
|
|
||||||
//
|
|
||||||
// ByteBuffer may be used with functions appending data to the given []byte
|
|
||||||
// slice. See example code for details.
|
|
||||||
//
|
|
||||||
// Use AcquireByteBuffer for obtaining an empty byte buffer.
|
|
||||||
//
|
|
||||||
// ByteBuffer is deprecated. Use github.com/valyala/bytebufferpool instead.
|
|
||||||
type ByteBuffer bytebufferpool.ByteBuffer
|
|
||||||
|
|
||||||
// Write implements io.Writer - it appends p to ByteBuffer.B
|
|
||||||
func (b *ByteBuffer) Write(p []byte) (int, error) {
|
|
||||||
return bb(b).Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteString appends s to ByteBuffer.B
|
|
||||||
func (b *ByteBuffer) WriteString(s string) (int, error) {
|
|
||||||
return bb(b).WriteString(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets ByteBuffer.B to p
|
|
||||||
func (b *ByteBuffer) Set(p []byte) {
|
|
||||||
bb(b).Set(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetString sets ByteBuffer.B to s
|
|
||||||
func (b *ByteBuffer) SetString(s string) {
|
|
||||||
bb(b).SetString(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset makes ByteBuffer.B empty.
|
|
||||||
func (b *ByteBuffer) Reset() {
|
|
||||||
bb(b).Reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcquireByteBuffer returns an empty byte buffer from the pool.
|
|
||||||
//
|
|
||||||
// Acquired byte buffer may be returned to the pool via ReleaseByteBuffer call.
|
|
||||||
// This reduces the number of memory allocations required for byte buffer
|
|
||||||
// management.
|
|
||||||
func AcquireByteBuffer() *ByteBuffer {
|
|
||||||
return (*ByteBuffer)(defaultByteBufferPool.Get())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReleaseByteBuffer returns byte buffer to the pool.
|
|
||||||
//
|
|
||||||
// ByteBuffer.B mustn't be touched after returning it to the pool.
|
|
||||||
// Otherwise data races occur.
|
|
||||||
func ReleaseByteBuffer(b *ByteBuffer) {
|
|
||||||
defaultByteBufferPool.Put(bb(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func bb(b *ByteBuffer) *bytebufferpool.ByteBuffer {
|
|
||||||
return (*bytebufferpool.ByteBuffer)(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultByteBufferPool bytebufferpool.Pool
|
|
446
vendor/github.com/VictoriaMetrics/fasthttp/bytesconv.go
generated
vendored
446
vendor/github.com/VictoriaMetrics/fasthttp/bytesconv.go
generated
vendored
|
@ -1,446 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AppendHTMLEscape appends html-escaped s to dst and returns the extended dst.
|
|
||||||
func AppendHTMLEscape(dst []byte, s string) []byte {
|
|
||||||
if strings.IndexByte(s, '<') < 0 &&
|
|
||||||
strings.IndexByte(s, '>') < 0 &&
|
|
||||||
strings.IndexByte(s, '"') < 0 &&
|
|
||||||
strings.IndexByte(s, '\'') < 0 {
|
|
||||||
|
|
||||||
// fast path - nothing to escape
|
|
||||||
return append(dst, s...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slow path
|
|
||||||
var prev int
|
|
||||||
var sub string
|
|
||||||
for i, n := 0, len(s); i < n; i++ {
|
|
||||||
sub = ""
|
|
||||||
switch s[i] {
|
|
||||||
case '<':
|
|
||||||
sub = "<"
|
|
||||||
case '>':
|
|
||||||
sub = ">"
|
|
||||||
case '"':
|
|
||||||
sub = """
|
|
||||||
case '\'':
|
|
||||||
sub = "'"
|
|
||||||
}
|
|
||||||
if len(sub) > 0 {
|
|
||||||
dst = append(dst, s[prev:i]...)
|
|
||||||
dst = append(dst, sub...)
|
|
||||||
prev = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return append(dst, s[prev:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendHTMLEscapeBytes appends html-escaped s to dst and returns
|
|
||||||
// the extended dst.
|
|
||||||
func AppendHTMLEscapeBytes(dst, s []byte) []byte {
|
|
||||||
return AppendHTMLEscape(dst, b2s(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendIPv4 appends string representation of the given ip v4 to dst
|
|
||||||
// and returns the extended dst.
|
|
||||||
func AppendIPv4(dst []byte, ip net.IP) []byte {
|
|
||||||
ip = ip.To4()
|
|
||||||
if ip == nil {
|
|
||||||
return append(dst, "non-v4 ip passed to AppendIPv4"...)
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = AppendUint(dst, int(ip[0]))
|
|
||||||
for i := 1; i < 4; i++ {
|
|
||||||
dst = append(dst, '.')
|
|
||||||
dst = AppendUint(dst, int(ip[i]))
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
var errEmptyIPStr = errors.New("empty ip address string")
|
|
||||||
|
|
||||||
// ParseIPv4 parses ip address from ipStr into dst and returns the extended dst.
|
|
||||||
func ParseIPv4(dst net.IP, ipStr []byte) (net.IP, error) {
|
|
||||||
if len(ipStr) == 0 {
|
|
||||||
return dst, errEmptyIPStr
|
|
||||||
}
|
|
||||||
if len(dst) < net.IPv4len {
|
|
||||||
dst = make([]byte, net.IPv4len)
|
|
||||||
}
|
|
||||||
copy(dst, net.IPv4zero)
|
|
||||||
dst = dst.To4()
|
|
||||||
if dst == nil {
|
|
||||||
panic("BUG: dst must not be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
b := ipStr
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
n := bytes.IndexByte(b, '.')
|
|
||||||
if n < 0 {
|
|
||||||
return dst, fmt.Errorf("cannot find dot in ipStr %q", ipStr)
|
|
||||||
}
|
|
||||||
v, err := ParseUint(b[:n])
|
|
||||||
if err != nil {
|
|
||||||
return dst, fmt.Errorf("cannot parse ipStr %q: %s", ipStr, err)
|
|
||||||
}
|
|
||||||
if v > 255 {
|
|
||||||
return dst, fmt.Errorf("cannot parse ipStr %q: ip part cannot exceed 255: parsed %d", ipStr, v)
|
|
||||||
}
|
|
||||||
dst[i] = byte(v)
|
|
||||||
b = b[n+1:]
|
|
||||||
}
|
|
||||||
v, err := ParseUint(b)
|
|
||||||
if err != nil {
|
|
||||||
return dst, fmt.Errorf("cannot parse ipStr %q: %s", ipStr, err)
|
|
||||||
}
|
|
||||||
if v > 255 {
|
|
||||||
return dst, fmt.Errorf("cannot parse ipStr %q: ip part cannot exceed 255: parsed %d", ipStr, v)
|
|
||||||
}
|
|
||||||
dst[3] = byte(v)
|
|
||||||
|
|
||||||
return dst, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendHTTPDate appends HTTP-compliant (RFC1123) representation of date
|
|
||||||
// to dst and returns the extended dst.
|
|
||||||
func AppendHTTPDate(dst []byte, date time.Time) []byte {
|
|
||||||
dst = date.In(time.UTC).AppendFormat(dst, time.RFC1123)
|
|
||||||
copy(dst[len(dst)-3:], strGMT)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseHTTPDate parses HTTP-compliant (RFC1123) date.
|
|
||||||
func ParseHTTPDate(date []byte) (time.Time, error) {
|
|
||||||
return time.Parse(time.RFC1123, b2s(date))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendUint appends n to dst and returns the extended dst.
|
|
||||||
func AppendUint(dst []byte, n int) []byte {
|
|
||||||
if n < 0 {
|
|
||||||
panic("BUG: int must be positive")
|
|
||||||
}
|
|
||||||
|
|
||||||
var b [20]byte
|
|
||||||
buf := b[:]
|
|
||||||
i := len(buf)
|
|
||||||
var q int
|
|
||||||
for n >= 10 {
|
|
||||||
i--
|
|
||||||
q = n / 10
|
|
||||||
buf[i] = '0' + byte(n-q*10)
|
|
||||||
n = q
|
|
||||||
}
|
|
||||||
i--
|
|
||||||
buf[i] = '0' + byte(n)
|
|
||||||
|
|
||||||
dst = append(dst, buf[i:]...)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseUint parses uint from buf.
|
|
||||||
func ParseUint(buf []byte) (int, error) {
|
|
||||||
v, n, err := parseUintBuf(buf)
|
|
||||||
if n != len(buf) {
|
|
||||||
return -1, errUnexpectedTrailingChar
|
|
||||||
}
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
errEmptyInt = errors.New("empty integer")
|
|
||||||
errUnexpectedFirstChar = errors.New("unexpected first char found. Expecting 0-9")
|
|
||||||
errUnexpectedTrailingChar = errors.New("unexpected traling char found. Expecting 0-9")
|
|
||||||
errTooLongInt = errors.New("too long int")
|
|
||||||
)
|
|
||||||
|
|
||||||
func parseUintBuf(b []byte) (int, int, error) {
|
|
||||||
n := len(b)
|
|
||||||
if n == 0 {
|
|
||||||
return -1, 0, errEmptyInt
|
|
||||||
}
|
|
||||||
v := 0
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
c := b[i]
|
|
||||||
k := c - '0'
|
|
||||||
if k > 9 {
|
|
||||||
if i == 0 {
|
|
||||||
return -1, i, errUnexpectedFirstChar
|
|
||||||
}
|
|
||||||
return v, i, nil
|
|
||||||
}
|
|
||||||
if i >= maxIntChars {
|
|
||||||
return -1, i, errTooLongInt
|
|
||||||
}
|
|
||||||
v = 10*v + int(k)
|
|
||||||
}
|
|
||||||
return v, n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
errEmptyFloat = errors.New("empty float number")
|
|
||||||
errDuplicateFloatPoint = errors.New("duplicate point found in float number")
|
|
||||||
errUnexpectedFloatEnd = errors.New("unexpected end of float number")
|
|
||||||
errInvalidFloatExponent = errors.New("invalid float number exponent")
|
|
||||||
errUnexpectedFloatChar = errors.New("unexpected char found in float number")
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseUfloat parses unsigned float from buf.
|
|
||||||
func ParseUfloat(buf []byte) (float64, error) {
|
|
||||||
if len(buf) == 0 {
|
|
||||||
return -1, errEmptyFloat
|
|
||||||
}
|
|
||||||
b := buf
|
|
||||||
var v uint64
|
|
||||||
var offset = 1.0
|
|
||||||
var pointFound bool
|
|
||||||
for i, c := range b {
|
|
||||||
if c < '0' || c > '9' {
|
|
||||||
if c == '.' {
|
|
||||||
if pointFound {
|
|
||||||
return -1, errDuplicateFloatPoint
|
|
||||||
}
|
|
||||||
pointFound = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if c == 'e' || c == 'E' {
|
|
||||||
if i+1 >= len(b) {
|
|
||||||
return -1, errUnexpectedFloatEnd
|
|
||||||
}
|
|
||||||
b = b[i+1:]
|
|
||||||
minus := -1
|
|
||||||
switch b[0] {
|
|
||||||
case '+':
|
|
||||||
b = b[1:]
|
|
||||||
minus = 1
|
|
||||||
case '-':
|
|
||||||
b = b[1:]
|
|
||||||
default:
|
|
||||||
minus = 1
|
|
||||||
}
|
|
||||||
vv, err := ParseUint(b)
|
|
||||||
if err != nil {
|
|
||||||
return -1, errInvalidFloatExponent
|
|
||||||
}
|
|
||||||
return float64(v) * offset * math.Pow10(minus*int(vv)), nil
|
|
||||||
}
|
|
||||||
return -1, errUnexpectedFloatChar
|
|
||||||
}
|
|
||||||
v = 10*v + uint64(c-'0')
|
|
||||||
if pointFound {
|
|
||||||
offset /= 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return float64(v) * offset, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
errEmptyHexNum = errors.New("empty hex number")
|
|
||||||
errTooLargeHexNum = errors.New("too large hex number")
|
|
||||||
)
|
|
||||||
|
|
||||||
func readHexInt(r *bufio.Reader) (int, error) {
|
|
||||||
n := 0
|
|
||||||
i := 0
|
|
||||||
var k int
|
|
||||||
for {
|
|
||||||
c, err := r.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF && i > 0 {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
k = int(hex2intTable[c])
|
|
||||||
if k == 16 {
|
|
||||||
if i == 0 {
|
|
||||||
return -1, errEmptyHexNum
|
|
||||||
}
|
|
||||||
r.UnreadByte()
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
if i >= maxHexIntChars {
|
|
||||||
return -1, errTooLargeHexNum
|
|
||||||
}
|
|
||||||
n = (n << 4) | k
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hexIntBufPool sync.Pool
|
|
||||||
|
|
||||||
func writeHexInt(w *bufio.Writer, n int) error {
|
|
||||||
if n < 0 {
|
|
||||||
panic("BUG: int must be positive")
|
|
||||||
}
|
|
||||||
|
|
||||||
v := hexIntBufPool.Get()
|
|
||||||
if v == nil {
|
|
||||||
v = make([]byte, maxHexIntChars+1)
|
|
||||||
}
|
|
||||||
buf := v.([]byte)
|
|
||||||
i := len(buf) - 1
|
|
||||||
for {
|
|
||||||
buf[i] = int2hexbyte(n & 0xf)
|
|
||||||
n >>= 4
|
|
||||||
if n == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
_, err := w.Write(buf[i:])
|
|
||||||
hexIntBufPool.Put(v)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func int2hexbyte(n int) byte {
|
|
||||||
if n < 10 {
|
|
||||||
return '0' + byte(n)
|
|
||||||
}
|
|
||||||
return 'a' + byte(n) - 10
|
|
||||||
}
|
|
||||||
|
|
||||||
func hexCharUpper(c byte) byte {
|
|
||||||
if c < 10 {
|
|
||||||
return '0' + c
|
|
||||||
}
|
|
||||||
return c - 10 + 'A'
|
|
||||||
}
|
|
||||||
|
|
||||||
var hex2intTable = func() []byte {
|
|
||||||
b := make([]byte, 256)
|
|
||||||
for i := 0; i < 256; i++ {
|
|
||||||
c := byte(16)
|
|
||||||
if i >= '0' && i <= '9' {
|
|
||||||
c = byte(i) - '0'
|
|
||||||
} else if i >= 'a' && i <= 'f' {
|
|
||||||
c = byte(i) - 'a' + 10
|
|
||||||
} else if i >= 'A' && i <= 'F' {
|
|
||||||
c = byte(i) - 'A' + 10
|
|
||||||
}
|
|
||||||
b[i] = c
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}()
|
|
||||||
|
|
||||||
const toLower = 'a' - 'A'
|
|
||||||
|
|
||||||
var toLowerTable = func() [256]byte {
|
|
||||||
var a [256]byte
|
|
||||||
for i := 0; i < 256; i++ {
|
|
||||||
c := byte(i)
|
|
||||||
if c >= 'A' && c <= 'Z' {
|
|
||||||
c += toLower
|
|
||||||
}
|
|
||||||
a[i] = c
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}()
|
|
||||||
|
|
||||||
var toUpperTable = func() [256]byte {
|
|
||||||
var a [256]byte
|
|
||||||
for i := 0; i < 256; i++ {
|
|
||||||
c := byte(i)
|
|
||||||
if c >= 'a' && c <= 'z' {
|
|
||||||
c -= toLower
|
|
||||||
}
|
|
||||||
a[i] = c
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}()
|
|
||||||
|
|
||||||
func lowercaseBytes(b []byte) {
|
|
||||||
for i := 0; i < len(b); i++ {
|
|
||||||
p := &b[i]
|
|
||||||
*p = toLowerTable[*p]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// b2s converts byte slice to a string without memory allocation.
|
|
||||||
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
|
|
||||||
//
|
|
||||||
// Note it may break if string and/or slice header will change
|
|
||||||
// in the future go versions.
|
|
||||||
func b2s(b []byte) string {
|
|
||||||
return *(*string)(unsafe.Pointer(&b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// s2b converts string to a byte slice without memory allocation.
|
|
||||||
//
|
|
||||||
// Note it may break if string and/or slice header will change
|
|
||||||
// in the future go versions.
|
|
||||||
func s2b(s string) (b []byte) {
|
|
||||||
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
|
||||||
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
|
||||||
bh.Data = sh.Data
|
|
||||||
bh.Len = sh.Len
|
|
||||||
bh.Cap = sh.Len
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendUnquotedArg appends url-decoded src to dst and returns appended dst.
|
|
||||||
//
|
|
||||||
// dst may point to src. In this case src will be overwritten.
|
|
||||||
func AppendUnquotedArg(dst, src []byte) []byte {
|
|
||||||
return decodeArgAppend(dst, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendQuotedArg appends url-encoded src to dst and returns appended dst.
|
|
||||||
func AppendQuotedArg(dst, src []byte) []byte {
|
|
||||||
for _, c := range src {
|
|
||||||
// See http://www.w3.org/TR/html5/forms.html#form-submission-algorithm
|
|
||||||
if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' ||
|
|
||||||
c == '*' || c == '-' || c == '.' || c == '_' {
|
|
||||||
dst = append(dst, c)
|
|
||||||
} else {
|
|
||||||
dst = append(dst, '%', hexCharUpper(c>>4), hexCharUpper(c&15))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendQuotedPath(dst, src []byte) []byte {
|
|
||||||
for _, c := range src {
|
|
||||||
if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' ||
|
|
||||||
c == '/' || c == '.' || c == ',' || c == '=' || c == ':' || c == '&' || c == '~' || c == '-' || c == '_' {
|
|
||||||
dst = append(dst, c)
|
|
||||||
} else {
|
|
||||||
dst = append(dst, '%', hexCharUpper(c>>4), hexCharUpper(c&15))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualBytesStr returns true if string(b) == s.
|
|
||||||
//
|
|
||||||
// This function has no performance benefits comparing to string(b) == s.
|
|
||||||
// It is left here for backwards compatibility only.
|
|
||||||
//
|
|
||||||
// This function is deperecated and may be deleted soon.
|
|
||||||
func EqualBytesStr(b []byte, s string) bool {
|
|
||||||
return string(b) == s
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendBytesStr appends src to dst and returns the extended dst.
|
|
||||||
//
|
|
||||||
// This function has no performance benefits comparing to append(dst, src...).
|
|
||||||
// It is left here for backwards compatibility only.
|
|
||||||
//
|
|
||||||
// This function is deprecated and may be deleted soon.
|
|
||||||
func AppendBytesStr(dst []byte, src string) []byte {
|
|
||||||
return append(dst, src...)
|
|
||||||
}
|
|
8
vendor/github.com/VictoriaMetrics/fasthttp/bytesconv_32.go
generated
vendored
8
vendor/github.com/VictoriaMetrics/fasthttp/bytesconv_32.go
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
// +build !amd64,!arm64,!ppc64
|
|
||||||
|
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxIntChars = 9
|
|
||||||
maxHexIntChars = 7
|
|
||||||
)
|
|
8
vendor/github.com/VictoriaMetrics/fasthttp/bytesconv_64.go
generated
vendored
8
vendor/github.com/VictoriaMetrics/fasthttp/bytesconv_64.go
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
// +build amd64 arm64 ppc64
|
|
||||||
|
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxIntChars = 18
|
|
||||||
maxHexIntChars = 15
|
|
||||||
)
|
|
2134
vendor/github.com/VictoriaMetrics/fasthttp/client.go
generated
vendored
2134
vendor/github.com/VictoriaMetrics/fasthttp/client.go
generated
vendored
File diff suppressed because it is too large
Load diff
28
vendor/github.com/VictoriaMetrics/fasthttp/coarseTime.go
generated
vendored
28
vendor/github.com/VictoriaMetrics/fasthttp/coarseTime.go
generated
vendored
|
@ -1,28 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CoarseTimeNow returns the current time truncated to the nearest second.
|
|
||||||
//
|
|
||||||
// This is a faster alternative to time.Now().
|
|
||||||
func CoarseTimeNow() time.Time {
|
|
||||||
tp := coarseTime.Load().(*time.Time)
|
|
||||||
return *tp
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
t := time.Now().Truncate(time.Second)
|
|
||||||
coarseTime.Store(&t)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
t := time.Now().Truncate(time.Second)
|
|
||||||
coarseTime.Store(&t)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
var coarseTime atomic.Value
|
|
440
vendor/github.com/VictoriaMetrics/fasthttp/compress.go
generated
vendored
440
vendor/github.com/VictoriaMetrics/fasthttp/compress.go
generated
vendored
|
@ -1,440 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/fasthttp/stackless"
|
|
||||||
"github.com/klauspost/compress/flate"
|
|
||||||
"github.com/klauspost/compress/gzip"
|
|
||||||
"github.com/klauspost/compress/zlib"
|
|
||||||
"github.com/valyala/bytebufferpool"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Supported compression levels.
|
|
||||||
const (
|
|
||||||
CompressNoCompression = flate.NoCompression
|
|
||||||
CompressBestSpeed = flate.BestSpeed
|
|
||||||
CompressBestCompression = flate.BestCompression
|
|
||||||
CompressDefaultCompression = 6 // flate.DefaultCompression
|
|
||||||
CompressHuffmanOnly = -2 // flate.HuffmanOnly
|
|
||||||
)
|
|
||||||
|
|
||||||
func acquireGzipReader(r io.Reader) (*gzip.Reader, error) {
|
|
||||||
v := gzipReaderPool.Get()
|
|
||||||
if v == nil {
|
|
||||||
return gzip.NewReader(r)
|
|
||||||
}
|
|
||||||
zr := v.(*gzip.Reader)
|
|
||||||
if err := zr.Reset(r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return zr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseGzipReader(zr *gzip.Reader) {
|
|
||||||
zr.Close()
|
|
||||||
gzipReaderPool.Put(zr)
|
|
||||||
}
|
|
||||||
|
|
||||||
var gzipReaderPool sync.Pool
|
|
||||||
|
|
||||||
func acquireFlateReader(r io.Reader) (io.ReadCloser, error) {
|
|
||||||
v := flateReaderPool.Get()
|
|
||||||
if v == nil {
|
|
||||||
zr, err := zlib.NewReader(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return zr, nil
|
|
||||||
}
|
|
||||||
zr := v.(io.ReadCloser)
|
|
||||||
if err := resetFlateReader(zr, r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return zr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseFlateReader(zr io.ReadCloser) {
|
|
||||||
zr.Close()
|
|
||||||
flateReaderPool.Put(zr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resetFlateReader(zr io.ReadCloser, r io.Reader) error {
|
|
||||||
zrr, ok := zr.(zlib.Resetter)
|
|
||||||
if !ok {
|
|
||||||
panic("BUG: zlib.Reader doesn't implement zlib.Resetter???")
|
|
||||||
}
|
|
||||||
return zrr.Reset(r, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
var flateReaderPool sync.Pool
|
|
||||||
|
|
||||||
func acquireStacklessGzipWriter(w io.Writer, level int) stackless.Writer {
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := stacklessGzipWriterPoolMap[nLevel]
|
|
||||||
v := p.Get()
|
|
||||||
if v == nil {
|
|
||||||
return stackless.NewWriter(w, func(w io.Writer) stackless.Writer {
|
|
||||||
return acquireRealGzipWriter(w, level)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
sw := v.(stackless.Writer)
|
|
||||||
sw.Reset(w)
|
|
||||||
return sw
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseStacklessGzipWriter(sw stackless.Writer, level int) {
|
|
||||||
sw.Close()
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := stacklessGzipWriterPoolMap[nLevel]
|
|
||||||
p.Put(sw)
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquireRealGzipWriter(w io.Writer, level int) *gzip.Writer {
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := realGzipWriterPoolMap[nLevel]
|
|
||||||
v := p.Get()
|
|
||||||
if v == nil {
|
|
||||||
zw, err := gzip.NewWriterLevel(w, level)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("BUG: unexpected error from gzip.NewWriterLevel(%d): %s", level, err))
|
|
||||||
}
|
|
||||||
return zw
|
|
||||||
}
|
|
||||||
zw := v.(*gzip.Writer)
|
|
||||||
zw.Reset(w)
|
|
||||||
return zw
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseRealGzipWriter(zw *gzip.Writer, level int) {
|
|
||||||
zw.Close()
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := realGzipWriterPoolMap[nLevel]
|
|
||||||
p.Put(zw)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
stacklessGzipWriterPoolMap = newCompressWriterPoolMap()
|
|
||||||
realGzipWriterPoolMap = newCompressWriterPoolMap()
|
|
||||||
)
|
|
||||||
|
|
||||||
// AppendGzipBytesLevel appends gzipped src to dst using the given
|
|
||||||
// compression level and returns the resulting dst.
|
|
||||||
//
|
|
||||||
// Supported compression levels are:
|
|
||||||
//
|
|
||||||
// * CompressNoCompression
|
|
||||||
// * CompressBestSpeed
|
|
||||||
// * CompressBestCompression
|
|
||||||
// * CompressDefaultCompression
|
|
||||||
// * CompressHuffmanOnly
|
|
||||||
func AppendGzipBytesLevel(dst, src []byte, level int) []byte {
|
|
||||||
w := &byteSliceWriter{dst}
|
|
||||||
WriteGzipLevel(w, src, level)
|
|
||||||
return w.b
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteGzipLevel writes gzipped p to w using the given compression level
|
|
||||||
// and returns the number of compressed bytes written to w.
|
|
||||||
//
|
|
||||||
// Supported compression levels are:
|
|
||||||
//
|
|
||||||
// * CompressNoCompression
|
|
||||||
// * CompressBestSpeed
|
|
||||||
// * CompressBestCompression
|
|
||||||
// * CompressDefaultCompression
|
|
||||||
// * CompressHuffmanOnly
|
|
||||||
func WriteGzipLevel(w io.Writer, p []byte, level int) (int, error) {
|
|
||||||
switch w.(type) {
|
|
||||||
case *byteSliceWriter,
|
|
||||||
*bytes.Buffer,
|
|
||||||
*ByteBuffer,
|
|
||||||
*bytebufferpool.ByteBuffer:
|
|
||||||
// These writers don't block, so we can just use stacklessWriteGzip
|
|
||||||
ctx := &compressCtx{
|
|
||||||
w: w,
|
|
||||||
p: p,
|
|
||||||
level: level,
|
|
||||||
}
|
|
||||||
stacklessWriteGzip(ctx)
|
|
||||||
return len(p), nil
|
|
||||||
default:
|
|
||||||
zw := acquireStacklessGzipWriter(w, level)
|
|
||||||
n, err := zw.Write(p)
|
|
||||||
releaseStacklessGzipWriter(zw, level)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var stacklessWriteGzip = stackless.NewFunc(nonblockingWriteGzip)
|
|
||||||
|
|
||||||
func nonblockingWriteGzip(ctxv interface{}) {
|
|
||||||
ctx := ctxv.(*compressCtx)
|
|
||||||
zw := acquireRealGzipWriter(ctx.w, ctx.level)
|
|
||||||
|
|
||||||
_, err := zw.Write(ctx.p)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("BUG: gzip.Writer.Write for len(p)=%d returned unexpected error: %s", len(ctx.p), err))
|
|
||||||
}
|
|
||||||
|
|
||||||
releaseRealGzipWriter(zw, ctx.level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteGzip writes gzipped p to w and returns the number of compressed
|
|
||||||
// bytes written to w.
|
|
||||||
func WriteGzip(w io.Writer, p []byte) (int, error) {
|
|
||||||
return WriteGzipLevel(w, p, CompressDefaultCompression)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendGzipBytes appends gzipped src to dst and returns the resulting dst.
|
|
||||||
func AppendGzipBytes(dst, src []byte) []byte {
|
|
||||||
return AppendGzipBytesLevel(dst, src, CompressDefaultCompression)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteGunzip writes ungzipped p to w and returns the number of uncompressed
|
|
||||||
// bytes written to w.
|
|
||||||
func WriteGunzip(w io.Writer, p []byte) (int, error) {
|
|
||||||
r := &byteSliceReader{p}
|
|
||||||
zr, err := acquireGzipReader(r)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
n, err := copyZeroAlloc(w, zr)
|
|
||||||
releaseGzipReader(zr)
|
|
||||||
nn := int(n)
|
|
||||||
if int64(nn) != n {
|
|
||||||
return 0, fmt.Errorf("too much data gunzipped: %d", n)
|
|
||||||
}
|
|
||||||
return nn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendGunzipBytes appends gunzipped src to dst and returns the resulting dst.
|
|
||||||
func AppendGunzipBytes(dst, src []byte) ([]byte, error) {
|
|
||||||
w := &byteSliceWriter{dst}
|
|
||||||
_, err := WriteGunzip(w, src)
|
|
||||||
return w.b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendDeflateBytesLevel appends deflated src to dst using the given
|
|
||||||
// compression level and returns the resulting dst.
|
|
||||||
//
|
|
||||||
// Supported compression levels are:
|
|
||||||
//
|
|
||||||
// * CompressNoCompression
|
|
||||||
// * CompressBestSpeed
|
|
||||||
// * CompressBestCompression
|
|
||||||
// * CompressDefaultCompression
|
|
||||||
// * CompressHuffmanOnly
|
|
||||||
func AppendDeflateBytesLevel(dst, src []byte, level int) []byte {
|
|
||||||
w := &byteSliceWriter{dst}
|
|
||||||
WriteDeflateLevel(w, src, level)
|
|
||||||
return w.b
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteDeflateLevel writes deflated p to w using the given compression level
|
|
||||||
// and returns the number of compressed bytes written to w.
|
|
||||||
//
|
|
||||||
// Supported compression levels are:
|
|
||||||
//
|
|
||||||
// * CompressNoCompression
|
|
||||||
// * CompressBestSpeed
|
|
||||||
// * CompressBestCompression
|
|
||||||
// * CompressDefaultCompression
|
|
||||||
// * CompressHuffmanOnly
|
|
||||||
func WriteDeflateLevel(w io.Writer, p []byte, level int) (int, error) {
|
|
||||||
switch w.(type) {
|
|
||||||
case *byteSliceWriter,
|
|
||||||
*bytes.Buffer,
|
|
||||||
*ByteBuffer,
|
|
||||||
*bytebufferpool.ByteBuffer:
|
|
||||||
// These writers don't block, so we can just use stacklessWriteDeflate
|
|
||||||
ctx := &compressCtx{
|
|
||||||
w: w,
|
|
||||||
p: p,
|
|
||||||
level: level,
|
|
||||||
}
|
|
||||||
stacklessWriteDeflate(ctx)
|
|
||||||
return len(p), nil
|
|
||||||
default:
|
|
||||||
zw := acquireStacklessDeflateWriter(w, level)
|
|
||||||
n, err := zw.Write(p)
|
|
||||||
releaseStacklessDeflateWriter(zw, level)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var stacklessWriteDeflate = stackless.NewFunc(nonblockingWriteDeflate)
|
|
||||||
|
|
||||||
func nonblockingWriteDeflate(ctxv interface{}) {
|
|
||||||
ctx := ctxv.(*compressCtx)
|
|
||||||
zw := acquireRealDeflateWriter(ctx.w, ctx.level)
|
|
||||||
|
|
||||||
_, err := zw.Write(ctx.p)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("BUG: zlib.Writer.Write for len(p)=%d returned unexpected error: %s", len(ctx.p), err))
|
|
||||||
}
|
|
||||||
|
|
||||||
releaseRealDeflateWriter(zw, ctx.level)
|
|
||||||
}
|
|
||||||
|
|
||||||
type compressCtx struct {
|
|
||||||
w io.Writer
|
|
||||||
p []byte
|
|
||||||
level int
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteDeflate writes deflated p to w and returns the number of compressed
|
|
||||||
// bytes written to w.
|
|
||||||
func WriteDeflate(w io.Writer, p []byte) (int, error) {
|
|
||||||
return WriteDeflateLevel(w, p, CompressDefaultCompression)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendDeflateBytes appends deflated src to dst and returns the resulting dst.
|
|
||||||
func AppendDeflateBytes(dst, src []byte) []byte {
|
|
||||||
return AppendDeflateBytesLevel(dst, src, CompressDefaultCompression)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteInflate writes inflated p to w and returns the number of uncompressed
|
|
||||||
// bytes written to w.
|
|
||||||
func WriteInflate(w io.Writer, p []byte) (int, error) {
|
|
||||||
r := &byteSliceReader{p}
|
|
||||||
zr, err := acquireFlateReader(r)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
n, err := copyZeroAlloc(w, zr)
|
|
||||||
releaseFlateReader(zr)
|
|
||||||
nn := int(n)
|
|
||||||
if int64(nn) != n {
|
|
||||||
return 0, fmt.Errorf("too much data inflated: %d", n)
|
|
||||||
}
|
|
||||||
return nn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendInflateBytes appends inflated src to dst and returns the resulting dst.
|
|
||||||
func AppendInflateBytes(dst, src []byte) ([]byte, error) {
|
|
||||||
w := &byteSliceWriter{dst}
|
|
||||||
_, err := WriteInflate(w, src)
|
|
||||||
return w.b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type byteSliceWriter struct {
|
|
||||||
b []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *byteSliceWriter) Write(p []byte) (int, error) {
|
|
||||||
w.b = append(w.b, p...)
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type byteSliceReader struct {
|
|
||||||
b []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *byteSliceReader) Read(p []byte) (int, error) {
|
|
||||||
if len(r.b) == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
n := copy(p, r.b)
|
|
||||||
r.b = r.b[n:]
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquireStacklessDeflateWriter(w io.Writer, level int) stackless.Writer {
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := stacklessDeflateWriterPoolMap[nLevel]
|
|
||||||
v := p.Get()
|
|
||||||
if v == nil {
|
|
||||||
return stackless.NewWriter(w, func(w io.Writer) stackless.Writer {
|
|
||||||
return acquireRealDeflateWriter(w, level)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
sw := v.(stackless.Writer)
|
|
||||||
sw.Reset(w)
|
|
||||||
return sw
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseStacklessDeflateWriter(sw stackless.Writer, level int) {
|
|
||||||
sw.Close()
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := stacklessDeflateWriterPoolMap[nLevel]
|
|
||||||
p.Put(sw)
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquireRealDeflateWriter(w io.Writer, level int) *zlib.Writer {
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := realDeflateWriterPoolMap[nLevel]
|
|
||||||
v := p.Get()
|
|
||||||
if v == nil {
|
|
||||||
zw, err := zlib.NewWriterLevel(w, level)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("BUG: unexpected error from zlib.NewWriterLevel(%d): %s", level, err))
|
|
||||||
}
|
|
||||||
return zw
|
|
||||||
}
|
|
||||||
zw := v.(*zlib.Writer)
|
|
||||||
zw.Reset(w)
|
|
||||||
return zw
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseRealDeflateWriter(zw *zlib.Writer, level int) {
|
|
||||||
zw.Close()
|
|
||||||
nLevel := normalizeCompressLevel(level)
|
|
||||||
p := realDeflateWriterPoolMap[nLevel]
|
|
||||||
p.Put(zw)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
stacklessDeflateWriterPoolMap = newCompressWriterPoolMap()
|
|
||||||
realDeflateWriterPoolMap = newCompressWriterPoolMap()
|
|
||||||
)
|
|
||||||
|
|
||||||
func newCompressWriterPoolMap() []*sync.Pool {
|
|
||||||
// Initialize pools for all the compression levels defined
|
|
||||||
// in https://golang.org/pkg/compress/flate/#pkg-constants .
|
|
||||||
// Compression levels are normalized with normalizeCompressLevel,
|
|
||||||
// so the fit [0..11].
|
|
||||||
var m []*sync.Pool
|
|
||||||
for i := 0; i < 12; i++ {
|
|
||||||
m = append(m, &sync.Pool{})
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func isFileCompressible(f *os.File, minCompressRatio float64) bool {
|
|
||||||
// Try compressing the first 4kb of of the file
|
|
||||||
// and see if it can be compressed by more than
|
|
||||||
// the given minCompressRatio.
|
|
||||||
b := AcquireByteBuffer()
|
|
||||||
zw := acquireStacklessGzipWriter(b, CompressDefaultCompression)
|
|
||||||
lr := &io.LimitedReader{
|
|
||||||
R: f,
|
|
||||||
N: 4096,
|
|
||||||
}
|
|
||||||
_, err := copyZeroAlloc(zw, lr)
|
|
||||||
releaseStacklessGzipWriter(zw, CompressDefaultCompression)
|
|
||||||
f.Seek(0, 0)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 4096 - lr.N
|
|
||||||
zn := len(b.B)
|
|
||||||
ReleaseByteBuffer(b)
|
|
||||||
return float64(zn) < float64(n)*minCompressRatio
|
|
||||||
}
|
|
||||||
|
|
||||||
// normalizes compression level into [0..11], so it could be used as an index
|
|
||||||
// in *PoolMap.
|
|
||||||
func normalizeCompressLevel(level int) int {
|
|
||||||
// -2 is the lowest compression level - CompressHuffmanOnly
|
|
||||||
// 9 is the highest compression level - CompressBestCompression
|
|
||||||
if level < -2 || level > 9 {
|
|
||||||
level = CompressDefaultCompression
|
|
||||||
}
|
|
||||||
return level + 2
|
|
||||||
}
|
|
396
vendor/github.com/VictoriaMetrics/fasthttp/cookie.go
generated
vendored
396
vendor/github.com/VictoriaMetrics/fasthttp/cookie.go
generated
vendored
|
@ -1,396 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var zeroTime time.Time
|
|
||||||
|
|
||||||
var (
|
|
||||||
// CookieExpireDelete may be set on Cookie.Expire for expiring the given cookie.
|
|
||||||
CookieExpireDelete = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
|
|
||||||
|
|
||||||
// CookieExpireUnlimited indicates that the cookie doesn't expire.
|
|
||||||
CookieExpireUnlimited = zeroTime
|
|
||||||
)
|
|
||||||
|
|
||||||
// AcquireCookie returns an empty Cookie object from the pool.
|
|
||||||
//
|
|
||||||
// The returned object may be returned back to the pool with ReleaseCookie.
|
|
||||||
// This allows reducing GC load.
|
|
||||||
func AcquireCookie() *Cookie {
|
|
||||||
return cookiePool.Get().(*Cookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReleaseCookie returns the Cookie object acquired with AcquireCookie back
|
|
||||||
// to the pool.
|
|
||||||
//
|
|
||||||
// Do not access released Cookie object, otherwise data races may occur.
|
|
||||||
func ReleaseCookie(c *Cookie) {
|
|
||||||
c.Reset()
|
|
||||||
cookiePool.Put(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
var cookiePool = &sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return &Cookie{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cookie represents HTTP response cookie.
|
|
||||||
//
|
|
||||||
// Do not copy Cookie objects. Create new object and use CopyTo instead.
|
|
||||||
//
|
|
||||||
// Cookie instance MUST NOT be used from concurrently running goroutines.
|
|
||||||
type Cookie struct {
|
|
||||||
noCopy noCopy
|
|
||||||
|
|
||||||
key []byte
|
|
||||||
value []byte
|
|
||||||
expire time.Time
|
|
||||||
domain []byte
|
|
||||||
path []byte
|
|
||||||
|
|
||||||
httpOnly bool
|
|
||||||
secure bool
|
|
||||||
|
|
||||||
bufKV argsKV
|
|
||||||
buf []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyTo copies src cookie to c.
|
|
||||||
func (c *Cookie) CopyTo(src *Cookie) {
|
|
||||||
c.Reset()
|
|
||||||
c.key = append(c.key[:0], src.key...)
|
|
||||||
c.value = append(c.value[:0], src.value...)
|
|
||||||
c.expire = src.expire
|
|
||||||
c.domain = append(c.domain[:0], src.domain...)
|
|
||||||
c.path = append(c.path[:0], src.path...)
|
|
||||||
c.httpOnly = src.httpOnly
|
|
||||||
c.secure = src.secure
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTPOnly returns true if the cookie is http only.
|
|
||||||
func (c *Cookie) HTTPOnly() bool {
|
|
||||||
return c.httpOnly
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHTTPOnly sets cookie's httpOnly flag to the given value.
|
|
||||||
func (c *Cookie) SetHTTPOnly(httpOnly bool) {
|
|
||||||
c.httpOnly = httpOnly
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secure returns true if the cookie is secure.
|
|
||||||
func (c *Cookie) Secure() bool {
|
|
||||||
return c.secure
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSecure sets cookie's secure flag to the given value.
|
|
||||||
func (c *Cookie) SetSecure(secure bool) {
|
|
||||||
c.secure = secure
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path returns cookie path.
|
|
||||||
func (c *Cookie) Path() []byte {
|
|
||||||
return c.path
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPath sets cookie path.
|
|
||||||
func (c *Cookie) SetPath(path string) {
|
|
||||||
c.buf = append(c.buf[:0], path...)
|
|
||||||
c.path = normalizePath(c.path, c.buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPathBytes sets cookie path.
|
|
||||||
func (c *Cookie) SetPathBytes(path []byte) {
|
|
||||||
c.buf = append(c.buf[:0], path...)
|
|
||||||
c.path = normalizePath(c.path, c.buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Domain returns cookie domain.
|
|
||||||
//
|
|
||||||
// The returned domain is valid until the next Cookie modification method call.
|
|
||||||
func (c *Cookie) Domain() []byte {
|
|
||||||
return c.domain
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDomain sets cookie domain.
|
|
||||||
func (c *Cookie) SetDomain(domain string) {
|
|
||||||
c.domain = append(c.domain[:0], domain...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDomainBytes sets cookie domain.
|
|
||||||
func (c *Cookie) SetDomainBytes(domain []byte) {
|
|
||||||
c.domain = append(c.domain[:0], domain...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expire returns cookie expiration time.
|
|
||||||
//
|
|
||||||
// CookieExpireUnlimited is returned if cookie doesn't expire
|
|
||||||
func (c *Cookie) Expire() time.Time {
|
|
||||||
expire := c.expire
|
|
||||||
if expire.IsZero() {
|
|
||||||
expire = CookieExpireUnlimited
|
|
||||||
}
|
|
||||||
return expire
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetExpire sets cookie expiration time.
|
|
||||||
//
|
|
||||||
// Set expiration time to CookieExpireDelete for expiring (deleting)
|
|
||||||
// the cookie on the client.
|
|
||||||
//
|
|
||||||
// By default cookie lifetime is limited by browser session.
|
|
||||||
func (c *Cookie) SetExpire(expire time.Time) {
|
|
||||||
c.expire = expire
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns cookie value.
|
|
||||||
//
|
|
||||||
// The returned value is valid until the next Cookie modification method call.
|
|
||||||
func (c *Cookie) Value() []byte {
|
|
||||||
return c.value
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValue sets cookie value.
|
|
||||||
func (c *Cookie) SetValue(value string) {
|
|
||||||
c.value = append(c.value[:0], value...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValueBytes sets cookie value.
|
|
||||||
func (c *Cookie) SetValueBytes(value []byte) {
|
|
||||||
c.value = append(c.value[:0], value...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key returns cookie name.
|
|
||||||
//
|
|
||||||
// The returned value is valid until the next Cookie modification method call.
|
|
||||||
func (c *Cookie) Key() []byte {
|
|
||||||
return c.key
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetKey sets cookie name.
|
|
||||||
func (c *Cookie) SetKey(key string) {
|
|
||||||
c.key = append(c.key[:0], key...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetKeyBytes sets cookie name.
|
|
||||||
func (c *Cookie) SetKeyBytes(key []byte) {
|
|
||||||
c.key = append(c.key[:0], key...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset clears the cookie.
|
|
||||||
func (c *Cookie) Reset() {
|
|
||||||
c.key = c.key[:0]
|
|
||||||
c.value = c.value[:0]
|
|
||||||
c.expire = zeroTime
|
|
||||||
c.domain = c.domain[:0]
|
|
||||||
c.path = c.path[:0]
|
|
||||||
c.httpOnly = false
|
|
||||||
c.secure = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendBytes appends cookie representation to dst and returns
|
|
||||||
// the extended dst.
|
|
||||||
func (c *Cookie) AppendBytes(dst []byte) []byte {
|
|
||||||
if len(c.key) > 0 {
|
|
||||||
dst = append(dst, c.key...)
|
|
||||||
dst = append(dst, '=')
|
|
||||||
}
|
|
||||||
dst = append(dst, c.value...)
|
|
||||||
|
|
||||||
if !c.expire.IsZero() {
|
|
||||||
c.bufKV.value = AppendHTTPDate(c.bufKV.value[:0], c.expire)
|
|
||||||
dst = append(dst, ';', ' ')
|
|
||||||
dst = append(dst, strCookieExpires...)
|
|
||||||
dst = append(dst, '=')
|
|
||||||
dst = append(dst, c.bufKV.value...)
|
|
||||||
}
|
|
||||||
if len(c.domain) > 0 {
|
|
||||||
dst = appendCookiePart(dst, strCookieDomain, c.domain)
|
|
||||||
}
|
|
||||||
if len(c.path) > 0 {
|
|
||||||
dst = appendCookiePart(dst, strCookiePath, c.path)
|
|
||||||
}
|
|
||||||
if c.httpOnly {
|
|
||||||
dst = append(dst, ';', ' ')
|
|
||||||
dst = append(dst, strCookieHTTPOnly...)
|
|
||||||
}
|
|
||||||
if c.secure {
|
|
||||||
dst = append(dst, ';', ' ')
|
|
||||||
dst = append(dst, strCookieSecure...)
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cookie returns cookie representation.
|
|
||||||
//
|
|
||||||
// The returned value is valid until the next call to Cookie methods.
|
|
||||||
func (c *Cookie) Cookie() []byte {
|
|
||||||
c.buf = c.AppendBytes(c.buf[:0])
|
|
||||||
return c.buf
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns cookie representation.
|
|
||||||
func (c *Cookie) String() string {
|
|
||||||
return string(c.Cookie())
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes cookie representation to w.
|
|
||||||
//
|
|
||||||
// WriteTo implements io.WriterTo interface.
|
|
||||||
func (c *Cookie) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
n, err := w.Write(c.Cookie())
|
|
||||||
return int64(n), err
|
|
||||||
}
|
|
||||||
|
|
||||||
var errNoCookies = errors.New("no cookies found")
|
|
||||||
|
|
||||||
// Parse parses Set-Cookie header.
|
|
||||||
func (c *Cookie) Parse(src string) error {
|
|
||||||
c.buf = append(c.buf[:0], src...)
|
|
||||||
return c.ParseBytes(c.buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseBytes parses Set-Cookie header.
|
|
||||||
func (c *Cookie) ParseBytes(src []byte) error {
|
|
||||||
c.Reset()
|
|
||||||
|
|
||||||
var s cookieScanner
|
|
||||||
s.b = src
|
|
||||||
|
|
||||||
kv := &c.bufKV
|
|
||||||
if !s.next(kv) {
|
|
||||||
return errNoCookies
|
|
||||||
}
|
|
||||||
|
|
||||||
c.key = append(c.key[:0], kv.key...)
|
|
||||||
c.value = append(c.value[:0], kv.value...)
|
|
||||||
|
|
||||||
for s.next(kv) {
|
|
||||||
if len(kv.key) == 0 && len(kv.value) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch string(kv.key) {
|
|
||||||
case "expires":
|
|
||||||
v := b2s(kv.value)
|
|
||||||
exptime, err := time.ParseInLocation(time.RFC1123, v, time.UTC)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.expire = exptime
|
|
||||||
case "domain":
|
|
||||||
c.domain = append(c.domain[:0], kv.value...)
|
|
||||||
case "path":
|
|
||||||
c.path = append(c.path[:0], kv.value...)
|
|
||||||
case "":
|
|
||||||
switch string(kv.value) {
|
|
||||||
case "HttpOnly":
|
|
||||||
c.httpOnly = true
|
|
||||||
case "secure":
|
|
||||||
c.secure = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendCookiePart(dst, key, value []byte) []byte {
|
|
||||||
dst = append(dst, ';', ' ')
|
|
||||||
dst = append(dst, key...)
|
|
||||||
dst = append(dst, '=')
|
|
||||||
return append(dst, value...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCookieKey(dst, src []byte) []byte {
|
|
||||||
n := bytes.IndexByte(src, '=')
|
|
||||||
if n >= 0 {
|
|
||||||
src = src[:n]
|
|
||||||
}
|
|
||||||
return decodeCookieArg(dst, src, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendRequestCookieBytes(dst []byte, cookies []argsKV) []byte {
|
|
||||||
for i, n := 0, len(cookies); i < n; i++ {
|
|
||||||
kv := &cookies[i]
|
|
||||||
if len(kv.key) > 0 {
|
|
||||||
dst = append(dst, kv.key...)
|
|
||||||
dst = append(dst, '=')
|
|
||||||
}
|
|
||||||
dst = append(dst, kv.value...)
|
|
||||||
if i+1 < n {
|
|
||||||
dst = append(dst, ';', ' ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseRequestCookies(cookies []argsKV, src []byte) []argsKV {
|
|
||||||
var s cookieScanner
|
|
||||||
s.b = src
|
|
||||||
var kv *argsKV
|
|
||||||
cookies, kv = allocArg(cookies)
|
|
||||||
for s.next(kv) {
|
|
||||||
if len(kv.key) > 0 || len(kv.value) > 0 {
|
|
||||||
cookies, kv = allocArg(cookies)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return releaseArg(cookies)
|
|
||||||
}
|
|
||||||
|
|
||||||
type cookieScanner struct {
|
|
||||||
b []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *cookieScanner) next(kv *argsKV) bool {
|
|
||||||
b := s.b
|
|
||||||
if len(b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
isKey := true
|
|
||||||
k := 0
|
|
||||||
for i, c := range b {
|
|
||||||
switch c {
|
|
||||||
case '=':
|
|
||||||
if isKey {
|
|
||||||
isKey = false
|
|
||||||
kv.key = decodeCookieArg(kv.key, b[:i], false)
|
|
||||||
k = i + 1
|
|
||||||
}
|
|
||||||
case ';':
|
|
||||||
if isKey {
|
|
||||||
kv.key = kv.key[:0]
|
|
||||||
}
|
|
||||||
kv.value = decodeCookieArg(kv.value, b[k:i], true)
|
|
||||||
s.b = b[i+1:]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if isKey {
|
|
||||||
kv.key = kv.key[:0]
|
|
||||||
}
|
|
||||||
kv.value = decodeCookieArg(kv.value, b[k:], true)
|
|
||||||
s.b = b[len(b):]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeCookieArg(dst, src []byte, skipQuotes bool) []byte {
|
|
||||||
for len(src) > 0 && src[0] == ' ' {
|
|
||||||
src = src[1:]
|
|
||||||
}
|
|
||||||
for len(src) > 0 && src[len(src)-1] == ' ' {
|
|
||||||
src = src[:len(src)-1]
|
|
||||||
}
|
|
||||||
if skipQuotes {
|
|
||||||
if len(src) > 1 && src[0] == '"' && src[len(src)-1] == '"' {
|
|
||||||
src = src[1 : len(src)-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return append(dst[:0], src...)
|
|
||||||
}
|
|
40
vendor/github.com/VictoriaMetrics/fasthttp/doc.go
generated
vendored
40
vendor/github.com/VictoriaMetrics/fasthttp/doc.go
generated
vendored
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
Package fasthttp provides fast HTTP server and client API.
|
|
||||||
|
|
||||||
Fasthttp provides the following features:
|
|
||||||
|
|
||||||
* Optimized for speed. Easily handles more than 100K qps and more than 1M
|
|
||||||
concurrent keep-alive connections on modern hardware.
|
|
||||||
* Optimized for low memory usage.
|
|
||||||
* Easy 'Connection: Upgrade' support via RequestCtx.Hijack.
|
|
||||||
* Server supports requests' pipelining. Multiple requests may be read from
|
|
||||||
a single network packet and multiple responses may be sent in a single
|
|
||||||
network packet. This may be useful for highly loaded REST services.
|
|
||||||
* Server provides the following anti-DoS limits:
|
|
||||||
|
|
||||||
* The number of concurrent connections.
|
|
||||||
* The number of concurrent connections per client IP.
|
|
||||||
* The number of requests per connection.
|
|
||||||
* Request read timeout.
|
|
||||||
* Response write timeout.
|
|
||||||
* Maximum request header size.
|
|
||||||
* Maximum request body size.
|
|
||||||
* Maximum request execution time.
|
|
||||||
* Maximum keep-alive connection lifetime.
|
|
||||||
* Early filtering out non-GET requests.
|
|
||||||
|
|
||||||
* A lot of additional useful info is exposed to request handler:
|
|
||||||
|
|
||||||
* Server and client address.
|
|
||||||
* Per-request logger.
|
|
||||||
* Unique request id.
|
|
||||||
* Request start time.
|
|
||||||
* Connection start time.
|
|
||||||
* Request sequence number for the current connection.
|
|
||||||
|
|
||||||
* Client supports automatic retry on idempotent requests' failure.
|
|
||||||
* Fasthttp API is designed with the ability to extend existing client
|
|
||||||
and server implementations or to write custom client and server
|
|
||||||
implementations from scratch.
|
|
||||||
*/
|
|
||||||
package fasthttp
|
|
2
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/doc.go
generated
vendored
2
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/doc.go
generated
vendored
|
@ -1,2 +0,0 @@
|
||||||
// Package fasthttputil provides utility functions for fasthttp.
|
|
||||||
package fasthttputil
|
|
5
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/ecdsa.key
generated
vendored
5
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/ecdsa.key
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MHcCAQEEIBpQbZ6a5jL1Yh4wdP6yZk4MKjYWArD/QOLENFw8vbELoAoGCCqGSM49
|
|
||||||
AwEHoUQDQgAEKQCZWgE2IBhb47ot8MIs1D4KSisHYlZ41IWyeutpjb0fjwwIhimh
|
|
||||||
pl1Qld1/d2j3Z3vVyfa5yD+ncV7qCFZuSg==
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
10
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/ecdsa.pem
generated
vendored
10
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/ecdsa.pem
generated
vendored
|
@ -1,10 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIBbTCCAROgAwIBAgIQPo718S+K+G7hc1SgTEU4QDAKBggqhkjOPQQDAjASMRAw
|
|
||||||
DgYDVQQKEwdBY21lIENvMB4XDTE3MDQyMDIxMDExNFoXDTE4MDQyMDIxMDExNFow
|
|
||||||
EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCkA
|
|
||||||
mVoBNiAYW+O6LfDCLNQ+CkorB2JWeNSFsnrraY29H48MCIYpoaZdUJXdf3do92d7
|
|
||||||
1cn2ucg/p3Fe6ghWbkqjSzBJMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
|
|
||||||
BgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggq
|
|
||||||
hkjOPQQDAgNIADBFAiEAoLAIQkvSuIcHUqyWroA6yWYw2fznlRH/uO9/hMCxUCEC
|
|
||||||
IClRYb/5O9eD/Eq/ozPnwNpsQHOeYefEhadJ/P82y0lG
|
|
||||||
-----END CERTIFICATE-----
|
|
84
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/inmemory_listener.go
generated
vendored
84
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/inmemory_listener.go
generated
vendored
|
@ -1,84 +0,0 @@
|
||||||
package fasthttputil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InmemoryListener provides in-memory dialer<->net.Listener implementation.
|
|
||||||
//
|
|
||||||
// It may be used either for fast in-process client<->server communcations
|
|
||||||
// without network stack overhead or for client<->server tests.
|
|
||||||
type InmemoryListener struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
closed bool
|
|
||||||
conns chan net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInmemoryListener returns new in-memory dialer<->net.Listener.
|
|
||||||
func NewInmemoryListener() *InmemoryListener {
|
|
||||||
return &InmemoryListener{
|
|
||||||
conns: make(chan net.Conn, 1024),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accept implements net.Listener's Accept.
|
|
||||||
//
|
|
||||||
// It is safe calling Accept from concurrently running goroutines.
|
|
||||||
//
|
|
||||||
// Accept returns new connection per each Dial call.
|
|
||||||
func (ln *InmemoryListener) Accept() (net.Conn, error) {
|
|
||||||
c, ok := <-ln.conns
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("InmemoryListener is already closed: use of closed network connection")
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close implements net.Listener's Close.
|
|
||||||
func (ln *InmemoryListener) Close() error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ln.lock.Lock()
|
|
||||||
if !ln.closed {
|
|
||||||
close(ln.conns)
|
|
||||||
ln.closed = true
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("InmemoryListener is already closed")
|
|
||||||
}
|
|
||||||
ln.lock.Unlock()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Addr implements net.Listener's Addr.
|
|
||||||
func (ln *InmemoryListener) Addr() net.Addr {
|
|
||||||
return &net.UnixAddr{
|
|
||||||
Name: "InmemoryListener",
|
|
||||||
Net: "memory",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial creates new client<->server connection, enqueues server side
|
|
||||||
// of the connection to Accept and returns client side of the connection.
|
|
||||||
//
|
|
||||||
// It is safe calling Dial from concurrently running goroutines.
|
|
||||||
func (ln *InmemoryListener) Dial() (net.Conn, error) {
|
|
||||||
pc := NewPipeConns()
|
|
||||||
cConn := pc.Conn1()
|
|
||||||
sConn := pc.Conn2()
|
|
||||||
ln.lock.Lock()
|
|
||||||
if !ln.closed {
|
|
||||||
ln.conns <- sConn
|
|
||||||
} else {
|
|
||||||
sConn.Close()
|
|
||||||
cConn.Close()
|
|
||||||
cConn = nil
|
|
||||||
}
|
|
||||||
ln.lock.Unlock()
|
|
||||||
|
|
||||||
if cConn == nil {
|
|
||||||
return nil, fmt.Errorf("InmemoryListener is already closed")
|
|
||||||
}
|
|
||||||
return cConn, nil
|
|
||||||
}
|
|
283
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/pipeconns.go
generated
vendored
283
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/pipeconns.go
generated
vendored
|
@ -1,283 +0,0 @@
|
||||||
package fasthttputil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewPipeConns returns new bi-directonal connection pipe.
|
|
||||||
func NewPipeConns() *PipeConns {
|
|
||||||
ch1 := make(chan *byteBuffer, 4)
|
|
||||||
ch2 := make(chan *byteBuffer, 4)
|
|
||||||
|
|
||||||
pc := &PipeConns{
|
|
||||||
stopCh: make(chan struct{}),
|
|
||||||
}
|
|
||||||
pc.c1.rCh = ch1
|
|
||||||
pc.c1.wCh = ch2
|
|
||||||
pc.c2.rCh = ch2
|
|
||||||
pc.c2.wCh = ch1
|
|
||||||
pc.c1.pc = pc
|
|
||||||
pc.c2.pc = pc
|
|
||||||
return pc
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipeConns provides bi-directional connection pipe,
|
|
||||||
// which use in-process memory as a transport.
|
|
||||||
//
|
|
||||||
// PipeConns must be created by calling NewPipeConns.
|
|
||||||
//
|
|
||||||
// PipeConns has the following additional features comparing to connections
|
|
||||||
// returned from net.Pipe():
|
|
||||||
//
|
|
||||||
// * It is faster.
|
|
||||||
// * It buffers Write calls, so there is no need to have concurrent goroutine
|
|
||||||
// calling Read in order to unblock each Write call.
|
|
||||||
// * It supports read and write deadlines.
|
|
||||||
//
|
|
||||||
type PipeConns struct {
|
|
||||||
c1 pipeConn
|
|
||||||
c2 pipeConn
|
|
||||||
stopCh chan struct{}
|
|
||||||
stopChLock sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conn1 returns the first end of bi-directional pipe.
|
|
||||||
//
|
|
||||||
// Data written to Conn1 may be read from Conn2.
|
|
||||||
// Data written to Conn2 may be read from Conn1.
|
|
||||||
func (pc *PipeConns) Conn1() net.Conn {
|
|
||||||
return &pc.c1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conn2 returns the second end of bi-directional pipe.
|
|
||||||
//
|
|
||||||
// Data written to Conn2 may be read from Conn1.
|
|
||||||
// Data written to Conn1 may be read from Conn2.
|
|
||||||
func (pc *PipeConns) Conn2() net.Conn {
|
|
||||||
return &pc.c2
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes pipe connections.
|
|
||||||
func (pc *PipeConns) Close() error {
|
|
||||||
pc.stopChLock.Lock()
|
|
||||||
select {
|
|
||||||
case <-pc.stopCh:
|
|
||||||
default:
|
|
||||||
close(pc.stopCh)
|
|
||||||
}
|
|
||||||
pc.stopChLock.Unlock()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type pipeConn struct {
|
|
||||||
b *byteBuffer
|
|
||||||
bb []byte
|
|
||||||
|
|
||||||
rCh chan *byteBuffer
|
|
||||||
wCh chan *byteBuffer
|
|
||||||
pc *PipeConns
|
|
||||||
|
|
||||||
readDeadlineTimer *time.Timer
|
|
||||||
writeDeadlineTimer *time.Timer
|
|
||||||
|
|
||||||
readDeadlineCh <-chan time.Time
|
|
||||||
writeDeadlineCh <-chan time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) Write(p []byte) (int, error) {
|
|
||||||
b := acquireByteBuffer()
|
|
||||||
b.b = append(b.b[:0], p...)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-c.pc.stopCh:
|
|
||||||
releaseByteBuffer(b)
|
|
||||||
return 0, errConnectionClosed
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case c.wCh <- b:
|
|
||||||
default:
|
|
||||||
select {
|
|
||||||
case c.wCh <- b:
|
|
||||||
case <-c.writeDeadlineCh:
|
|
||||||
c.writeDeadlineCh = closedDeadlineCh
|
|
||||||
return 0, ErrTimeout
|
|
||||||
case <-c.pc.stopCh:
|
|
||||||
releaseByteBuffer(b)
|
|
||||||
return 0, errConnectionClosed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) Read(p []byte) (int, error) {
|
|
||||||
mayBlock := true
|
|
||||||
nn := 0
|
|
||||||
for len(p) > 0 {
|
|
||||||
n, err := c.read(p, mayBlock)
|
|
||||||
nn += n
|
|
||||||
if err != nil {
|
|
||||||
if !mayBlock && err == errWouldBlock {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return nn, err
|
|
||||||
}
|
|
||||||
p = p[n:]
|
|
||||||
mayBlock = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return nn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) read(p []byte, mayBlock bool) (int, error) {
|
|
||||||
if len(c.bb) == 0 {
|
|
||||||
if err := c.readNextByteBuffer(mayBlock); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n := copy(p, c.bb)
|
|
||||||
c.bb = c.bb[n:]
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) readNextByteBuffer(mayBlock bool) error {
|
|
||||||
releaseByteBuffer(c.b)
|
|
||||||
c.b = nil
|
|
||||||
|
|
||||||
select {
|
|
||||||
case c.b = <-c.rCh:
|
|
||||||
default:
|
|
||||||
if !mayBlock {
|
|
||||||
return errWouldBlock
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case c.b = <-c.rCh:
|
|
||||||
case <-c.readDeadlineCh:
|
|
||||||
c.readDeadlineCh = closedDeadlineCh
|
|
||||||
// rCh may contain data when deadline is reached.
|
|
||||||
// Read the data before returning ErrTimeout.
|
|
||||||
select {
|
|
||||||
case c.b = <-c.rCh:
|
|
||||||
default:
|
|
||||||
return ErrTimeout
|
|
||||||
}
|
|
||||||
case <-c.pc.stopCh:
|
|
||||||
// rCh may contain data when stopCh is closed.
|
|
||||||
// Read the data before returning EOF.
|
|
||||||
select {
|
|
||||||
case c.b = <-c.rCh:
|
|
||||||
default:
|
|
||||||
return io.EOF
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.bb = c.b.b
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
errWouldBlock = errors.New("would block")
|
|
||||||
errConnectionClosed = errors.New("connection closed")
|
|
||||||
|
|
||||||
// ErrTimeout is returned from Read() or Write() on timeout.
|
|
||||||
ErrTimeout = errors.New("timeout")
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *pipeConn) Close() error {
|
|
||||||
return c.pc.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) LocalAddr() net.Addr {
|
|
||||||
return pipeAddr(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) RemoteAddr() net.Addr {
|
|
||||||
return pipeAddr(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) SetDeadline(deadline time.Time) error {
|
|
||||||
c.SetReadDeadline(deadline)
|
|
||||||
c.SetWriteDeadline(deadline)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) SetReadDeadline(deadline time.Time) error {
|
|
||||||
if c.readDeadlineTimer == nil {
|
|
||||||
c.readDeadlineTimer = time.NewTimer(time.Hour)
|
|
||||||
}
|
|
||||||
c.readDeadlineCh = updateTimer(c.readDeadlineTimer, deadline)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pipeConn) SetWriteDeadline(deadline time.Time) error {
|
|
||||||
if c.writeDeadlineTimer == nil {
|
|
||||||
c.writeDeadlineTimer = time.NewTimer(time.Hour)
|
|
||||||
}
|
|
||||||
c.writeDeadlineCh = updateTimer(c.writeDeadlineTimer, deadline)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateTimer(t *time.Timer, deadline time.Time) <-chan time.Time {
|
|
||||||
if !t.Stop() {
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if deadline.IsZero() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
d := -time.Since(deadline)
|
|
||||||
if d <= 0 {
|
|
||||||
return closedDeadlineCh
|
|
||||||
}
|
|
||||||
t.Reset(d)
|
|
||||||
return t.C
|
|
||||||
}
|
|
||||||
|
|
||||||
var closedDeadlineCh = func() <-chan time.Time {
|
|
||||||
ch := make(chan time.Time)
|
|
||||||
close(ch)
|
|
||||||
return ch
|
|
||||||
}()
|
|
||||||
|
|
||||||
type pipeAddr int
|
|
||||||
|
|
||||||
func (pipeAddr) Network() string {
|
|
||||||
return "pipe"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pipeAddr) String() string {
|
|
||||||
return "pipe"
|
|
||||||
}
|
|
||||||
|
|
||||||
type byteBuffer struct {
|
|
||||||
b []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquireByteBuffer() *byteBuffer {
|
|
||||||
return byteBufferPool.Get().(*byteBuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseByteBuffer(b *byteBuffer) {
|
|
||||||
if b != nil {
|
|
||||||
byteBufferPool.Put(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var byteBufferPool = &sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return &byteBuffer{
|
|
||||||
b: make([]byte, 1024),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
28
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/rsa.key
generated
vendored
28
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/rsa.key
generated
vendored
|
@ -1,28 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD4IQusAs8PJdnG
|
|
||||||
3mURt/AXtgC+ceqLOatJ49JJE1VPTkMAy+oE1f1XvkMrYsHqmDf6GWVzgVXryL4U
|
|
||||||
wq2/nJSm56ddhN55nI8oSN3dtywUB8/ShelEN73nlN77PeD9tl6NksPwWaKrqxq0
|
|
||||||
FlabRPZSQCfmgZbhDV8Sa8mfCkFU0G0lit6kLGceCKMvmW+9Bz7ebsYmVdmVMxmf
|
|
||||||
IJStFD44lWFTdUc65WISKEdW2ELcUefb0zOLw+0PCbXFGJH5x5ktksW8+BBk2Hkg
|
|
||||||
GeQRL/qPCccthbScO0VgNj3zJ3ZZL0ObSDAbvNDG85joeNjDNq5DT/BAZ0bOSbEF
|
|
||||||
sh+f9BAzAgMBAAECggEBAJWv2cq7Jw6MVwSRxYca38xuD6TUNBopgBvjREixURW2
|
|
||||||
sNUaLuMb9Omp7fuOaE2N5rcJ+xnjPGIxh/oeN5MQctz9gwn3zf6vY+15h97pUb4D
|
|
||||||
uGvYPRDaT8YVGS+X9NMZ4ZCmqW2lpWzKnCFoGHcy8yZLbcaxBsRdvKzwOYGoPiFb
|
|
||||||
K2QuhXZ/1UPmqK9i2DFKtj40X6vBszTNboFxOVpXrPu0FJwLVSDf2hSZ4fMM0DH3
|
|
||||||
YqwKcYf5te+hxGKgrqRA3tn0NCWii0in6QIwXMC+kMw1ebg/tZKqyDLMNptAK8J+
|
|
||||||
DVw9m5X1seUHS5ehU/g2jrQrtK5WYn7MrFK4lBzlRwECgYEA/d1TeANYECDWRRDk
|
|
||||||
B0aaRZs87Rwl/J9PsvbsKvtU/bX+OfSOUjOa9iQBqn0LmU8GqusEET/QVUfocVwV
|
|
||||||
Bggf/5qDLxz100Rj0ags/yE/kNr0Bb31kkkKHFMnCT06YasR7qKllwrAlPJvQv9x
|
|
||||||
IzBKq+T/Dx08Wep9bCRSFhzRCnsCgYEA+jdeZXTDr/Vz+D2B3nAw1frqYFfGnEVY
|
|
||||||
wqmoK3VXMDkGuxsloO2rN+SyiUo3JNiQNPDub/t7175GH5pmKtZOlftePANsUjBj
|
|
||||||
wZ1D0rI5Bxu/71ibIUYIRVmXsTEQkh/ozoh3jXCZ9+bLgYiYx7789IUZZSokFQ3D
|
|
||||||
FICUT9KJ36kCgYAGoq9Y1rWJjmIrYfqj2guUQC+CfxbbGIrrwZqAsRsSmpwvhZ3m
|
|
||||||
tiSZxG0quKQB+NfSxdvQW5ulbwC7Xc3K35F+i9pb8+TVBdeaFkw+yu6vaZmxQLrX
|
|
||||||
fQM/pEjD7A7HmMIaO7QaU5SfEAsqdCTP56Y8AftMuNXn/8IRfo2KuGwaWwKBgFpU
|
|
||||||
ILzJoVdlad9E/Rw7LjYhZfkv1uBVXIyxyKcfrkEXZSmozDXDdxsvcZCEfVHM6Ipk
|
|
||||||
K/+7LuMcqp4AFEAEq8wTOdq6daFaHLkpt/FZK6M4TlruhtpFOPkoNc3e45eM83OT
|
|
||||||
6mziKINJC1CQ6m65sQHpBtjxlKMRG8rL/D6wx9s5AoGBAMRlqNPMwglT3hvDmsAt
|
|
||||||
9Lf9pdmhERUlHhD8bj8mDaBj2Aqv7f6VRJaYZqP403pKKQexuqcn80mtjkSAPFkN
|
|
||||||
Cj7BVt/RXm5uoxDTnfi26RF9F6yNDEJ7UU9+peBr99aazF/fTgW/1GcMkQnum8uV
|
|
||||||
c257YgaWmjK9uB0Y2r2VxS0G
|
|
||||||
-----END PRIVATE KEY-----
|
|
17
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/rsa.pem
generated
vendored
17
vendor/github.com/VictoriaMetrics/fasthttp/fasthttputil/rsa.pem
generated
vendored
|
@ -1,17 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICujCCAaKgAwIBAgIJAMbXnKZ/cikUMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
|
||||||
BAMTCnVidW50dS5uYW4wHhcNMTUwMjA0MDgwMTM5WhcNMjUwMjAxMDgwMTM5WjAV
|
|
||||||
MRMwEQYDVQQDEwp1YnVudHUubmFuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
||||||
CgKCAQEA+CELrALPDyXZxt5lEbfwF7YAvnHqizmrSePSSRNVT05DAMvqBNX9V75D
|
|
||||||
K2LB6pg3+hllc4FV68i+FMKtv5yUpuenXYTeeZyPKEjd3bcsFAfP0oXpRDe955Te
|
|
||||||
+z3g/bZejZLD8Fmiq6satBZWm0T2UkAn5oGW4Q1fEmvJnwpBVNBtJYrepCxnHgij
|
|
||||||
L5lvvQc+3m7GJlXZlTMZnyCUrRQ+OJVhU3VHOuViEihHVthC3FHn29Mzi8PtDwm1
|
|
||||||
xRiR+ceZLZLFvPgQZNh5IBnkES/6jwnHLYW0nDtFYDY98yd2WS9Dm0gwG7zQxvOY
|
|
||||||
6HjYwzauQ0/wQGdGzkmxBbIfn/QQMwIDAQABow0wCzAJBgNVHRMEAjAAMA0GCSqG
|
|
||||||
SIb3DQEBCwUAA4IBAQBQjKm/4KN/iTgXbLTL3i7zaxYXFLXsnT1tF+ay4VA8aj98
|
|
||||||
L3JwRTciZ3A5iy/W4VSCt3eASwOaPWHKqDBB5RTtL73LoAqsWmO3APOGQAbixcQ2
|
|
||||||
45GXi05OKeyiYRi1Nvq7Unv9jUkRDHUYVPZVSAjCpsXzPhFkmZoTRxmx5l0ZF7Li
|
|
||||||
K91lI5h+eFq0dwZwrmlPambyh1vQUi70VHv8DNToVU29kel7YLbxGbuqETfhrcy6
|
|
||||||
X+Mha6RYITkAn5FqsZcKMsc9eYGEF4l3XV+oS7q6xfTxktYJMFTI18J0lQ2Lv/CI
|
|
||||||
whdMnYGntDQBE/iFCrJEGNsKGc38796GBOb5j+zd
|
|
||||||
-----END CERTIFICATE-----
|
|
1252
vendor/github.com/VictoriaMetrics/fasthttp/fs.go
generated
vendored
1252
vendor/github.com/VictoriaMetrics/fasthttp/fs.go
generated
vendored
File diff suppressed because it is too large
Load diff
9
vendor/github.com/VictoriaMetrics/fasthttp/go.mod
generated
vendored
9
vendor/github.com/VictoriaMetrics/fasthttp/go.mod
generated
vendored
|
@ -1,9 +0,0 @@
|
||||||
module github.com/VictoriaMetrics/fasthttp
|
|
||||||
|
|
||||||
go 1.13
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/klauspost/compress v1.11.0
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0
|
|
||||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a
|
|
||||||
)
|
|
6
vendor/github.com/VictoriaMetrics/fasthttp/go.sum
generated
vendored
6
vendor/github.com/VictoriaMetrics/fasthttp/go.sum
generated
vendored
|
@ -1,6 +0,0 @@
|
||||||
github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg=
|
|
||||||
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
|
||||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
|
|
||||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
|
2037
vendor/github.com/VictoriaMetrics/fasthttp/header.go
generated
vendored
2037
vendor/github.com/VictoriaMetrics/fasthttp/header.go
generated
vendored
File diff suppressed because it is too large
Load diff
1714
vendor/github.com/VictoriaMetrics/fasthttp/http.go
generated
vendored
1714
vendor/github.com/VictoriaMetrics/fasthttp/http.go
generated
vendored
File diff suppressed because it is too large
Load diff
183
vendor/github.com/VictoriaMetrics/fasthttp/lbclient.go
generated
vendored
183
vendor/github.com/VictoriaMetrics/fasthttp/lbclient.go
generated
vendored
|
@ -1,183 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BalancingClient is the interface for clients, which may be passed
|
|
||||||
// to LBClient.Clients.
|
|
||||||
type BalancingClient interface {
|
|
||||||
DoDeadline(req *Request, resp *Response, deadline time.Time) error
|
|
||||||
PendingRequests() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// LBClient balances requests among available LBClient.Clients.
|
|
||||||
//
|
|
||||||
// It has the following features:
|
|
||||||
//
|
|
||||||
// - Balances load among available clients using 'least loaded' + 'round robin'
|
|
||||||
// hybrid technique.
|
|
||||||
// - Dynamically decreases load on unhealthy clients.
|
|
||||||
//
|
|
||||||
// It is forbidden copying LBClient instances. Create new instances instead.
|
|
||||||
//
|
|
||||||
// It is safe calling LBClient methods from concurrently running goroutines.
|
|
||||||
type LBClient struct {
|
|
||||||
noCopy noCopy
|
|
||||||
|
|
||||||
// Clients must contain non-zero clients list.
|
|
||||||
// Incoming requests are balanced among these clients.
|
|
||||||
Clients []BalancingClient
|
|
||||||
|
|
||||||
// HealthCheck is a callback called after each request.
|
|
||||||
//
|
|
||||||
// The request, response and the error returned by the client
|
|
||||||
// is passed to HealthCheck, so the callback may determine whether
|
|
||||||
// the client is healthy.
|
|
||||||
//
|
|
||||||
// Load on the current client is decreased if HealthCheck returns false.
|
|
||||||
//
|
|
||||||
// By default HealthCheck returns false if err != nil.
|
|
||||||
HealthCheck func(req *Request, resp *Response, err error) bool
|
|
||||||
|
|
||||||
// Timeout is the request timeout used when calling LBClient.Do.
|
|
||||||
//
|
|
||||||
// DefaultLBClientTimeout is used by default.
|
|
||||||
Timeout time.Duration
|
|
||||||
|
|
||||||
cs []*lbClient
|
|
||||||
|
|
||||||
// nextIdx is for spreading requests among equally loaded clients
|
|
||||||
// in a round-robin fashion.
|
|
||||||
nextIdx uint32
|
|
||||||
|
|
||||||
once sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultLBClientTimeout is the default request timeout used by LBClient
|
|
||||||
// when calling LBClient.Do.
|
|
||||||
//
|
|
||||||
// The timeout may be overriden via LBClient.Timeout.
|
|
||||||
const DefaultLBClientTimeout = time.Second
|
|
||||||
|
|
||||||
// DoDeadline calls DoDeadline on the least loaded client
|
|
||||||
func (cc *LBClient) DoDeadline(req *Request, resp *Response, deadline time.Time) error {
|
|
||||||
return cc.get().DoDeadline(req, resp, deadline)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoTimeout calculates deadline and calls DoDeadline on the least loaded client
|
|
||||||
func (cc *LBClient) DoTimeout(req *Request, resp *Response, timeout time.Duration) error {
|
|
||||||
deadline := time.Now().Add(timeout)
|
|
||||||
return cc.get().DoDeadline(req, resp, deadline)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do calls calculates deadline using LBClient.Timeout and calls DoDeadline
|
|
||||||
// on the least loaded client.
|
|
||||||
func (cc *LBClient) Do(req *Request, resp *Response) error {
|
|
||||||
timeout := cc.Timeout
|
|
||||||
if timeout <= 0 {
|
|
||||||
timeout = DefaultLBClientTimeout
|
|
||||||
}
|
|
||||||
return cc.DoTimeout(req, resp, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *LBClient) init() {
|
|
||||||
if len(cc.Clients) == 0 {
|
|
||||||
panic("BUG: LBClient.Clients cannot be empty")
|
|
||||||
}
|
|
||||||
for _, c := range cc.Clients {
|
|
||||||
cc.cs = append(cc.cs, &lbClient{
|
|
||||||
c: c,
|
|
||||||
healthCheck: cc.HealthCheck,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Randomize nextIdx in order to prevent initial servers'
|
|
||||||
// hammering from a cluster of identical LBClients.
|
|
||||||
cc.nextIdx = uint32(time.Now().UnixNano())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *LBClient) get() *lbClient {
|
|
||||||
cc.once.Do(cc.init)
|
|
||||||
|
|
||||||
cs := cc.cs
|
|
||||||
idx := atomic.AddUint32(&cc.nextIdx, 1)
|
|
||||||
idx %= uint32(len(cs))
|
|
||||||
|
|
||||||
minC := cs[idx]
|
|
||||||
minN := minC.PendingRequests()
|
|
||||||
if minN == 0 {
|
|
||||||
return minC
|
|
||||||
}
|
|
||||||
for _, c := range cs[idx+1:] {
|
|
||||||
n := c.PendingRequests()
|
|
||||||
if n == 0 {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
if n < minN {
|
|
||||||
minC = c
|
|
||||||
minN = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, c := range cs[:idx] {
|
|
||||||
n := c.PendingRequests()
|
|
||||||
if n == 0 {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
if n < minN {
|
|
||||||
minC = c
|
|
||||||
minN = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return minC
|
|
||||||
}
|
|
||||||
|
|
||||||
type lbClient struct {
|
|
||||||
c BalancingClient
|
|
||||||
healthCheck func(req *Request, resp *Response, err error) bool
|
|
||||||
penalty uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *lbClient) DoDeadline(req *Request, resp *Response, deadline time.Time) error {
|
|
||||||
err := c.c.DoDeadline(req, resp, deadline)
|
|
||||||
if !c.isHealthy(req, resp, err) && c.incPenalty() {
|
|
||||||
// Penalize the client returning error, so the next requests
|
|
||||||
// are routed to another clients.
|
|
||||||
time.AfterFunc(penaltyDuration, c.decPenalty)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *lbClient) PendingRequests() int {
|
|
||||||
n := c.c.PendingRequests()
|
|
||||||
m := atomic.LoadUint32(&c.penalty)
|
|
||||||
return n + int(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *lbClient) isHealthy(req *Request, resp *Response, err error) bool {
|
|
||||||
if c.healthCheck == nil {
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
return c.healthCheck(req, resp, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *lbClient) incPenalty() bool {
|
|
||||||
m := atomic.AddUint32(&c.penalty, 1)
|
|
||||||
if m > maxPenalty {
|
|
||||||
c.decPenalty()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *lbClient) decPenalty() {
|
|
||||||
atomic.AddUint32(&c.penalty, ^uint32(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxPenalty = 300
|
|
||||||
|
|
||||||
penaltyDuration = 3 * time.Second
|
|
||||||
)
|
|
9
vendor/github.com/VictoriaMetrics/fasthttp/nocopy.go
generated
vendored
9
vendor/github.com/VictoriaMetrics/fasthttp/nocopy.go
generated
vendored
|
@ -1,9 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
// Embed this type into a struct, which mustn't be copied,
|
|
||||||
// so `go vet` gives a warning if this struct is copied.
|
|
||||||
//
|
|
||||||
// See https://github.com/golang/go/issues/8005#issuecomment-190753527 for details.
|
|
||||||
type noCopy struct{}
|
|
||||||
|
|
||||||
func (*noCopy) Lock() {}
|
|
100
vendor/github.com/VictoriaMetrics/fasthttp/peripconn.go
generated
vendored
100
vendor/github.com/VictoriaMetrics/fasthttp/peripconn.go
generated
vendored
|
@ -1,100 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type perIPConnCounter struct {
|
|
||||||
pool sync.Pool
|
|
||||||
lock sync.Mutex
|
|
||||||
m map[uint32]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *perIPConnCounter) Register(ip uint32) int {
|
|
||||||
cc.lock.Lock()
|
|
||||||
if cc.m == nil {
|
|
||||||
cc.m = make(map[uint32]int)
|
|
||||||
}
|
|
||||||
n := cc.m[ip] + 1
|
|
||||||
cc.m[ip] = n
|
|
||||||
cc.lock.Unlock()
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *perIPConnCounter) Unregister(ip uint32) {
|
|
||||||
cc.lock.Lock()
|
|
||||||
if cc.m == nil {
|
|
||||||
cc.lock.Unlock()
|
|
||||||
panic("BUG: perIPConnCounter.Register() wasn't called")
|
|
||||||
}
|
|
||||||
n := cc.m[ip] - 1
|
|
||||||
if n < 0 {
|
|
||||||
cc.lock.Unlock()
|
|
||||||
panic(fmt.Sprintf("BUG: negative per-ip counter=%d for ip=%d", n, ip))
|
|
||||||
}
|
|
||||||
cc.m[ip] = n
|
|
||||||
cc.lock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
type perIPConn struct {
|
|
||||||
net.Conn
|
|
||||||
|
|
||||||
ip uint32
|
|
||||||
perIPConnCounter *perIPConnCounter
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquirePerIPConn(conn net.Conn, ip uint32, counter *perIPConnCounter) *perIPConn {
|
|
||||||
v := counter.pool.Get()
|
|
||||||
if v == nil {
|
|
||||||
v = &perIPConn{
|
|
||||||
perIPConnCounter: counter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c := v.(*perIPConn)
|
|
||||||
c.Conn = conn
|
|
||||||
c.ip = ip
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func releasePerIPConn(c *perIPConn) {
|
|
||||||
c.Conn = nil
|
|
||||||
c.perIPConnCounter.pool.Put(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *perIPConn) Close() error {
|
|
||||||
err := c.Conn.Close()
|
|
||||||
c.perIPConnCounter.Unregister(c.ip)
|
|
||||||
releasePerIPConn(c)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUint32IP(c net.Conn) uint32 {
|
|
||||||
return ip2uint32(getConnIP4(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getConnIP4(c net.Conn) net.IP {
|
|
||||||
addr := c.RemoteAddr()
|
|
||||||
ipAddr, ok := addr.(*net.TCPAddr)
|
|
||||||
if !ok {
|
|
||||||
return net.IPv4zero
|
|
||||||
}
|
|
||||||
return ipAddr.IP.To4()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ip2uint32(ip net.IP) uint32 {
|
|
||||||
if len(ip) != 4 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return uint32(ip[0])<<24 | uint32(ip[1])<<16 | uint32(ip[2])<<8 | uint32(ip[3])
|
|
||||||
}
|
|
||||||
|
|
||||||
func uint322ip(ip uint32) net.IP {
|
|
||||||
b := make([]byte, 4)
|
|
||||||
b[0] = byte(ip >> 24)
|
|
||||||
b[1] = byte(ip >> 16)
|
|
||||||
b[2] = byte(ip >> 8)
|
|
||||||
b[3] = byte(ip)
|
|
||||||
return b
|
|
||||||
}
|
|
1982
vendor/github.com/VictoriaMetrics/fasthttp/server.go
generated
vendored
1982
vendor/github.com/VictoriaMetrics/fasthttp/server.go
generated
vendored
File diff suppressed because it is too large
Load diff
28
vendor/github.com/VictoriaMetrics/fasthttp/ssl-cert-snakeoil.key
generated
vendored
28
vendor/github.com/VictoriaMetrics/fasthttp/ssl-cert-snakeoil.key
generated
vendored
|
@ -1,28 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD4IQusAs8PJdnG
|
|
||||||
3mURt/AXtgC+ceqLOatJ49JJE1VPTkMAy+oE1f1XvkMrYsHqmDf6GWVzgVXryL4U
|
|
||||||
wq2/nJSm56ddhN55nI8oSN3dtywUB8/ShelEN73nlN77PeD9tl6NksPwWaKrqxq0
|
|
||||||
FlabRPZSQCfmgZbhDV8Sa8mfCkFU0G0lit6kLGceCKMvmW+9Bz7ebsYmVdmVMxmf
|
|
||||||
IJStFD44lWFTdUc65WISKEdW2ELcUefb0zOLw+0PCbXFGJH5x5ktksW8+BBk2Hkg
|
|
||||||
GeQRL/qPCccthbScO0VgNj3zJ3ZZL0ObSDAbvNDG85joeNjDNq5DT/BAZ0bOSbEF
|
|
||||||
sh+f9BAzAgMBAAECggEBAJWv2cq7Jw6MVwSRxYca38xuD6TUNBopgBvjREixURW2
|
|
||||||
sNUaLuMb9Omp7fuOaE2N5rcJ+xnjPGIxh/oeN5MQctz9gwn3zf6vY+15h97pUb4D
|
|
||||||
uGvYPRDaT8YVGS+X9NMZ4ZCmqW2lpWzKnCFoGHcy8yZLbcaxBsRdvKzwOYGoPiFb
|
|
||||||
K2QuhXZ/1UPmqK9i2DFKtj40X6vBszTNboFxOVpXrPu0FJwLVSDf2hSZ4fMM0DH3
|
|
||||||
YqwKcYf5te+hxGKgrqRA3tn0NCWii0in6QIwXMC+kMw1ebg/tZKqyDLMNptAK8J+
|
|
||||||
DVw9m5X1seUHS5ehU/g2jrQrtK5WYn7MrFK4lBzlRwECgYEA/d1TeANYECDWRRDk
|
|
||||||
B0aaRZs87Rwl/J9PsvbsKvtU/bX+OfSOUjOa9iQBqn0LmU8GqusEET/QVUfocVwV
|
|
||||||
Bggf/5qDLxz100Rj0ags/yE/kNr0Bb31kkkKHFMnCT06YasR7qKllwrAlPJvQv9x
|
|
||||||
IzBKq+T/Dx08Wep9bCRSFhzRCnsCgYEA+jdeZXTDr/Vz+D2B3nAw1frqYFfGnEVY
|
|
||||||
wqmoK3VXMDkGuxsloO2rN+SyiUo3JNiQNPDub/t7175GH5pmKtZOlftePANsUjBj
|
|
||||||
wZ1D0rI5Bxu/71ibIUYIRVmXsTEQkh/ozoh3jXCZ9+bLgYiYx7789IUZZSokFQ3D
|
|
||||||
FICUT9KJ36kCgYAGoq9Y1rWJjmIrYfqj2guUQC+CfxbbGIrrwZqAsRsSmpwvhZ3m
|
|
||||||
tiSZxG0quKQB+NfSxdvQW5ulbwC7Xc3K35F+i9pb8+TVBdeaFkw+yu6vaZmxQLrX
|
|
||||||
fQM/pEjD7A7HmMIaO7QaU5SfEAsqdCTP56Y8AftMuNXn/8IRfo2KuGwaWwKBgFpU
|
|
||||||
ILzJoVdlad9E/Rw7LjYhZfkv1uBVXIyxyKcfrkEXZSmozDXDdxsvcZCEfVHM6Ipk
|
|
||||||
K/+7LuMcqp4AFEAEq8wTOdq6daFaHLkpt/FZK6M4TlruhtpFOPkoNc3e45eM83OT
|
|
||||||
6mziKINJC1CQ6m65sQHpBtjxlKMRG8rL/D6wx9s5AoGBAMRlqNPMwglT3hvDmsAt
|
|
||||||
9Lf9pdmhERUlHhD8bj8mDaBj2Aqv7f6VRJaYZqP403pKKQexuqcn80mtjkSAPFkN
|
|
||||||
Cj7BVt/RXm5uoxDTnfi26RF9F6yNDEJ7UU9+peBr99aazF/fTgW/1GcMkQnum8uV
|
|
||||||
c257YgaWmjK9uB0Y2r2VxS0G
|
|
||||||
-----END PRIVATE KEY-----
|
|
17
vendor/github.com/VictoriaMetrics/fasthttp/ssl-cert-snakeoil.pem
generated
vendored
17
vendor/github.com/VictoriaMetrics/fasthttp/ssl-cert-snakeoil.pem
generated
vendored
|
@ -1,17 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICujCCAaKgAwIBAgIJAMbXnKZ/cikUMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
|
||||||
BAMTCnVidW50dS5uYW4wHhcNMTUwMjA0MDgwMTM5WhcNMjUwMjAxMDgwMTM5WjAV
|
|
||||||
MRMwEQYDVQQDEwp1YnVudHUubmFuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
||||||
CgKCAQEA+CELrALPDyXZxt5lEbfwF7YAvnHqizmrSePSSRNVT05DAMvqBNX9V75D
|
|
||||||
K2LB6pg3+hllc4FV68i+FMKtv5yUpuenXYTeeZyPKEjd3bcsFAfP0oXpRDe955Te
|
|
||||||
+z3g/bZejZLD8Fmiq6satBZWm0T2UkAn5oGW4Q1fEmvJnwpBVNBtJYrepCxnHgij
|
|
||||||
L5lvvQc+3m7GJlXZlTMZnyCUrRQ+OJVhU3VHOuViEihHVthC3FHn29Mzi8PtDwm1
|
|
||||||
xRiR+ceZLZLFvPgQZNh5IBnkES/6jwnHLYW0nDtFYDY98yd2WS9Dm0gwG7zQxvOY
|
|
||||||
6HjYwzauQ0/wQGdGzkmxBbIfn/QQMwIDAQABow0wCzAJBgNVHRMEAjAAMA0GCSqG
|
|
||||||
SIb3DQEBCwUAA4IBAQBQjKm/4KN/iTgXbLTL3i7zaxYXFLXsnT1tF+ay4VA8aj98
|
|
||||||
L3JwRTciZ3A5iy/W4VSCt3eASwOaPWHKqDBB5RTtL73LoAqsWmO3APOGQAbixcQ2
|
|
||||||
45GXi05OKeyiYRi1Nvq7Unv9jUkRDHUYVPZVSAjCpsXzPhFkmZoTRxmx5l0ZF7Li
|
|
||||||
K91lI5h+eFq0dwZwrmlPambyh1vQUi70VHv8DNToVU29kel7YLbxGbuqETfhrcy6
|
|
||||||
X+Mha6RYITkAn5FqsZcKMsc9eYGEF4l3XV+oS7q6xfTxktYJMFTI18J0lQ2Lv/CI
|
|
||||||
whdMnYGntDQBE/iFCrJEGNsKGc38796GBOb5j+zd
|
|
||||||
-----END CERTIFICATE-----
|
|
3
vendor/github.com/VictoriaMetrics/fasthttp/stackless/doc.go
generated
vendored
3
vendor/github.com/VictoriaMetrics/fasthttp/stackless/doc.go
generated
vendored
|
@ -1,3 +0,0 @@
|
||||||
// Package stackless provides functionality that may save stack space
|
|
||||||
// for high number of concurrently running goroutines.
|
|
||||||
package stackless
|
|
79
vendor/github.com/VictoriaMetrics/fasthttp/stackless/func.go
generated
vendored
79
vendor/github.com/VictoriaMetrics/fasthttp/stackless/func.go
generated
vendored
|
@ -1,79 +0,0 @@
|
||||||
package stackless
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewFunc returns stackless wrapper for the function f.
|
|
||||||
//
|
|
||||||
// Unlike f, the returned stackless wrapper doesn't use stack space
|
|
||||||
// on the goroutine that calls it.
|
|
||||||
// The wrapper may save a lot of stack space if the following conditions
|
|
||||||
// are met:
|
|
||||||
//
|
|
||||||
// - f doesn't contain blocking calls on network, I/O or channels;
|
|
||||||
// - f uses a lot of stack space;
|
|
||||||
// - the wrapper is called from high number of concurrent goroutines.
|
|
||||||
//
|
|
||||||
// The stackless wrapper returns false if the call cannot be processed
|
|
||||||
// at the moment due to high load.
|
|
||||||
func NewFunc(f func(ctx interface{})) func(ctx interface{}) bool {
|
|
||||||
if f == nil {
|
|
||||||
panic("BUG: f cannot be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
funcWorkCh := make(chan *funcWork, runtime.GOMAXPROCS(-1)*2048)
|
|
||||||
onceInit := func() {
|
|
||||||
n := runtime.GOMAXPROCS(-1)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
go funcWorker(funcWorkCh, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var once sync.Once
|
|
||||||
|
|
||||||
return func(ctx interface{}) bool {
|
|
||||||
once.Do(onceInit)
|
|
||||||
fw := getFuncWork()
|
|
||||||
fw.ctx = ctx
|
|
||||||
|
|
||||||
select {
|
|
||||||
case funcWorkCh <- fw:
|
|
||||||
default:
|
|
||||||
putFuncWork(fw)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
<-fw.done
|
|
||||||
putFuncWork(fw)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func funcWorker(funcWorkCh <-chan *funcWork, f func(ctx interface{})) {
|
|
||||||
for fw := range funcWorkCh {
|
|
||||||
f(fw.ctx)
|
|
||||||
fw.done <- struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFuncWork() *funcWork {
|
|
||||||
v := funcWorkPool.Get()
|
|
||||||
if v == nil {
|
|
||||||
v = &funcWork{
|
|
||||||
done: make(chan struct{}, 1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v.(*funcWork)
|
|
||||||
}
|
|
||||||
|
|
||||||
func putFuncWork(fw *funcWork) {
|
|
||||||
fw.ctx = nil
|
|
||||||
funcWorkPool.Put(fw)
|
|
||||||
}
|
|
||||||
|
|
||||||
var funcWorkPool sync.Pool
|
|
||||||
|
|
||||||
type funcWork struct {
|
|
||||||
ctx interface{}
|
|
||||||
done chan struct{}
|
|
||||||
}
|
|
138
vendor/github.com/VictoriaMetrics/fasthttp/stackless/writer.go
generated
vendored
138
vendor/github.com/VictoriaMetrics/fasthttp/stackless/writer.go
generated
vendored
|
@ -1,138 +0,0 @@
|
||||||
package stackless
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/valyala/bytebufferpool"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Writer is an interface stackless writer must conform to.
|
|
||||||
//
|
|
||||||
// The interface contains common subset for Writers from compress/* packages.
|
|
||||||
type Writer interface {
|
|
||||||
Write(p []byte) (int, error)
|
|
||||||
Flush() error
|
|
||||||
Close() error
|
|
||||||
Reset(w io.Writer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWriterFunc must return new writer that will be wrapped into
|
|
||||||
// stackless writer.
|
|
||||||
type NewWriterFunc func(w io.Writer) Writer
|
|
||||||
|
|
||||||
// NewWriter creates a stackless writer around a writer returned
|
|
||||||
// from newWriter.
|
|
||||||
//
|
|
||||||
// The returned writer writes data to dstW.
|
|
||||||
//
|
|
||||||
// Writers that use a lot of stack space may be wrapped into stackless writer,
|
|
||||||
// thus saving stack space for high number of concurrently running goroutines.
|
|
||||||
func NewWriter(dstW io.Writer, newWriter NewWriterFunc) Writer {
|
|
||||||
w := &writer{
|
|
||||||
dstW: dstW,
|
|
||||||
}
|
|
||||||
w.zw = newWriter(&w.xw)
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
type writer struct {
|
|
||||||
dstW io.Writer
|
|
||||||
zw Writer
|
|
||||||
xw xWriter
|
|
||||||
|
|
||||||
err error
|
|
||||||
n int
|
|
||||||
|
|
||||||
p []byte
|
|
||||||
op op
|
|
||||||
}
|
|
||||||
|
|
||||||
type op int
|
|
||||||
|
|
||||||
const (
|
|
||||||
opWrite op = iota
|
|
||||||
opFlush
|
|
||||||
opClose
|
|
||||||
opReset
|
|
||||||
)
|
|
||||||
|
|
||||||
func (w *writer) Write(p []byte) (int, error) {
|
|
||||||
w.p = p
|
|
||||||
err := w.do(opWrite)
|
|
||||||
w.p = nil
|
|
||||||
return w.n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *writer) Flush() error {
|
|
||||||
return w.do(opFlush)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *writer) Close() error {
|
|
||||||
return w.do(opClose)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *writer) Reset(dstW io.Writer) {
|
|
||||||
w.xw.Reset()
|
|
||||||
w.do(opReset)
|
|
||||||
w.dstW = dstW
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *writer) do(op op) error {
|
|
||||||
w.op = op
|
|
||||||
if !stacklessWriterFunc(w) {
|
|
||||||
return errHighLoad
|
|
||||||
}
|
|
||||||
err := w.err
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if w.xw.bb != nil && len(w.xw.bb.B) > 0 {
|
|
||||||
_, err = w.dstW.Write(w.xw.bb.B)
|
|
||||||
}
|
|
||||||
w.xw.Reset()
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var errHighLoad = errors.New("cannot compress data due to high load")
|
|
||||||
|
|
||||||
var stacklessWriterFunc = NewFunc(writerFunc)
|
|
||||||
|
|
||||||
func writerFunc(ctx interface{}) {
|
|
||||||
w := ctx.(*writer)
|
|
||||||
switch w.op {
|
|
||||||
case opWrite:
|
|
||||||
w.n, w.err = w.zw.Write(w.p)
|
|
||||||
case opFlush:
|
|
||||||
w.err = w.zw.Flush()
|
|
||||||
case opClose:
|
|
||||||
w.err = w.zw.Close()
|
|
||||||
case opReset:
|
|
||||||
w.zw.Reset(&w.xw)
|
|
||||||
w.err = nil
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("BUG: unexpected op: %d", w.op))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type xWriter struct {
|
|
||||||
bb *bytebufferpool.ByteBuffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *xWriter) Write(p []byte) (int, error) {
|
|
||||||
if w.bb == nil {
|
|
||||||
w.bb = bufferPool.Get()
|
|
||||||
}
|
|
||||||
w.bb.Write(p)
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *xWriter) Reset() {
|
|
||||||
if w.bb != nil {
|
|
||||||
bufferPool.Put(w.bb)
|
|
||||||
w.bb = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var bufferPool bytebufferpool.Pool
|
|
176
vendor/github.com/VictoriaMetrics/fasthttp/status.go
generated
vendored
176
vendor/github.com/VictoriaMetrics/fasthttp/status.go
generated
vendored
|
@ -1,176 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HTTP status codes were stolen from net/http.
|
|
||||||
const (
|
|
||||||
StatusContinue = 100 // RFC 7231, 6.2.1
|
|
||||||
StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2
|
|
||||||
StatusProcessing = 102 // RFC 2518, 10.1
|
|
||||||
|
|
||||||
StatusOK = 200 // RFC 7231, 6.3.1
|
|
||||||
StatusCreated = 201 // RFC 7231, 6.3.2
|
|
||||||
StatusAccepted = 202 // RFC 7231, 6.3.3
|
|
||||||
StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4
|
|
||||||
StatusNoContent = 204 // RFC 7231, 6.3.5
|
|
||||||
StatusResetContent = 205 // RFC 7231, 6.3.6
|
|
||||||
StatusPartialContent = 206 // RFC 7233, 4.1
|
|
||||||
StatusMultiStatus = 207 // RFC 4918, 11.1
|
|
||||||
StatusAlreadyReported = 208 // RFC 5842, 7.1
|
|
||||||
StatusIMUsed = 226 // RFC 3229, 10.4.1
|
|
||||||
|
|
||||||
StatusMultipleChoices = 300 // RFC 7231, 6.4.1
|
|
||||||
StatusMovedPermanently = 301 // RFC 7231, 6.4.2
|
|
||||||
StatusFound = 302 // RFC 7231, 6.4.3
|
|
||||||
StatusSeeOther = 303 // RFC 7231, 6.4.4
|
|
||||||
StatusNotModified = 304 // RFC 7232, 4.1
|
|
||||||
StatusUseProxy = 305 // RFC 7231, 6.4.5
|
|
||||||
_ = 306 // RFC 7231, 6.4.6 (Unused)
|
|
||||||
StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7
|
|
||||||
StatusPermanentRedirect = 308 // RFC 7538, 3
|
|
||||||
|
|
||||||
StatusBadRequest = 400 // RFC 7231, 6.5.1
|
|
||||||
StatusUnauthorized = 401 // RFC 7235, 3.1
|
|
||||||
StatusPaymentRequired = 402 // RFC 7231, 6.5.2
|
|
||||||
StatusForbidden = 403 // RFC 7231, 6.5.3
|
|
||||||
StatusNotFound = 404 // RFC 7231, 6.5.4
|
|
||||||
StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5
|
|
||||||
StatusNotAcceptable = 406 // RFC 7231, 6.5.6
|
|
||||||
StatusProxyAuthRequired = 407 // RFC 7235, 3.2
|
|
||||||
StatusRequestTimeout = 408 // RFC 7231, 6.5.7
|
|
||||||
StatusConflict = 409 // RFC 7231, 6.5.8
|
|
||||||
StatusGone = 410 // RFC 7231, 6.5.9
|
|
||||||
StatusLengthRequired = 411 // RFC 7231, 6.5.10
|
|
||||||
StatusPreconditionFailed = 412 // RFC 7232, 4.2
|
|
||||||
StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11
|
|
||||||
StatusRequestURITooLong = 414 // RFC 7231, 6.5.12
|
|
||||||
StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13
|
|
||||||
StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4
|
|
||||||
StatusExpectationFailed = 417 // RFC 7231, 6.5.14
|
|
||||||
StatusTeapot = 418 // RFC 7168, 2.3.3
|
|
||||||
StatusUnprocessableEntity = 422 // RFC 4918, 11.2
|
|
||||||
StatusLocked = 423 // RFC 4918, 11.3
|
|
||||||
StatusFailedDependency = 424 // RFC 4918, 11.4
|
|
||||||
StatusUpgradeRequired = 426 // RFC 7231, 6.5.15
|
|
||||||
StatusPreconditionRequired = 428 // RFC 6585, 3
|
|
||||||
StatusTooManyRequests = 429 // RFC 6585, 4
|
|
||||||
StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5
|
|
||||||
StatusUnavailableForLegalReasons = 451 // RFC 7725, 3
|
|
||||||
|
|
||||||
StatusInternalServerError = 500 // RFC 7231, 6.6.1
|
|
||||||
StatusNotImplemented = 501 // RFC 7231, 6.6.2
|
|
||||||
StatusBadGateway = 502 // RFC 7231, 6.6.3
|
|
||||||
StatusServiceUnavailable = 503 // RFC 7231, 6.6.4
|
|
||||||
StatusGatewayTimeout = 504 // RFC 7231, 6.6.5
|
|
||||||
StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6
|
|
||||||
StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1
|
|
||||||
StatusInsufficientStorage = 507 // RFC 4918, 11.5
|
|
||||||
StatusLoopDetected = 508 // RFC 5842, 7.2
|
|
||||||
StatusNotExtended = 510 // RFC 2774, 7
|
|
||||||
StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
statusLines atomic.Value
|
|
||||||
|
|
||||||
statusMessages = map[int]string{
|
|
||||||
StatusContinue: "Continue",
|
|
||||||
StatusSwitchingProtocols: "Switching Protocols",
|
|
||||||
StatusProcessing: "Processing",
|
|
||||||
|
|
||||||
StatusOK: "OK",
|
|
||||||
StatusCreated: "Created",
|
|
||||||
StatusAccepted: "Accepted",
|
|
||||||
StatusNonAuthoritativeInfo: "Non-Authoritative Information",
|
|
||||||
StatusNoContent: "No Content",
|
|
||||||
StatusResetContent: "Reset Content",
|
|
||||||
StatusPartialContent: "Partial Content",
|
|
||||||
StatusMultiStatus: "Multi-Status",
|
|
||||||
StatusAlreadyReported: "Already Reported",
|
|
||||||
StatusIMUsed: "IM Used",
|
|
||||||
|
|
||||||
StatusMultipleChoices: "Multiple Choices",
|
|
||||||
StatusMovedPermanently: "Moved Permanently",
|
|
||||||
StatusFound: "Found",
|
|
||||||
StatusSeeOther: "See Other",
|
|
||||||
StatusNotModified: "Not Modified",
|
|
||||||
StatusUseProxy: "Use Proxy",
|
|
||||||
StatusTemporaryRedirect: "Temporary Redirect",
|
|
||||||
StatusPermanentRedirect: "Permanent Redirect",
|
|
||||||
|
|
||||||
StatusBadRequest: "Bad Request",
|
|
||||||
StatusUnauthorized: "Unauthorized",
|
|
||||||
StatusPaymentRequired: "Payment Required",
|
|
||||||
StatusForbidden: "Forbidden",
|
|
||||||
StatusNotFound: "Not Found",
|
|
||||||
StatusMethodNotAllowed: "Method Not Allowed",
|
|
||||||
StatusNotAcceptable: "Not Acceptable",
|
|
||||||
StatusProxyAuthRequired: "Proxy Authentication Required",
|
|
||||||
StatusRequestTimeout: "Request Timeout",
|
|
||||||
StatusConflict: "Conflict",
|
|
||||||
StatusGone: "Gone",
|
|
||||||
StatusLengthRequired: "Length Required",
|
|
||||||
StatusPreconditionFailed: "Precondition Failed",
|
|
||||||
StatusRequestEntityTooLarge: "Request Entity Too Large",
|
|
||||||
StatusRequestURITooLong: "Request URI Too Long",
|
|
||||||
StatusUnsupportedMediaType: "Unsupported Media Type",
|
|
||||||
StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
|
|
||||||
StatusExpectationFailed: "Expectation Failed",
|
|
||||||
StatusTeapot: "I'm a teapot",
|
|
||||||
StatusUnprocessableEntity: "Unprocessable Entity",
|
|
||||||
StatusLocked: "Locked",
|
|
||||||
StatusFailedDependency: "Failed Dependency",
|
|
||||||
StatusUpgradeRequired: "Upgrade Required",
|
|
||||||
StatusPreconditionRequired: "Precondition Required",
|
|
||||||
StatusTooManyRequests: "Too Many Requests",
|
|
||||||
StatusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large",
|
|
||||||
StatusUnavailableForLegalReasons: "Unavailable For Legal Reasons",
|
|
||||||
|
|
||||||
StatusInternalServerError: "Internal Server Error",
|
|
||||||
StatusNotImplemented: "Not Implemented",
|
|
||||||
StatusBadGateway: "Bad Gateway",
|
|
||||||
StatusServiceUnavailable: "Service Unavailable",
|
|
||||||
StatusGatewayTimeout: "Gateway Timeout",
|
|
||||||
StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
|
|
||||||
StatusVariantAlsoNegotiates: "Variant Also Negotiates",
|
|
||||||
StatusInsufficientStorage: "Insufficient Storage",
|
|
||||||
StatusLoopDetected: "Loop Detected",
|
|
||||||
StatusNotExtended: "Not Extended",
|
|
||||||
StatusNetworkAuthenticationRequired: "Network Authentication Required",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// StatusMessage returns HTTP status message for the given status code.
|
|
||||||
func StatusMessage(statusCode int) string {
|
|
||||||
s := statusMessages[statusCode]
|
|
||||||
if s == "" {
|
|
||||||
s = "Unknown Status Code"
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
statusLines.Store(make(map[int][]byte))
|
|
||||||
}
|
|
||||||
|
|
||||||
func statusLine(statusCode int) []byte {
|
|
||||||
m := statusLines.Load().(map[int][]byte)
|
|
||||||
h := m[statusCode]
|
|
||||||
if h != nil {
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
statusText := StatusMessage(statusCode)
|
|
||||||
|
|
||||||
h = []byte(fmt.Sprintf("HTTP/1.1 %d %s\r\n", statusCode, statusText))
|
|
||||||
newM := make(map[int][]byte, len(m)+1)
|
|
||||||
for k, v := range m {
|
|
||||||
newM[k] = v
|
|
||||||
}
|
|
||||||
newM[statusCode] = h
|
|
||||||
statusLines.Store(newM)
|
|
||||||
return h
|
|
||||||
}
|
|
54
vendor/github.com/VictoriaMetrics/fasthttp/stream.go
generated
vendored
54
vendor/github.com/VictoriaMetrics/fasthttp/stream.go
generated
vendored
|
@ -1,54 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/fasthttp/fasthttputil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StreamWriter must write data to w.
|
|
||||||
//
|
|
||||||
// Usually StreamWriter writes data to w in a loop (aka 'data streaming').
|
|
||||||
//
|
|
||||||
// StreamWriter must return immediately if w returns error.
|
|
||||||
//
|
|
||||||
// Since the written data is buffered, do not forget calling w.Flush
|
|
||||||
// when the data must be propagated to reader.
|
|
||||||
type StreamWriter func(w *bufio.Writer)
|
|
||||||
|
|
||||||
// NewStreamReader returns a reader, which replays all the data generated by sw.
|
|
||||||
//
|
|
||||||
// The returned reader may be passed to Response.SetBodyStream.
|
|
||||||
//
|
|
||||||
// Close must be called on the returned reader after all the required data
|
|
||||||
// has been read. Otherwise goroutine leak may occur.
|
|
||||||
//
|
|
||||||
// See also Response.SetBodyStreamWriter.
|
|
||||||
func NewStreamReader(sw StreamWriter) io.ReadCloser {
|
|
||||||
pc := fasthttputil.NewPipeConns()
|
|
||||||
pw := pc.Conn1()
|
|
||||||
pr := pc.Conn2()
|
|
||||||
|
|
||||||
var bw *bufio.Writer
|
|
||||||
v := streamWriterBufPool.Get()
|
|
||||||
if v == nil {
|
|
||||||
bw = bufio.NewWriter(pw)
|
|
||||||
} else {
|
|
||||||
bw = v.(*bufio.Writer)
|
|
||||||
bw.Reset(pw)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
sw(bw)
|
|
||||||
bw.Flush()
|
|
||||||
pw.Close()
|
|
||||||
|
|
||||||
streamWriterBufPool.Put(bw)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return pr
|
|
||||||
}
|
|
||||||
|
|
||||||
var streamWriterBufPool sync.Pool
|
|
73
vendor/github.com/VictoriaMetrics/fasthttp/strings.go
generated
vendored
73
vendor/github.com/VictoriaMetrics/fasthttp/strings.go
generated
vendored
|
@ -1,73 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
var (
|
|
||||||
defaultServerName = []byte("fasthttp")
|
|
||||||
defaultUserAgent = []byte("fasthttp")
|
|
||||||
defaultContentType = []byte("text/plain; charset=utf-8")
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
strSlash = []byte("/")
|
|
||||||
strSlashSlash = []byte("//")
|
|
||||||
strSlashDotDot = []byte("/..")
|
|
||||||
strSlashDotSlash = []byte("/./")
|
|
||||||
strSlashDotDotSlash = []byte("/../")
|
|
||||||
strCRLF = []byte("\r\n")
|
|
||||||
strHTTP = []byte("http")
|
|
||||||
strHTTPS = []byte("https")
|
|
||||||
strHTTP11 = []byte("HTTP/1.1")
|
|
||||||
strColonSlashSlash = []byte("://")
|
|
||||||
strColonSpace = []byte(": ")
|
|
||||||
strGMT = []byte("GMT")
|
|
||||||
|
|
||||||
strResponseContinue = []byte("HTTP/1.1 100 Continue\r\n\r\n")
|
|
||||||
|
|
||||||
strGet = []byte("GET")
|
|
||||||
strHead = []byte("HEAD")
|
|
||||||
strPost = []byte("POST")
|
|
||||||
strPut = []byte("PUT")
|
|
||||||
strDelete = []byte("DELETE")
|
|
||||||
|
|
||||||
strExpect = []byte("Expect")
|
|
||||||
strConnection = []byte("Connection")
|
|
||||||
strContentLength = []byte("Content-Length")
|
|
||||||
strContentType = []byte("Content-Type")
|
|
||||||
strDate = []byte("Date")
|
|
||||||
strHost = []byte("Host")
|
|
||||||
strReferer = []byte("Referer")
|
|
||||||
strServer = []byte("Server")
|
|
||||||
strTransferEncoding = []byte("Transfer-Encoding")
|
|
||||||
strContentEncoding = []byte("Content-Encoding")
|
|
||||||
strAcceptEncoding = []byte("Accept-Encoding")
|
|
||||||
strUserAgent = []byte("User-Agent")
|
|
||||||
strCookie = []byte("Cookie")
|
|
||||||
strSetCookie = []byte("Set-Cookie")
|
|
||||||
strLocation = []byte("Location")
|
|
||||||
strIfModifiedSince = []byte("If-Modified-Since")
|
|
||||||
strLastModified = []byte("Last-Modified")
|
|
||||||
strAcceptRanges = []byte("Accept-Ranges")
|
|
||||||
strRange = []byte("Range")
|
|
||||||
strContentRange = []byte("Content-Range")
|
|
||||||
|
|
||||||
strCookieExpires = []byte("expires")
|
|
||||||
strCookieDomain = []byte("domain")
|
|
||||||
strCookiePath = []byte("path")
|
|
||||||
strCookieHTTPOnly = []byte("HttpOnly")
|
|
||||||
strCookieSecure = []byte("secure")
|
|
||||||
|
|
||||||
strClose = []byte("close")
|
|
||||||
strGzip = []byte("gzip")
|
|
||||||
strDeflate = []byte("deflate")
|
|
||||||
strKeepAlive = []byte("keep-alive")
|
|
||||||
strKeepAliveCamelCase = []byte("Keep-Alive")
|
|
||||||
strUpgrade = []byte("Upgrade")
|
|
||||||
strChunked = []byte("chunked")
|
|
||||||
strIdentity = []byte("identity")
|
|
||||||
str100Continue = []byte("100-continue")
|
|
||||||
strPostArgsContentType = []byte("application/x-www-form-urlencoded")
|
|
||||||
strMultipartFormData = []byte("multipart/form-data")
|
|
||||||
strBoundary = []byte("boundary")
|
|
||||||
strBytes = []byte("bytes")
|
|
||||||
strTextSlash = []byte("text/")
|
|
||||||
strApplicationSlash = []byte("application/")
|
|
||||||
)
|
|
369
vendor/github.com/VictoriaMetrics/fasthttp/tcpdialer.go
generated
vendored
369
vendor/github.com/VictoriaMetrics/fasthttp/tcpdialer.go
generated
vendored
|
@ -1,369 +0,0 @@
|
||||||
package fasthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Dial dials the given TCP addr using tcp4.
|
|
||||||
//
|
|
||||||
// This function has the following additional features comparing to net.Dial:
|
|
||||||
//
|
|
||||||
// * It reduces load on DNS resolver by caching resolved TCP addressed
|
|
||||||
// for DefaultDNSCacheDuration.
|
|
||||||
// * It dials all the resolved TCP addresses in round-robin manner until
|
|
||||||
// connection is established. This may be useful if certain addresses
|
|
||||||
// are temporarily unreachable.
|
|
||||||
// * It returns ErrDialTimeout if connection cannot be established during
|
|
||||||
// DefaultDialTimeout seconds. Use DialTimeout for customizing dial timeout.
|
|
||||||
//
|
|
||||||
// This dialer is intended for custom code wrapping before passing
|
|
||||||
// to Client.Dial or HostClient.Dial.
|
|
||||||
//
|
|
||||||
// For instance, per-host counters and/or limits may be implemented
|
|
||||||
// by such wrappers.
|
|
||||||
//
|
|
||||||
// The addr passed to the function must contain port. Example addr values:
|
|
||||||
//
|
|
||||||
// * foobar.baz:443
|
|
||||||
// * foo.bar:80
|
|
||||||
// * aaa.com:8080
|
|
||||||
func Dial(addr string) (net.Conn, error) {
|
|
||||||
return getDialer(DefaultDialTimeout, false)(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialTimeout dials the given TCP addr using tcp4 using the given timeout.
|
|
||||||
//
|
|
||||||
// This function has the following additional features comparing to net.Dial:
|
|
||||||
//
|
|
||||||
// * It reduces load on DNS resolver by caching resolved TCP addressed
|
|
||||||
// for DefaultDNSCacheDuration.
|
|
||||||
// * It dials all the resolved TCP addresses in round-robin manner until
|
|
||||||
// connection is established. This may be useful if certain addresses
|
|
||||||
// are temporarily unreachable.
|
|
||||||
//
|
|
||||||
// This dialer is intended for custom code wrapping before passing
|
|
||||||
// to Client.Dial or HostClient.Dial.
|
|
||||||
//
|
|
||||||
// For instance, per-host counters and/or limits may be implemented
|
|
||||||
// by such wrappers.
|
|
||||||
//
|
|
||||||
// The addr passed to the function must contain port. Example addr values:
|
|
||||||
//
|
|
||||||
// * foobar.baz:443
|
|
||||||
// * foo.bar:80
|
|
||||||
// * aaa.com:8080
|
|
||||||
func DialTimeout(addr string, timeout time.Duration) (net.Conn, error) {
|
|
||||||
return getDialer(timeout, false)(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialDualStack dials the given TCP addr using both tcp4 and tcp6.
|
|
||||||
//
|
|
||||||
// This function has the following additional features comparing to net.Dial:
|
|
||||||
//
|
|
||||||
// * It reduces load on DNS resolver by caching resolved TCP addressed
|
|
||||||
// for DefaultDNSCacheDuration.
|
|
||||||
// * It dials all the resolved TCP addresses in round-robin manner until
|
|
||||||
// connection is established. This may be useful if certain addresses
|
|
||||||
// are temporarily unreachable.
|
|
||||||
// * It returns ErrDialTimeout if connection cannot be established during
|
|
||||||
// DefaultDialTimeout seconds. Use DialDualStackTimeout for custom dial
|
|
||||||
// timeout.
|
|
||||||
//
|
|
||||||
// This dialer is intended for custom code wrapping before passing
|
|
||||||
// to Client.Dial or HostClient.Dial.
|
|
||||||
//
|
|
||||||
// For instance, per-host counters and/or limits may be implemented
|
|
||||||
// by such wrappers.
|
|
||||||
//
|
|
||||||
// The addr passed to the function must contain port. Example addr values:
|
|
||||||
//
|
|
||||||
// * foobar.baz:443
|
|
||||||
// * foo.bar:80
|
|
||||||
// * aaa.com:8080
|
|
||||||
func DialDualStack(addr string) (net.Conn, error) {
|
|
||||||
return getDialer(DefaultDialTimeout, true)(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialDualStackTimeout dials the given TCP addr using both tcp4 and tcp6
|
|
||||||
// using the given timeout.
|
|
||||||
//
|
|
||||||
// This function has the following additional features comparing to net.Dial:
|
|
||||||
//
|
|
||||||
// * It reduces load on DNS resolver by caching resolved TCP addressed
|
|
||||||
// for DefaultDNSCacheDuration.
|
|
||||||
// * It dials all the resolved TCP addresses in round-robin manner until
|
|
||||||
// connection is established. This may be useful if certain addresses
|
|
||||||
// are temporarily unreachable.
|
|
||||||
//
|
|
||||||
// This dialer is intended for custom code wrapping before passing
|
|
||||||
// to Client.Dial or HostClient.Dial.
|
|
||||||
//
|
|
||||||
// For instance, per-host counters and/or limits may be implemented
|
|
||||||
// by such wrappers.
|
|
||||||
//
|
|
||||||
// The addr passed to the function must contain port. Example addr values:
|
|
||||||
//
|
|
||||||
// * foobar.baz:443
|
|
||||||
// * foo.bar:80
|
|
||||||
// * aaa.com:8080
|
|
||||||
func DialDualStackTimeout(addr string, timeout time.Duration) (net.Conn, error) {
|
|
||||||
return getDialer(timeout, true)(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getDialer(timeout time.Duration, dualStack bool) DialFunc {
|
|
||||||
if timeout <= 0 {
|
|
||||||
timeout = DefaultDialTimeout
|
|
||||||
}
|
|
||||||
timeoutRounded := int(timeout.Seconds()*10 + 9)
|
|
||||||
|
|
||||||
m := dialMap
|
|
||||||
if dualStack {
|
|
||||||
m = dialDualStackMap
|
|
||||||
}
|
|
||||||
|
|
||||||
dialMapLock.Lock()
|
|
||||||
d := m[timeoutRounded]
|
|
||||||
if d == nil {
|
|
||||||
dialer := dialerStd
|
|
||||||
if dualStack {
|
|
||||||
dialer = dialerDualStack
|
|
||||||
}
|
|
||||||
d = dialer.NewDial(timeout)
|
|
||||||
m[timeoutRounded] = d
|
|
||||||
}
|
|
||||||
dialMapLock.Unlock()
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
dialerStd = &tcpDialer{}
|
|
||||||
dialerDualStack = &tcpDialer{DualStack: true}
|
|
||||||
|
|
||||||
dialMap = make(map[int]DialFunc)
|
|
||||||
dialDualStackMap = make(map[int]DialFunc)
|
|
||||||
dialMapLock sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
type tcpDialer struct {
|
|
||||||
DualStack bool
|
|
||||||
|
|
||||||
tcpAddrsLock sync.Mutex
|
|
||||||
tcpAddrsMap map[string]*tcpAddrEntry
|
|
||||||
|
|
||||||
concurrencyCh chan struct{}
|
|
||||||
|
|
||||||
once sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxDialConcurrency = 1000
|
|
||||||
|
|
||||||
func (d *tcpDialer) NewDial(timeout time.Duration) DialFunc {
|
|
||||||
d.once.Do(func() {
|
|
||||||
d.concurrencyCh = make(chan struct{}, maxDialConcurrency)
|
|
||||||
d.tcpAddrsMap = make(map[string]*tcpAddrEntry)
|
|
||||||
go d.tcpAddrsClean()
|
|
||||||
})
|
|
||||||
|
|
||||||
return func(addr string) (net.Conn, error) {
|
|
||||||
addrs, idx, err := d.getTCPAddrs(addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
network := "tcp4"
|
|
||||||
if d.DualStack {
|
|
||||||
network = "tcp"
|
|
||||||
}
|
|
||||||
|
|
||||||
var conn net.Conn
|
|
||||||
n := uint32(len(addrs))
|
|
||||||
deadline := time.Now().Add(timeout)
|
|
||||||
for n > 0 {
|
|
||||||
conn, err = tryDial(network, &addrs[idx%n], deadline, d.concurrencyCh)
|
|
||||||
if err == nil {
|
|
||||||
return conn, nil
|
|
||||||
}
|
|
||||||
if err == ErrDialTimeout {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
idx++
|
|
||||||
n--
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryDial(network string, addr *net.TCPAddr, deadline time.Time, concurrencyCh chan struct{}) (net.Conn, error) {
|
|
||||||
timeout := -time.Since(deadline)
|
|
||||||
if timeout <= 0 {
|
|
||||||
return nil, ErrDialTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case concurrencyCh <- struct{}{}:
|
|
||||||
default:
|
|
||||||
tc := acquireTimer(timeout)
|
|
||||||
isTimeout := false
|
|
||||||
select {
|
|
||||||
case concurrencyCh <- struct{}{}:
|
|
||||||
case <-tc.C:
|
|
||||||
isTimeout = true
|
|
||||||
}
|
|
||||||
releaseTimer(tc)
|
|
||||||
if isTimeout {
|
|
||||||
return nil, ErrDialTimeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout = -time.Since(deadline)
|
|
||||||
if timeout <= 0 {
|
|
||||||
<-concurrencyCh
|
|
||||||
return nil, ErrDialTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
chv := dialResultChanPool.Get()
|
|
||||||
if chv == nil {
|
|
||||||
chv = make(chan dialResult, 1)
|
|
||||||
}
|
|
||||||
ch := chv.(chan dialResult)
|
|
||||||
go func() {
|
|
||||||
var dr dialResult
|
|
||||||
dr.conn, dr.err = net.DialTCP(network, nil, addr)
|
|
||||||
ch <- dr
|
|
||||||
<-concurrencyCh
|
|
||||||
}()
|
|
||||||
|
|
||||||
var (
|
|
||||||
conn net.Conn
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
tc := acquireTimer(timeout)
|
|
||||||
select {
|
|
||||||
case dr := <-ch:
|
|
||||||
conn = dr.conn
|
|
||||||
err = dr.err
|
|
||||||
dialResultChanPool.Put(ch)
|
|
||||||
case <-tc.C:
|
|
||||||
err = ErrDialTimeout
|
|
||||||
}
|
|
||||||
releaseTimer(tc)
|
|
||||||
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var dialResultChanPool sync.Pool
|
|
||||||
|
|
||||||
type dialResult struct {
|
|
||||||
conn net.Conn
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrDialTimeout is returned when TCP dialing is timed out.
|
|
||||||
var ErrDialTimeout = errors.New("dialing to the given TCP address timed out")
|
|
||||||
|
|
||||||
// DefaultDialTimeout is timeout used by Dial and DialDualStack
|
|
||||||
// for establishing TCP connections.
|
|
||||||
const DefaultDialTimeout = 3 * time.Second
|
|
||||||
|
|
||||||
type tcpAddrEntry struct {
|
|
||||||
addrs []net.TCPAddr
|
|
||||||
addrsIdx uint32
|
|
||||||
|
|
||||||
resolveTime time.Time
|
|
||||||
pending bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultDNSCacheDuration is the duration for caching resolved TCP addresses
|
|
||||||
// by Dial* functions.
|
|
||||||
const DefaultDNSCacheDuration = time.Minute
|
|
||||||
|
|
||||||
func (d *tcpDialer) tcpAddrsClean() {
|
|
||||||
expireDuration := 2 * DefaultDNSCacheDuration
|
|
||||||
for {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
t := time.Now()
|
|
||||||
|
|
||||||
d.tcpAddrsLock.Lock()
|
|
||||||
for k, e := range d.tcpAddrsMap {
|
|
||||||
if t.Sub(e.resolveTime) > expireDuration {
|
|
||||||
delete(d.tcpAddrsMap, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.tcpAddrsLock.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *tcpDialer) getTCPAddrs(addr string) ([]net.TCPAddr, uint32, error) {
|
|
||||||
d.tcpAddrsLock.Lock()
|
|
||||||
e := d.tcpAddrsMap[addr]
|
|
||||||
if e != nil && !e.pending && time.Since(e.resolveTime) > DefaultDNSCacheDuration {
|
|
||||||
e.pending = true
|
|
||||||
e = nil
|
|
||||||
}
|
|
||||||
d.tcpAddrsLock.Unlock()
|
|
||||||
|
|
||||||
if e == nil {
|
|
||||||
addrs, err := resolveTCPAddrs(addr, d.DualStack)
|
|
||||||
if err != nil {
|
|
||||||
d.tcpAddrsLock.Lock()
|
|
||||||
e = d.tcpAddrsMap[addr]
|
|
||||||
if e != nil && e.pending {
|
|
||||||
e.pending = false
|
|
||||||
}
|
|
||||||
d.tcpAddrsLock.Unlock()
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
e = &tcpAddrEntry{
|
|
||||||
addrs: addrs,
|
|
||||||
resolveTime: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
d.tcpAddrsLock.Lock()
|
|
||||||
d.tcpAddrsMap[addr] = e
|
|
||||||
d.tcpAddrsLock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
idx := atomic.AddUint32(&e.addrsIdx, 1)
|
|
||||||
return e.addrs, idx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveTCPAddrs(addr string, dualStack bool) ([]net.TCPAddr, error) {
|
|
||||||
host, portS, err := net.SplitHostPort(addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
port, err := strconv.Atoi(portS)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ips, err := net.LookupIP(host)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
n := len(ips)
|
|
||||||
addrs := make([]net.TCPAddr, 0, n)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ip := ips[i]
|
|
||||||
if !dualStack && ip.To4() == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
addrs = append(addrs, net.TCPAddr{
|
|
||||||
IP: ip,
|
|
||||||
Port: port,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if len(addrs) == 0 {
|
|
||||||
return nil, errNoDNSEntries
|
|
||||||
}
|
|
||||||
return addrs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var errNoDNSEntries = errors.New("couldn't find DNS entries for the given domain. Try using DialDualStack")
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue