mirror of
https://github.com/coredns/coredns.git
synced 2026-03-31 01:05:33 -04:00
Drop caddy from vendor (#700)
* Removed caddy * new stuff * Now need to go get caddy * Duh
This commit is contained in:
78
Gopkg.lock
generated
78
Gopkg.lock
generated
@@ -22,8 +22,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/Shopify/sarama"
|
||||
packages = ["."]
|
||||
revision = "0fb560e5f7fbcaee2f75e3c34174320709f69944"
|
||||
version = "v1.11.0"
|
||||
revision = "c01858abb625b73a3af51d0798e4ad42c8147093"
|
||||
version = "v1.12.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/apache/thrift"
|
||||
@@ -46,14 +46,14 @@
|
||||
[[projects]]
|
||||
name = "github.com/coreos/etcd"
|
||||
packages = ["client","pkg/pathutil","pkg/types"]
|
||||
revision = "e5b7ee2d03627ca33201da428b8110ef7c3e95f1"
|
||||
version = "v3.1.6"
|
||||
revision = "d267ca9c184e953554257d0acdd1dc9c47d38229"
|
||||
version = "v3.1.8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/coreos/go-oidc"
|
||||
packages = ["http","jose","key","oauth2","oidc"]
|
||||
revision = "5157aa730c25a7531d4b99483e6a440d4ab735a0"
|
||||
revision = "c797a55f1c1001ec3169f1d0fbb4c5523563bec6"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/coreos/pkg"
|
||||
@@ -97,12 +97,6 @@
|
||||
revision = "777bb3f19bcafe2575ffb2a3e46af92509ae9594"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/flynn/go-shlex"
|
||||
packages = ["."]
|
||||
revision = "3f9db97f856818214da2e1057f8ad84803971cff"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
packages = ["."]
|
||||
@@ -143,7 +137,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/swag"
|
||||
packages = ["."]
|
||||
revision = "24ebf76d720bab64f62824d76bced3184a65490d"
|
||||
revision = "e43299b4afa7bc7f22e5e82e3d48607230e4c177"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gogo/protobuf"
|
||||
@@ -160,8 +154,8 @@
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "2bba0603135d7d7f5cb73b2125beeda19c09f4ef"
|
||||
packages = ["proto","ptypes/any"]
|
||||
revision = "5a0f697c9ed9d68fef0116532c6e05cfeae00e55"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -185,7 +179,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/grpc-ecosystem/grpc-opentracing"
|
||||
packages = ["go/otgrpc"]
|
||||
revision = "ef7d6c8df7564c20c0a19ed9737f6d67990c61fa"
|
||||
revision = "6c130eed1e297e1aa4d415a50c90d0c81c52677e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -215,13 +209,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/juju/ratelimit"
|
||||
packages = ["."]
|
||||
revision = "acf38b000a03e4ab89e40f20f1e548f4e6ac7f72"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/klauspost/crc32"
|
||||
packages = ["."]
|
||||
revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
|
||||
version = "v1.1"
|
||||
revision = "5b9ff866471762aa2ab2dced63c9fb6f53921342"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -233,7 +221,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = ["buffer","jlexer","jwriter"]
|
||||
revision = "3f09c2282fc5ad74b3d04a485311f3173c2431d3"
|
||||
revision = "44c0351a5bc860bcb2608d54aa03ea686c4e7b25"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
@@ -241,23 +229,17 @@
|
||||
revision = "3247c84500bff8d9fb6d579d800f20b3e091582c"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mholt/caddy"
|
||||
packages = [".","caddyfile","startupshutdown"]
|
||||
revision = "27785f7993319b615acae4ff2a33cdb36fb68376"
|
||||
version = "v0.10.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/miekg/dns"
|
||||
packages = ["."]
|
||||
revision = "113c7538ea6d8f429071f901bd26af59cc9676fe"
|
||||
revision = "fb6fbed0f5ec4e418de4f156c18d2e4f9bc854e7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/opentracing/opentracing-go"
|
||||
packages = [".","ext","log"]
|
||||
revision = "6edb48674bd9467b8e91fda004f2bd7202d60ce4"
|
||||
version = "v1.0.1"
|
||||
revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/openzipkin/zipkin-go-opentracing"
|
||||
@@ -272,10 +254,10 @@
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pierrec/lz4"
|
||||
packages = ["."]
|
||||
revision = "f5b77fd73d83122495309c0f459b810f83cc291f"
|
||||
revision = "5c9560bfa9ace2bf86080bf40d46b34ae44604df"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pierrec/xxHash"
|
||||
@@ -305,7 +287,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [".","xfs"]
|
||||
revision = "6ac8c5d890d415025dd5aae7595bcb2a6e7e2fad"
|
||||
revision = "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -317,7 +299,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "f1d95a35e132e8a1868023a08932b14f0b8b8fcb"
|
||||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -329,31 +311,31 @@
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "c7af5bf2638a1164f2eb5467c39c6cffbd13a02e"
|
||||
revision = "e1a4589e7d3ea14a3352255d04b6f1a418845e5e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = ["context","context/ctxhttp","http2","http2/hpack","idna","internal/timeseries","lex/httplex","trace"]
|
||||
revision = "da118f7b8e5954f39d0d2130ab35d4bf0e3cb344"
|
||||
revision = "3da985ce5951d99de868be4385f21ea6c2b22f24"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [".","google","internal","jws","jwt"]
|
||||
revision = "a6bd8cefa1811bd24b86f8902872e4e8225f74c4"
|
||||
revision = "f047394b6d14284165300fd82dad67edb3a4d7f6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "9ccfe848b9db8435a24c424abbc07a921adf1df5"
|
||||
revision = "b90f89a1e7a9c1f6b918820b3daa7f08488c8594"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable","width"]
|
||||
revision = "470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4"
|
||||
revision = "4ee4af566555f5fbe026368b75596286a312663a"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/appengine"
|
||||
@@ -361,11 +343,17 @@
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
revision = "aa2eb687b4d3e17154372564ad8d6bf11c3cf21f"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [".","codes","credentials","grpclog","internal","keepalive","metadata","naming","peer","stats","tap","transport"]
|
||||
revision = "8050b9cbc271307e5a716a9d782803d09b0d6f2d"
|
||||
version = "v1.2.1"
|
||||
packages = [".","codes","credentials","grpclb/grpc_lb_v1","grpclog","internal","keepalive","metadata","naming","peer","stats","status","tap","transport"]
|
||||
revision = "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/inf.v0"
|
||||
@@ -388,6 +376,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "9c7d469cf5543db6f5df55c0e72b1223fc15df4ef1242861e6981d2527eed2c9"
|
||||
inputs-digest = "a59be89c7a92b81f951b47efd072c2af04fb66b4f2b7a780cadb7466559d0d6b"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## "ignored" lists a set of packages (not projects) that are ignored when
|
||||
## dep statically analyzes source code. Ignored packages can be in this project,
|
||||
## or in a dependency.
|
||||
# ignored = ["github.com/user/project/badpkg"]
|
||||
ignored = ["github.com/mholt/caddy", "github.com/mholt/caddy/caddyfile", "github.com/mholt/caddy/startupshutdown"]
|
||||
|
||||
## Dependencies define constraints on dependent projects. They are respected by
|
||||
## dep whether coming from the Gopkg.toml of the current project or a dependency.
|
||||
|
||||
8
Makefile
8
Makefile
@@ -7,11 +7,11 @@ all: coredns
|
||||
# Phony this to ensure we always build the binary.
|
||||
# TODO: Add .go file dependencies.
|
||||
.PHONY: coredns
|
||||
coredns: check
|
||||
coredns: check caddy
|
||||
go build $(BUILD_VERBOSE) -ldflags="-s -w"
|
||||
|
||||
.PHONY: deps
|
||||
deps: core/zmiddleware.go core/dnsserver/zdirectives.go
|
||||
deps: core/zmiddleware.go core/dnsserver/zdirectives.go caddy
|
||||
go get -u github.com/golang/lint/golint
|
||||
|
||||
.PHONY: check
|
||||
@@ -25,6 +25,10 @@ test: check
|
||||
testk8s: check
|
||||
go test -race $(TEST_VERBOSE) -tags=k8s -run 'TestKubernetes' ./test ./middleware/kubernetes/...
|
||||
|
||||
.PHONY: caddy
|
||||
caddy:
|
||||
go get github.com/mholt/caddy
|
||||
|
||||
.PHONY: coverage
|
||||
coverage: check
|
||||
set -e -x
|
||||
|
||||
5
vendor/github.com/Shopify/sarama/.travis.yml
generated
vendored
5
vendor/github.com/Shopify/sarama/.travis.yml
generated
vendored
@@ -1,7 +1,7 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.6.3
|
||||
- 1.7.3
|
||||
- 1.8
|
||||
|
||||
env:
|
||||
global:
|
||||
@@ -12,8 +12,7 @@ env:
|
||||
- DEBUG=true
|
||||
matrix:
|
||||
- KAFKA_VERSION=0.9.0.1
|
||||
- KAFKA_VERSION=0.10.0.1
|
||||
- KAFKA_VERSION=0.10.1.0
|
||||
- KAFKA_VERSION=0.10.2.0
|
||||
|
||||
before_install:
|
||||
- export REPOSITORY_ROOT=${TRAVIS_BUILD_DIR}
|
||||
|
||||
39
vendor/github.com/Shopify/sarama/CHANGELOG.md
generated
vendored
39
vendor/github.com/Shopify/sarama/CHANGELOG.md
generated
vendored
@@ -1,7 +1,46 @@
|
||||
# Changelog
|
||||
|
||||
#### Version 1.12.0 (2017-05-08)
|
||||
|
||||
New Features:
|
||||
- Added support for the `ApiVersions` request and response pair, and Kafka
|
||||
version 0.10.2 ([#867](https://github.com/Shopify/sarama/pull/867)). Note
|
||||
that you still need to specify the Kafka version in the Sarama configuration
|
||||
for the time being.
|
||||
- Added a `Brokers` method to the Client which returns the complete set of
|
||||
active brokers ([#813](https://github.com/Shopify/sarama/pull/813)).
|
||||
- Added an `InSyncReplicas` method to the Client which returns the set of all
|
||||
in-sync broker IDs for the given partition, now that the Kafka versions for
|
||||
which this was misleading are no longer in our supported set
|
||||
([#872](https://github.com/Shopify/sarama/pull/872)).
|
||||
- Added a `NewCustomHashPartitioner` method which allows constructing a hash
|
||||
partitioner with a custom hash method in case the default (FNV-1a) is not
|
||||
suitable
|
||||
([#837](https://github.com/Shopify/sarama/pull/837),
|
||||
[#841](https://github.com/Shopify/sarama/pull/841)).
|
||||
|
||||
Improvements:
|
||||
- Recognize more Kafka error codes
|
||||
([#859](https://github.com/Shopify/sarama/pull/859)).
|
||||
|
||||
Bug Fixes:
|
||||
- Fix an issue where decoding a malformed FetchRequest would not return the
|
||||
correct error ([#818](https://github.com/Shopify/sarama/pull/818)).
|
||||
- Respect ordering of group protocols in JoinGroupRequests. This fix is
|
||||
transparent if you're using the `AddGroupProtocol` or
|
||||
`AddGroupProtocolMetadata` helpers; otherwise you will need to switch from
|
||||
the `GroupProtocols` field (now deprecated) to use `OrderedGroupProtocols`
|
||||
([#812](https://github.com/Shopify/sarama/issues/812)).
|
||||
- Fix an alignment-related issue with atomics on 32-bit architectures
|
||||
([#859](https://github.com/Shopify/sarama/pull/859)).
|
||||
|
||||
#### Version 1.11.0 (2016-12-20)
|
||||
|
||||
_Important:_ As of Sarama 1.11 it is necessary to set the config value of
|
||||
`Producer.Return.Successes` to true in order to use the SyncProducer. Previous
|
||||
versions would silently override this value when instantiating a SyncProducer
|
||||
which led to unexpected values and data races.
|
||||
|
||||
New Features:
|
||||
- Metrics! Thanks to Sébastien Launay for all his work on this feature
|
||||
([#701](https://github.com/Shopify/sarama/pull/701),
|
||||
|
||||
6
vendor/github.com/Shopify/sarama/README.md
generated
vendored
6
vendor/github.com/Shopify/sarama/README.md
generated
vendored
@@ -13,12 +13,14 @@ Sarama is an MIT-licensed Go client library for [Apache Kafka](https://kafka.apa
|
||||
- The [examples](./examples) directory contains more elaborate example applications.
|
||||
- The [tools](./tools) directory contains command line tools that can be useful for testing, diagnostics, and instrumentation.
|
||||
|
||||
You might also want to look at the [Frequently Asked Questions](https://github.com/Shopify/sarama/wiki/Frequently-Asked-Questions).
|
||||
|
||||
### Compatibility and API stability
|
||||
|
||||
Sarama provides a "2 releases + 2 months" compatibility guarantee: we support
|
||||
the two latest stable releases of Kafka and Go, and we provide a two month
|
||||
grace period for older releases. This means we currently officially support
|
||||
Go 1.7 and 1.6, and Kafka 0.10.0 and 0.9.0, although older releases are
|
||||
Go 1.8 and 1.7, and Kafka 0.10 and 0.9, although older releases are
|
||||
still likely to work.
|
||||
|
||||
Sarama follows semantic versioning and provides API stability via the gopkg.in service.
|
||||
@@ -27,7 +29,7 @@ A changelog is available [here](CHANGELOG.md).
|
||||
|
||||
### Contributing
|
||||
|
||||
* Get started by checking our [contribution guidelines](https://github.com/Shopify/sarama/blob/master/CONTRIBUTING.md).
|
||||
* Get started by checking our [contribution guidelines](https://github.com/Shopify/sarama/blob/master/.github/CONTRIBUTING.md).
|
||||
* Read the [Sarama wiki](https://github.com/Shopify/sarama/wiki) for more
|
||||
technical and design details.
|
||||
* The [Kafka Protocol Specification](https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol)
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/api_versions_response.go
generated
vendored
7
vendor/github.com/Shopify/sarama/api_versions_response.go
generated
vendored
@@ -50,12 +50,13 @@ func (r *ApiVersionsResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *ApiVersionsResponse) decode(pd packetDecoder, version int16) error {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
|
||||
r.Err = KError(kerr)
|
||||
|
||||
numBlocks, err := pd.getArrayLength()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
21
vendor/github.com/Shopify/sarama/async_producer.go
generated
vendored
21
vendor/github.com/Shopify/sarama/async_producer.go
generated
vendored
@@ -17,24 +17,23 @@ import (
|
||||
// scope.
|
||||
type AsyncProducer interface {
|
||||
|
||||
// AsyncClose triggers a shutdown of the producer, flushing any messages it may
|
||||
// have buffered. The shutdown has completed when both the Errors and Successes
|
||||
// channels have been closed. When calling AsyncClose, you *must* continue to
|
||||
// read from those channels in order to drain the results of any messages in
|
||||
// flight.
|
||||
// AsyncClose triggers a shutdown of the producer. The shutdown has completed
|
||||
// when both the Errors and Successes channels have been closed. When calling
|
||||
// AsyncClose, you *must* continue to read from those channels in order to
|
||||
// drain the results of any messages in flight.
|
||||
AsyncClose()
|
||||
|
||||
// Close shuts down the producer and flushes any messages it may have buffered.
|
||||
// You must call this function before a producer object passes out of scope, as
|
||||
// it may otherwise leak memory. You must call this before calling Close on the
|
||||
// underlying client.
|
||||
// Close shuts down the producer and waits for any buffered messages to be
|
||||
// flushed. You must call this function before a producer object passes out of
|
||||
// scope, as it may otherwise leak memory. You must call this before calling
|
||||
// Close on the underlying client.
|
||||
Close() error
|
||||
|
||||
// Input is the input channel for the user to write messages to that they
|
||||
// wish to send.
|
||||
Input() chan<- *ProducerMessage
|
||||
|
||||
// Successes is the success output channel back to the user when AckSuccesses is
|
||||
// Successes is the success output channel back to the user when Return.Successes is
|
||||
// enabled. If Return.Successes is true, you MUST read from this channel or the
|
||||
// Producer will deadlock. It is suggested that you send and read messages
|
||||
// together in a single select statement.
|
||||
@@ -200,7 +199,7 @@ func (p *asyncProducer) Close() error {
|
||||
|
||||
if p.conf.Producer.Return.Successes {
|
||||
go withRecover(func() {
|
||||
for _ = range p.successes {
|
||||
for range p.successes {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
4
vendor/github.com/Shopify/sarama/async_producer_test.go
generated
vendored
4
vendor/github.com/Shopify/sarama/async_producer_test.go
generated
vendored
@@ -18,7 +18,7 @@ func closeProducer(t *testing.T, p AsyncProducer) {
|
||||
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
for _ = range p.Successes() {
|
||||
for range p.Successes() {
|
||||
t.Error("Unexpected message on Successes()")
|
||||
}
|
||||
wg.Done()
|
||||
@@ -808,7 +808,7 @@ func ExampleAsyncProducer_goroutines() {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for _ = range producer.Successes() {
|
||||
for range producer.Successes() {
|
||||
successes++
|
||||
}
|
||||
}()
|
||||
|
||||
13
vendor/github.com/Shopify/sarama/broker.go
generated
vendored
13
vendor/github.com/Shopify/sarama/broker.go
generated
vendored
@@ -52,7 +52,7 @@ type responsePromise struct {
|
||||
errors chan error
|
||||
}
|
||||
|
||||
// NewBroker creates and returns a Broker targetting the given host:port address.
|
||||
// NewBroker creates and returns a Broker targeting the given host:port address.
|
||||
// This does not attempt to actually connect, you have to call Open() for that.
|
||||
func NewBroker(addr string) *Broker {
|
||||
return &Broker{id: -1, addr: addr}
|
||||
@@ -355,6 +355,17 @@ func (b *Broker) DescribeGroups(request *DescribeGroupsRequest) (*DescribeGroups
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (b *Broker) ApiVersions(request *ApiVersionsRequest) (*ApiVersionsResponse, error) {
|
||||
response := new(ApiVersionsResponse)
|
||||
|
||||
err := b.sendAndReceive(request, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (b *Broker) send(rb protocolBody, promiseResponse bool) (*responsePromise, error) {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
13
vendor/github.com/Shopify/sarama/broker_test.go
generated
vendored
13
vendor/github.com/Shopify/sarama/broker_test.go
generated
vendored
@@ -284,6 +284,19 @@ var brokerTestTable = []struct {
|
||||
t.Error("DescribeGroups request got no response!")
|
||||
}
|
||||
}},
|
||||
|
||||
{"ApiVersionsRequest",
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
func(t *testing.T, broker *Broker) {
|
||||
request := ApiVersionsRequest{}
|
||||
response, err := broker.ApiVersions(&request)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if response == nil {
|
||||
t.Error("ApiVersions request got no response!")
|
||||
}
|
||||
}},
|
||||
}
|
||||
|
||||
func validateBrokerMetrics(t *testing.T, broker *Broker, mockBrokerMetrics brokerMetrics) {
|
||||
|
||||
51
vendor/github.com/Shopify/sarama/client.go
generated
vendored
51
vendor/github.com/Shopify/sarama/client.go
generated
vendored
@@ -17,6 +17,9 @@ type Client interface {
|
||||
// altered after it has been created.
|
||||
Config() *Config
|
||||
|
||||
// Brokers returns the current set of active brokers as retrieved from cluster metadata.
|
||||
Brokers() []*Broker
|
||||
|
||||
// Topics returns the set of available topics as retrieved from cluster metadata.
|
||||
Topics() ([]string, error)
|
||||
|
||||
@@ -35,6 +38,11 @@ type Client interface {
|
||||
// Replicas returns the set of all replica IDs for the given partition.
|
||||
Replicas(topic string, partitionID int32) ([]int32, error)
|
||||
|
||||
// InSyncReplicas returns the set of all in-sync replica IDs for the given
|
||||
// partition. In-sync replicas are replicas which are fully caught up with
|
||||
// the partition leader.
|
||||
InSyncReplicas(topic string, partitionID int32) ([]int32, error)
|
||||
|
||||
// RefreshMetadata takes a list of topics and queries the cluster to refresh the
|
||||
// available metadata for those topics. If no topics are provided, it will refresh
|
||||
// metadata for all topics.
|
||||
@@ -133,7 +141,7 @@ func NewClient(addrs []string, conf *Config) (Client, error) {
|
||||
client.seedBrokers = append(client.seedBrokers, NewBroker(addrs[index]))
|
||||
}
|
||||
|
||||
// do an initial fetch of all cluster metadata by specifing an empty list of topics
|
||||
// do an initial fetch of all cluster metadata by specifying an empty list of topics
|
||||
err := client.RefreshMetadata()
|
||||
switch err {
|
||||
case nil:
|
||||
@@ -157,6 +165,16 @@ func (client *client) Config() *Config {
|
||||
return client.conf
|
||||
}
|
||||
|
||||
func (client *client) Brokers() []*Broker {
|
||||
client.lock.RLock()
|
||||
defer client.lock.RUnlock()
|
||||
brokers := make([]*Broker, 0)
|
||||
for _, broker := range client.brokers {
|
||||
brokers = append(brokers, broker)
|
||||
}
|
||||
return brokers
|
||||
}
|
||||
|
||||
func (client *client) Close() error {
|
||||
if client.Closed() {
|
||||
// Chances are this is being called from a defer() and the error will go unobserved
|
||||
@@ -282,6 +300,31 @@ func (client *client) Replicas(topic string, partitionID int32) ([]int32, error)
|
||||
return dupeAndSort(metadata.Replicas), nil
|
||||
}
|
||||
|
||||
func (client *client) InSyncReplicas(topic string, partitionID int32) ([]int32, error) {
|
||||
if client.Closed() {
|
||||
return nil, ErrClosedClient
|
||||
}
|
||||
|
||||
metadata := client.cachedMetadata(topic, partitionID)
|
||||
|
||||
if metadata == nil {
|
||||
err := client.RefreshMetadata(topic)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metadata = client.cachedMetadata(topic, partitionID)
|
||||
}
|
||||
|
||||
if metadata == nil {
|
||||
return nil, ErrUnknownTopicOrPartition
|
||||
}
|
||||
|
||||
if metadata.Err == ErrReplicaNotAvailable {
|
||||
return nil, metadata.Err
|
||||
}
|
||||
return dupeAndSort(metadata.Isr), nil
|
||||
}
|
||||
|
||||
func (client *client) Leader(topic string, partitionID int32) (*Broker, error) {
|
||||
if client.Closed() {
|
||||
return nil, ErrClosedClient
|
||||
@@ -592,12 +635,12 @@ func (client *client) tryRefreshMetadata(topics []string, attemptsRemaining int)
|
||||
switch err.(type) {
|
||||
case nil:
|
||||
// valid response, use it
|
||||
if shouldRetry, err := client.updateMetadata(response); shouldRetry {
|
||||
shouldRetry, err := client.updateMetadata(response)
|
||||
if shouldRetry {
|
||||
Logger.Println("client/metadata found some partitions to be leaderless")
|
||||
return retry(err) // note: err can be nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
|
||||
case PacketEncodingError:
|
||||
// didn't even send, return the error
|
||||
|
||||
11
vendor/github.com/Shopify/sarama/client_test.go
generated
vendored
11
vendor/github.com/Shopify/sarama/client_test.go
generated
vendored
@@ -196,6 +196,17 @@ func TestClientMetadata(t *testing.T) {
|
||||
t.Error("Incorrect (or unsorted) replica")
|
||||
}
|
||||
|
||||
isr, err = client.InSyncReplicas("my_topic", 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if len(isr) != 2 {
|
||||
t.Error("Client returned incorrect ISRs for partition:", isr)
|
||||
} else if isr[0] != 1 {
|
||||
t.Error("Incorrect (or unsorted) ISR:", isr)
|
||||
} else if isr[1] != 5 {
|
||||
t.Error("Incorrect (or unsorted) ISR:", isr)
|
||||
}
|
||||
|
||||
leader.Close()
|
||||
seedBroker.Close()
|
||||
safeClose(t, client)
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/config.go
generated
vendored
7
vendor/github.com/Shopify/sarama/config.go
generated
vendored
@@ -305,10 +305,13 @@ func (c *Config) Validate() error {
|
||||
Logger.Println("Producer.RequiredAcks > 1 is deprecated and will raise an exception with kafka >= 0.8.2.0.")
|
||||
}
|
||||
if c.Producer.MaxMessageBytes >= int(MaxRequestSize) {
|
||||
Logger.Println("Producer.MaxMessageBytes is larger than MaxRequestSize; it will be ignored.")
|
||||
Logger.Println("Producer.MaxMessageBytes must be smaller than MaxRequestSize; it will be ignored.")
|
||||
}
|
||||
if c.Producer.Flush.Bytes >= int(MaxRequestSize) {
|
||||
Logger.Println("Producer.Flush.Bytes is larger than MaxRequestSize; it will be ignored.")
|
||||
Logger.Println("Producer.Flush.Bytes must be smaller than MaxRequestSize; it will be ignored.")
|
||||
}
|
||||
if (c.Producer.Flush.Bytes > 0 || c.Producer.Flush.Messages > 0) && c.Producer.Flush.Frequency == 0 {
|
||||
Logger.Println("Producer.Flush: Bytes or Messages are set, but Frequency is not; messages may not get flushed.")
|
||||
}
|
||||
if c.Producer.Timeout%time.Millisecond != 0 {
|
||||
Logger.Println("Producer.Timeout only supports millisecond resolution; nanoseconds will be truncated.")
|
||||
|
||||
18
vendor/github.com/Shopify/sarama/consumer.go
generated
vendored
18
vendor/github.com/Shopify/sarama/consumer.go
generated
vendored
@@ -289,10 +289,11 @@ type PartitionConsumer interface {
|
||||
}
|
||||
|
||||
type partitionConsumer struct {
|
||||
consumer *consumer
|
||||
conf *Config
|
||||
topic string
|
||||
partition int32
|
||||
highWaterMarkOffset int64 // must be at the top of the struct because https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
consumer *consumer
|
||||
conf *Config
|
||||
topic string
|
||||
partition int32
|
||||
|
||||
broker *brokerConsumer
|
||||
messages chan *ConsumerMessage
|
||||
@@ -302,9 +303,8 @@ type partitionConsumer struct {
|
||||
trigger, dying chan none
|
||||
responseResult error
|
||||
|
||||
fetchSize int32
|
||||
offset int64
|
||||
highWaterMarkOffset int64
|
||||
fetchSize int32
|
||||
offset int64
|
||||
}
|
||||
|
||||
var errTimedOut = errors.New("timed out feeding messages to the user") // not user-facing
|
||||
@@ -324,7 +324,7 @@ func (child *partitionConsumer) sendError(err error) {
|
||||
}
|
||||
|
||||
func (child *partitionConsumer) dispatcher() {
|
||||
for _ = range child.trigger {
|
||||
for range child.trigger {
|
||||
select {
|
||||
case <-child.dying:
|
||||
close(child.trigger)
|
||||
@@ -411,7 +411,7 @@ func (child *partitionConsumer) Close() error {
|
||||
child.AsyncClose()
|
||||
|
||||
go withRecover(func() {
|
||||
for _ = range child.messages {
|
||||
for range child.messages {
|
||||
// drain
|
||||
}
|
||||
})
|
||||
|
||||
2
vendor/github.com/Shopify/sarama/consumer_group_members_test.go
generated
vendored
2
vendor/github.com/Shopify/sarama/consumer_group_members_test.go
generated
vendored
@@ -51,7 +51,7 @@ func TestConsumerGroupMemberAssignment(t *testing.T) {
|
||||
amt := &ConsumerGroupMemberAssignment{
|
||||
Version: 1,
|
||||
Topics: map[string][]int32{
|
||||
"one": []int32{0, 2, 4},
|
||||
"one": {0, 2, 4},
|
||||
},
|
||||
UserData: []byte{0x01, 0x02, 0x03},
|
||||
}
|
||||
|
||||
3
vendor/github.com/Shopify/sarama/crc32_field.go
generated
vendored
3
vendor/github.com/Shopify/sarama/crc32_field.go
generated
vendored
@@ -2,8 +2,7 @@ package sarama
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/klauspost/crc32"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
// crc32Field implements the pushEncoder and pushDecoder interfaces for calculating CRC32s.
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/describe_groups_response.go
generated
vendored
7
vendor/github.com/Shopify/sarama/describe_groups_response.go
generated
vendored
@@ -89,12 +89,13 @@ func (gd *GroupDescription) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (gd *GroupDescription) decode(pd packetDecoder) (err error) {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
gd.Err = KError(kerr)
|
||||
}
|
||||
|
||||
gd.Err = KError(kerr)
|
||||
|
||||
if gd.GroupId, err = pd.getString(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
3
vendor/github.com/Shopify/sarama/dev.yml
generated
vendored
3
vendor/github.com/Shopify/sarama/dev.yml
generated
vendored
@@ -1,7 +1,8 @@
|
||||
name: sarama
|
||||
|
||||
up:
|
||||
- go: 1.7.3
|
||||
- go:
|
||||
version: '1.8'
|
||||
|
||||
commands:
|
||||
test:
|
||||
|
||||
26
vendor/github.com/Shopify/sarama/errors.go
generated
vendored
26
vendor/github.com/Shopify/sarama/errors.go
generated
vendored
@@ -108,12 +108,20 @@ const (
|
||||
ErrUnsupportedSASLMechanism KError = 33
|
||||
ErrIllegalSASLState KError = 34
|
||||
ErrUnsupportedVersion KError = 35
|
||||
ErrTopicAlreadyExists KError = 36
|
||||
ErrInvalidPartitions KError = 37
|
||||
ErrInvalidReplicationFactor KError = 38
|
||||
ErrInvalidReplicaAssignment KError = 39
|
||||
ErrInvalidConfig KError = 40
|
||||
ErrNotController KError = 41
|
||||
ErrInvalidRequest KError = 42
|
||||
ErrUnsupportedForMessageFormat KError = 43
|
||||
ErrPolicyViolation KError = 44
|
||||
)
|
||||
|
||||
func (err KError) Error() string {
|
||||
// Error messages stolen/adapted from
|
||||
// https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol
|
||||
// https://kafka.apache.org/protocol#protocol_error_codes
|
||||
switch err {
|
||||
case ErrNoError:
|
||||
return "kafka server: Not an error, why are you printing me?"
|
||||
@@ -189,8 +197,24 @@ func (err KError) Error() string {
|
||||
return "kafka server: Request is not valid given the current SASL state."
|
||||
case ErrUnsupportedVersion:
|
||||
return "kafka server: The version of API is not supported."
|
||||
case ErrTopicAlreadyExists:
|
||||
return "kafka server: Topic with this name already exists."
|
||||
case ErrInvalidPartitions:
|
||||
return "kafka server: Number of partitions is invalid."
|
||||
case ErrInvalidReplicationFactor:
|
||||
return "kafka server: Replication-factor is invalid."
|
||||
case ErrInvalidReplicaAssignment:
|
||||
return "kafka server: Replica assignment is invalid."
|
||||
case ErrInvalidConfig:
|
||||
return "kafka server: Configuration is invalid."
|
||||
case ErrNotController:
|
||||
return "kafka server: This is not the correct controller for this cluster."
|
||||
case ErrInvalidRequest:
|
||||
return "kafka server: This most likely occurs because of a request being malformed by the client library or the message was sent to an incompatible broker. See the broker logs for more details."
|
||||
case ErrUnsupportedForMessageFormat:
|
||||
return "kafka server: The requested operation is not supported by the message format version."
|
||||
case ErrPolicyViolation:
|
||||
return "kafka server: Request parameters do not satisfy the configured policy."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Unknown error, how did this happen? Error code = %d", err)
|
||||
|
||||
2
vendor/github.com/Shopify/sarama/fetch_request.go
generated
vendored
2
vendor/github.com/Shopify/sarama/fetch_request.go
generated
vendored
@@ -92,7 +92,7 @@ func (r *FetchRequest) decode(pd packetDecoder, version int16) (err error) {
|
||||
}
|
||||
fetchBlock := &fetchRequestBlock{}
|
||||
if err = fetchBlock.decode(pd); err != nil {
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
r.blocks[topic][partition] = fetchBlock
|
||||
}
|
||||
|
||||
6
vendor/github.com/Shopify/sarama/heartbeat_response.go
generated
vendored
6
vendor/github.com/Shopify/sarama/heartbeat_response.go
generated
vendored
@@ -10,11 +10,11 @@ func (r *HeartbeatResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *HeartbeatResponse) decode(pd packetDecoder, version int16) error {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
r.Err = KError(kerr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
83
vendor/github.com/Shopify/sarama/join_group_request.go
generated
vendored
83
vendor/github.com/Shopify/sarama/join_group_request.go
generated
vendored
@@ -1,11 +1,36 @@
|
||||
package sarama
|
||||
|
||||
type GroupProtocol struct {
|
||||
Name string
|
||||
Metadata []byte
|
||||
}
|
||||
|
||||
func (p *GroupProtocol) decode(pd packetDecoder) (err error) {
|
||||
p.Name, err = pd.getString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.Metadata, err = pd.getBytes()
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *GroupProtocol) encode(pe packetEncoder) (err error) {
|
||||
if err := pe.putString(p.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := pe.putBytes(p.Metadata); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type JoinGroupRequest struct {
|
||||
GroupId string
|
||||
SessionTimeout int32
|
||||
MemberId string
|
||||
ProtocolType string
|
||||
GroupProtocols map[string][]byte
|
||||
GroupId string
|
||||
SessionTimeout int32
|
||||
MemberId string
|
||||
ProtocolType string
|
||||
GroupProtocols map[string][]byte // deprecated; use OrderedGroupProtocols
|
||||
OrderedGroupProtocols []*GroupProtocol
|
||||
}
|
||||
|
||||
func (r *JoinGroupRequest) encode(pe packetEncoder) error {
|
||||
@@ -20,16 +45,31 @@ func (r *JoinGroupRequest) encode(pe packetEncoder) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := pe.putArrayLength(len(r.GroupProtocols)); err != nil {
|
||||
return err
|
||||
}
|
||||
for name, metadata := range r.GroupProtocols {
|
||||
if err := pe.putString(name); err != nil {
|
||||
if len(r.GroupProtocols) > 0 {
|
||||
if len(r.OrderedGroupProtocols) > 0 {
|
||||
return PacketDecodingError{"cannot specify both GroupProtocols and OrderedGroupProtocols on JoinGroupRequest"}
|
||||
}
|
||||
|
||||
if err := pe.putArrayLength(len(r.GroupProtocols)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := pe.putBytes(metadata); err != nil {
|
||||
for name, metadata := range r.GroupProtocols {
|
||||
if err := pe.putString(name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := pe.putBytes(metadata); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := pe.putArrayLength(len(r.OrderedGroupProtocols)); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, protocol := range r.OrderedGroupProtocols {
|
||||
if err := protocol.encode(pe); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -62,16 +102,12 @@ func (r *JoinGroupRequest) decode(pd packetDecoder, version int16) (err error) {
|
||||
|
||||
r.GroupProtocols = make(map[string][]byte)
|
||||
for i := 0; i < n; i++ {
|
||||
name, err := pd.getString()
|
||||
if err != nil {
|
||||
protocol := &GroupProtocol{}
|
||||
if err := protocol.decode(pd); err != nil {
|
||||
return err
|
||||
}
|
||||
metadata, err := pd.getBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.GroupProtocols[name] = metadata
|
||||
r.GroupProtocols[protocol.Name] = protocol.Metadata
|
||||
r.OrderedGroupProtocols = append(r.OrderedGroupProtocols, protocol)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -90,11 +126,10 @@ func (r *JoinGroupRequest) requiredVersion() KafkaVersion {
|
||||
}
|
||||
|
||||
func (r *JoinGroupRequest) AddGroupProtocol(name string, metadata []byte) {
|
||||
if r.GroupProtocols == nil {
|
||||
r.GroupProtocols = make(map[string][]byte)
|
||||
}
|
||||
|
||||
r.GroupProtocols[name] = metadata
|
||||
r.OrderedGroupProtocols = append(r.OrderedGroupProtocols, &GroupProtocol{
|
||||
Name: name,
|
||||
Metadata: metadata,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *JoinGroupRequest) AddGroupProtocolMetadata(name string, metadata *ConsumerGroupMemberMetadata) error {
|
||||
|
||||
26
vendor/github.com/Shopify/sarama/join_group_request_test.go
generated
vendored
26
vendor/github.com/Shopify/sarama/join_group_request_test.go
generated
vendored
@@ -23,19 +23,35 @@ var (
|
||||
)
|
||||
|
||||
func TestJoinGroupRequest(t *testing.T) {
|
||||
var request *JoinGroupRequest
|
||||
|
||||
request = new(JoinGroupRequest)
|
||||
request := new(JoinGroupRequest)
|
||||
request.GroupId = "TestGroup"
|
||||
request.SessionTimeout = 100
|
||||
request.ProtocolType = "consumer"
|
||||
testRequest(t, "no protocols", request, joinGroupRequestNoProtocols)
|
||||
}
|
||||
|
||||
request = new(JoinGroupRequest)
|
||||
func TestJoinGroupRequestOneProtocol(t *testing.T) {
|
||||
request := new(JoinGroupRequest)
|
||||
request.GroupId = "TestGroup"
|
||||
request.SessionTimeout = 100
|
||||
request.MemberId = "OneProtocol"
|
||||
request.ProtocolType = "consumer"
|
||||
request.AddGroupProtocol("one", []byte{0x01, 0x02, 0x03})
|
||||
testRequest(t, "one protocol", request, joinGroupRequestOneProtocol)
|
||||
packet := testRequestEncode(t, "one protocol", request, joinGroupRequestOneProtocol)
|
||||
request.GroupProtocols = make(map[string][]byte)
|
||||
request.GroupProtocols["one"] = []byte{0x01, 0x02, 0x03}
|
||||
testRequestDecode(t, "one protocol", request, packet)
|
||||
}
|
||||
|
||||
func TestJoinGroupRequestDeprecatedEncode(t *testing.T) {
|
||||
request := new(JoinGroupRequest)
|
||||
request.GroupId = "TestGroup"
|
||||
request.SessionTimeout = 100
|
||||
request.MemberId = "OneProtocol"
|
||||
request.ProtocolType = "consumer"
|
||||
request.GroupProtocols = make(map[string][]byte)
|
||||
request.GroupProtocols["one"] = []byte{0x01, 0x02, 0x03}
|
||||
packet := testRequestEncode(t, "one protocol", request, joinGroupRequestOneProtocol)
|
||||
request.AddGroupProtocol("one", []byte{0x01, 0x02, 0x03})
|
||||
testRequestDecode(t, "one protocol", request, packet)
|
||||
}
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/join_group_response.go
generated
vendored
7
vendor/github.com/Shopify/sarama/join_group_response.go
generated
vendored
@@ -53,12 +53,13 @@ func (r *JoinGroupResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *JoinGroupResponse) decode(pd packetDecoder, version int16) (err error) {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
|
||||
r.Err = KError(kerr)
|
||||
|
||||
if r.GenerationId, err = pd.getInt32(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
6
vendor/github.com/Shopify/sarama/leave_group_response.go
generated
vendored
6
vendor/github.com/Shopify/sarama/leave_group_response.go
generated
vendored
@@ -10,11 +10,11 @@ func (r *LeaveGroupResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *LeaveGroupResponse) decode(pd packetDecoder, version int16) (err error) {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
r.Err = KError(kerr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/list_groups_response.go
generated
vendored
7
vendor/github.com/Shopify/sarama/list_groups_response.go
generated
vendored
@@ -24,12 +24,13 @@ func (r *ListGroupsResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *ListGroupsResponse) decode(pd packetDecoder, version int16) error {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
|
||||
r.Err = KError(kerr)
|
||||
|
||||
n, err := pd.getArrayLength()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
18
vendor/github.com/Shopify/sarama/message_test.go
generated
vendored
18
vendor/github.com/Shopify/sarama/message_test.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package sarama
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -24,6 +25,17 @@ var (
|
||||
0x08,
|
||||
0, 0, 9, 110, 136, 0, 255, 1, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
emptyGzipMessage18 = []byte{
|
||||
132, 99, 80, 148, //CRC
|
||||
0x00, // magic version byte
|
||||
0x01, // attribute flags
|
||||
0xFF, 0xFF, 0xFF, 0xFF, // key
|
||||
// value
|
||||
0x00, 0x00, 0x00, 0x17,
|
||||
0x1f, 0x8b,
|
||||
0x08,
|
||||
0, 0, 0, 0, 0, 0, 255, 1, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
emptyLZ4Message = []byte{
|
||||
132, 219, 238, 101, // CRC
|
||||
0x01, // version byte
|
||||
@@ -79,7 +91,11 @@ func TestMessageEncoding(t *testing.T) {
|
||||
|
||||
message.Value = []byte{}
|
||||
message.Codec = CompressionGZIP
|
||||
testEncodable(t, "empty gzip", &message, emptyGzipMessage)
|
||||
if runtime.Version() == "go1.8" {
|
||||
testEncodable(t, "empty gzip", &message, emptyGzipMessage18)
|
||||
} else {
|
||||
testEncodable(t, "empty gzip", &message, emptyGzipMessage)
|
||||
}
|
||||
|
||||
message.Value = []byte{}
|
||||
message.Codec = CompressionLZ4
|
||||
|
||||
12
vendor/github.com/Shopify/sarama/partitioner.go
generated
vendored
12
vendor/github.com/Shopify/sarama/partitioner.go
generated
vendored
@@ -87,6 +87,18 @@ type hashPartitioner struct {
|
||||
hasher hash.Hash32
|
||||
}
|
||||
|
||||
// NewCustomHashPartitioner is a wrapper around NewHashPartitioner, allowing the use of custom hasher.
|
||||
// The argument is a function providing the instance, implementing the hash.Hash32 interface. This is to ensure that
|
||||
// each partition dispatcher gets its own hasher, to avoid concurrency issues by sharing an instance.
|
||||
func NewCustomHashPartitioner(hasher func() hash.Hash32) PartitionerConstructor {
|
||||
return func(topic string) Partitioner {
|
||||
p := new(hashPartitioner)
|
||||
p.random = NewRandomPartitioner(topic)
|
||||
p.hasher = hasher()
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
// NewHashPartitioner returns a Partitioner which behaves as follows. If the message's key is nil then a
|
||||
// random partition is chosen. Otherwise the FNV-1a hash of the encoded bytes of the message key is used,
|
||||
// modulus the number of partitions. This ensures that messages with the same key always end up on the
|
||||
|
||||
50
vendor/github.com/Shopify/sarama/partitioner_test.go
generated
vendored
50
vendor/github.com/Shopify/sarama/partitioner_test.go
generated
vendored
@@ -2,6 +2,7 @@ package sarama
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"hash/fnv"
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
@@ -70,6 +71,55 @@ func TestRoundRobinPartitioner(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewHashPartitionerWithHasher(t *testing.T) {
|
||||
// use the current default hasher fnv.New32a()
|
||||
partitioner := NewCustomHashPartitioner(fnv.New32a)("mytopic")
|
||||
|
||||
choice, err := partitioner.Partition(&ProducerMessage{}, 1)
|
||||
if err != nil {
|
||||
t.Error(partitioner, err)
|
||||
}
|
||||
if choice != 0 {
|
||||
t.Error("Returned non-zero partition when only one available.")
|
||||
}
|
||||
|
||||
for i := 1; i < 50; i++ {
|
||||
choice, err := partitioner.Partition(&ProducerMessage{}, 50)
|
||||
if err != nil {
|
||||
t.Error(partitioner, err)
|
||||
}
|
||||
if choice < 0 || choice >= 50 {
|
||||
t.Error("Returned partition", choice, "outside of range for nil key.")
|
||||
}
|
||||
}
|
||||
|
||||
buf := make([]byte, 256)
|
||||
for i := 1; i < 50; i++ {
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
assertPartitioningConsistent(t, partitioner, &ProducerMessage{Key: ByteEncoder(buf)}, 50)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashPartitionerWithHasherMinInt32(t *testing.T) {
|
||||
// use the current default hasher fnv.New32a()
|
||||
partitioner := NewCustomHashPartitioner(fnv.New32a)("mytopic")
|
||||
|
||||
msg := ProducerMessage{}
|
||||
// "1468509572224" generates 2147483648 (uint32) result from Sum32 function
|
||||
// which is -2147483648 or int32's min value
|
||||
msg.Key = StringEncoder("1468509572224")
|
||||
|
||||
choice, err := partitioner.Partition(&msg, 50)
|
||||
if err != nil {
|
||||
t.Error(partitioner, err)
|
||||
}
|
||||
if choice < 0 || choice >= 50 {
|
||||
t.Error("Returned partition", choice, "outside of range for nil key.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashPartitioner(t *testing.T) {
|
||||
partitioner := NewHashPartitioner("mytopic")
|
||||
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/produce_response.go
generated
vendored
7
vendor/github.com/Shopify/sarama/produce_response.go
generated
vendored
@@ -76,11 +76,12 @@ func (r *ProduceResponse) decode(pd packetDecoder, version int16) (err error) {
|
||||
}
|
||||
|
||||
if r.Version >= 1 {
|
||||
if millis, err := pd.getInt32(); err != nil {
|
||||
millis, err := pd.getInt32()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.ThrottleTime = time.Duration(millis) * time.Millisecond
|
||||
}
|
||||
|
||||
r.ThrottleTime = time.Duration(millis) * time.Millisecond
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/real_decoder.go
generated
vendored
7
vendor/github.com/Shopify/sarama/real_decoder.go
generated
vendored
@@ -204,11 +204,12 @@ func (rd *realDecoder) getStringArray() ([]string, error) {
|
||||
|
||||
ret := make([]string, n)
|
||||
for i := range ret {
|
||||
if str, err := rd.getString(); err != nil {
|
||||
str, err := rd.getString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
ret[i] = str
|
||||
}
|
||||
|
||||
ret[i] = str
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
11
vendor/github.com/Shopify/sarama/request_test.go
generated
vendored
11
vendor/github.com/Shopify/sarama/request_test.go
generated
vendored
@@ -50,7 +50,11 @@ func testVersionDecodable(t *testing.T, name string, out versionedDecoder, in []
|
||||
}
|
||||
|
||||
func testRequest(t *testing.T, name string, rb protocolBody, expected []byte) {
|
||||
// Encoder request
|
||||
packet := testRequestEncode(t, name, rb, expected)
|
||||
testRequestDecode(t, name, rb, packet)
|
||||
}
|
||||
|
||||
func testRequestEncode(t *testing.T, name string, rb protocolBody, expected []byte) []byte {
|
||||
req := &request{correlationID: 123, clientID: "foo", body: rb}
|
||||
packet, err := encode(req, nil)
|
||||
headerSize := 14 + len("foo")
|
||||
@@ -59,7 +63,10 @@ func testRequest(t *testing.T, name string, rb protocolBody, expected []byte) {
|
||||
} else if !bytes.Equal(packet[headerSize:], expected) {
|
||||
t.Error("Encoding", name, "failed\ngot ", packet[headerSize:], "\nwant", expected)
|
||||
}
|
||||
// Decoder request
|
||||
return packet
|
||||
}
|
||||
|
||||
func testRequestDecode(t *testing.T, name string, rb protocolBody, packet []byte) {
|
||||
decoded, n, err := decodeRequest(bytes.NewReader(packet))
|
||||
if err != nil {
|
||||
t.Error("Failed to decode request", err)
|
||||
|
||||
8
vendor/github.com/Shopify/sarama/sasl_handshake_response.go
generated
vendored
8
vendor/github.com/Shopify/sarama/sasl_handshake_response.go
generated
vendored
@@ -11,13 +11,13 @@ func (r *SaslHandshakeResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *SaslHandshakeResponse) decode(pd packetDecoder, version int16) error {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
|
||||
var err error
|
||||
r.Err = KError(kerr)
|
||||
|
||||
if r.EnabledMechanisms, err = pd.getStringArray(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
7
vendor/github.com/Shopify/sarama/sync_group_response.go
generated
vendored
7
vendor/github.com/Shopify/sarama/sync_group_response.go
generated
vendored
@@ -17,12 +17,13 @@ func (r *SyncGroupResponse) encode(pe packetEncoder) error {
|
||||
}
|
||||
|
||||
func (r *SyncGroupResponse) decode(pd packetDecoder, version int16) (err error) {
|
||||
if kerr, err := pd.getInt16(); err != nil {
|
||||
kerr, err := pd.getInt16()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
r.Err = KError(kerr)
|
||||
}
|
||||
|
||||
r.Err = KError(kerr)
|
||||
|
||||
r.MemberAssignment, err = pd.getBytes()
|
||||
return
|
||||
}
|
||||
|
||||
8
vendor/github.com/Shopify/sarama/sync_producer.go
generated
vendored
8
vendor/github.com/Shopify/sarama/sync_producer.go
generated
vendored
@@ -25,10 +25,10 @@ type SyncProducer interface {
|
||||
// SendMessages will return an error.
|
||||
SendMessages(msgs []*ProducerMessage) error
|
||||
|
||||
// Close shuts down the producer and flushes any messages it may have buffered.
|
||||
// You must call this function before a producer object passes out of scope, as
|
||||
// it may otherwise leak memory. You must call this before calling Close on the
|
||||
// underlying client.
|
||||
// Close shuts down the producer and waits for any buffered messages to be
|
||||
// flushed. You must call this function before a producer object passes out of
|
||||
// scope, as it may otherwise leak memory. You must call this before calling
|
||||
// Close on the underlying client.
|
||||
Close() error
|
||||
}
|
||||
|
||||
|
||||
6
vendor/github.com/Shopify/sarama/sync_producer_test.go
generated
vendored
6
vendor/github.com/Shopify/sarama/sync_producer_test.go
generated
vendored
@@ -76,17 +76,17 @@ func TestSyncProducerBatch(t *testing.T) {
|
||||
}
|
||||
|
||||
err = producer.SendMessages([]*ProducerMessage{
|
||||
&ProducerMessage{
|
||||
{
|
||||
Topic: "my_topic",
|
||||
Value: StringEncoder(TestMessage),
|
||||
Metadata: "test",
|
||||
},
|
||||
&ProducerMessage{
|
||||
{
|
||||
Topic: "my_topic",
|
||||
Value: StringEncoder(TestMessage),
|
||||
Metadata: "test",
|
||||
},
|
||||
&ProducerMessage{
|
||||
{
|
||||
Topic: "my_topic",
|
||||
Value: StringEncoder(TestMessage),
|
||||
Metadata: "test",
|
||||
|
||||
1
vendor/github.com/Shopify/sarama/utils.go
generated
vendored
1
vendor/github.com/Shopify/sarama/utils.go
generated
vendored
@@ -148,5 +148,6 @@ var (
|
||||
V0_10_0_0 = newKafkaVersion(0, 10, 0, 0)
|
||||
V0_10_0_1 = newKafkaVersion(0, 10, 0, 1)
|
||||
V0_10_1_0 = newKafkaVersion(0, 10, 1, 0)
|
||||
V0_10_2_0 = newKafkaVersion(0, 10, 2, 0)
|
||||
minVersion = V0_8_2_0
|
||||
)
|
||||
|
||||
4
vendor/github.com/coreos/etcd/README.md
generated
vendored
4
vendor/github.com/coreos/etcd/README.md
generated
vendored
@@ -78,7 +78,7 @@ That's it! etcd is now running and serving client requests. For more
|
||||
|
||||
The [official etcd ports][iana-ports] are 2379 for client requests, and 2380 for peer communication.
|
||||
|
||||
[iana-ports]: https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=etcd
|
||||
[iana-ports]: http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
|
||||
|
||||
### Running a local etcd cluster
|
||||
|
||||
@@ -136,5 +136,3 @@ See [reporting bugs](Documentation/reporting_bugs.md) for details about reportin
|
||||
### License
|
||||
|
||||
etcd is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
|
||||
|
||||
|
||||
|
||||
150
vendor/github.com/coreos/go-oidc/gen.go
generated
vendored
150
vendor/github.com/coreos/go-oidc/gen.go
generated
vendored
@@ -1,150 +0,0 @@
|
||||
// +build ignore
|
||||
|
||||
// This file is used to generate keys for tests.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"text/template"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
type key struct {
|
||||
name string
|
||||
new func() (crypto.Signer, error)
|
||||
}
|
||||
|
||||
var keys = []key{
|
||||
{
|
||||
"ECDSA_256", func() (crypto.Signer, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
},
|
||||
},
|
||||
{
|
||||
"ECDSA_384", func() (crypto.Signer, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
},
|
||||
},
|
||||
{
|
||||
"ECDSA_521", func() (crypto.Signer, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
},
|
||||
},
|
||||
{
|
||||
"RSA_1024", func() (crypto.Signer, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 1024)
|
||||
},
|
||||
},
|
||||
{
|
||||
"RSA_2048", func() (crypto.Signer, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 2048)
|
||||
},
|
||||
},
|
||||
{
|
||||
"RSA_4096", func() (crypto.Signer, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 4096)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func newJWK(k key, prefix, ident string) (privBytes, pubBytes []byte, err error) {
|
||||
priv, err := k.new()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("generate %s: %v", k.name, err)
|
||||
}
|
||||
pub := priv.Public()
|
||||
|
||||
privKey := &jose.JSONWebKey{Key: priv}
|
||||
thumbprint, err := privKey.Thumbprint(crypto.SHA256)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("computing thumbprint: %v", err)
|
||||
}
|
||||
|
||||
keyID := hex.EncodeToString(thumbprint)
|
||||
privKey.KeyID = keyID
|
||||
pubKey := &jose.JSONWebKey{Key: pub, KeyID: keyID}
|
||||
|
||||
privBytes, err = json.MarshalIndent(privKey, prefix, ident)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pubBytes, err = json.MarshalIndent(pubKey, prefix, ident)
|
||||
return
|
||||
}
|
||||
|
||||
type keyData struct {
|
||||
Name string
|
||||
Priv string
|
||||
Pub string
|
||||
}
|
||||
|
||||
var tmpl = template.Must(template.New("").Parse(`// +build !golint
|
||||
|
||||
// This file contains statically created JWKs for tests created by gen.go
|
||||
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
func mustLoadJWK(s string) jose.JSONWebKey {
|
||||
var jwk jose.JSONWebKey
|
||||
if err := json.Unmarshal([]byte(s), &jwk); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return jwk
|
||||
}
|
||||
|
||||
var (
|
||||
{{- range $i, $key := .Keys }}
|
||||
testKey{{ $key.Name }} = mustLoadJWK(` + "`" + `{{ $key.Pub }}` + "`" + `)
|
||||
testKey{{ $key.Name }}_Priv = mustLoadJWK(` + "`" + `{{ $key.Priv }}` + "`" + `)
|
||||
{{ end -}}
|
||||
)
|
||||
`))
|
||||
|
||||
func main() {
|
||||
var tmplData struct {
|
||||
Keys []keyData
|
||||
}
|
||||
for _, k := range keys {
|
||||
for i := 0; i < 4; i++ {
|
||||
log.Printf("generating %s", k.name)
|
||||
priv, pub, err := newJWK(k, "\t", "\t")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
name := fmt.Sprintf("%s_%d", k.name, i)
|
||||
|
||||
tmplData.Keys = append(tmplData.Keys, keyData{
|
||||
Name: name,
|
||||
Priv: string(priv),
|
||||
Pub: string(pub),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
buff := new(bytes.Buffer)
|
||||
if err := tmpl.Execute(buff, tmplData); err != nil {
|
||||
log.Fatalf("excuting template: %v", err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile("jose_test.go", buff.Bytes(), 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
405
vendor/github.com/coreos/go-oidc/jose_test.go
generated
vendored
405
vendor/github.com/coreos/go-oidc/jose_test.go
generated
vendored
@@ -1,405 +0,0 @@
|
||||
// +build !golint
|
||||
|
||||
// This file contains statically created JWKs for tests created by gen.go
|
||||
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
func mustLoadJWK(s string) jose.JSONWebKey {
|
||||
var jwk jose.JSONWebKey
|
||||
if err := json.Unmarshal([]byte(s), &jwk); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return jwk
|
||||
}
|
||||
|
||||
var (
|
||||
testKeyECDSA_256_0 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bd06f3e11f523e310f8c2c8b20a892727fb558e0e23602312568b20a41e11188",
|
||||
"crv": "P-256",
|
||||
"x": "xK5N69f0-SAgWbjw2otcQeCGs3qqYMyqOWk4Os5Z_Xc",
|
||||
"y": "AXSaOPcMklJY9UKZhkGzVevqhAIUEzE3cfZ8o-ML5xE"
|
||||
}`)
|
||||
testKeyECDSA_256_0_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bd06f3e11f523e310f8c2c8b20a892727fb558e0e23602312568b20a41e11188",
|
||||
"crv": "P-256",
|
||||
"x": "xK5N69f0-SAgWbjw2otcQeCGs3qqYMyqOWk4Os5Z_Xc",
|
||||
"y": "AXSaOPcMklJY9UKZhkGzVevqhAIUEzE3cfZ8o-ML5xE",
|
||||
"d": "L7jynYt-fMRPqw1e9vgXCGTg4yhGU4tlLxiFyNVimG4"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_256_1 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "27ebd2f5bf6723e4de06caaab03703be458a37bf28a9fa748576a0826acb6ec2",
|
||||
"crv": "P-256",
|
||||
"x": "KZisP6wLCph4q6056jr7BH_asiX9RcLcS3HrNjdCpkw",
|
||||
"y": "5DrW-kEge0sePHlKmh1d2kqd10r32JEW6eyyewy18j8"
|
||||
}`)
|
||||
testKeyECDSA_256_1_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "27ebd2f5bf6723e4de06caaab03703be458a37bf28a9fa748576a0826acb6ec2",
|
||||
"crv": "P-256",
|
||||
"x": "KZisP6wLCph4q6056jr7BH_asiX9RcLcS3HrNjdCpkw",
|
||||
"y": "5DrW-kEge0sePHlKmh1d2kqd10r32JEW6eyyewy18j8",
|
||||
"d": "r6CiIpv0icIq5U4LYO39nBDVhCHCLObDFYC5IG9Y8Hk"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_256_2 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "2c7d179db6006c90ece4d91f554791ff35156693c693102c00f66f473d15df17",
|
||||
"crv": "P-256",
|
||||
"x": "oDwcKp7SqgeRvycK5GgYjrlW4fbHn2Ybfd5iG7kDiPc",
|
||||
"y": "qazib9UwdUdbHSFzdy_HN10xZEItLvufPw0v7nIJOWA"
|
||||
}`)
|
||||
testKeyECDSA_256_2_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "2c7d179db6006c90ece4d91f554791ff35156693c693102c00f66f473d15df17",
|
||||
"crv": "P-256",
|
||||
"x": "oDwcKp7SqgeRvycK5GgYjrlW4fbHn2Ybfd5iG7kDiPc",
|
||||
"y": "qazib9UwdUdbHSFzdy_HN10xZEItLvufPw0v7nIJOWA",
|
||||
"d": "p79U6biKrOyrKzg-i3C7FVJiqzlqBhYQqmyOiZ9bhVM"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_256_3 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "aba0a256999af470c8b2449103ae75b257d907da4d1cbfc73c1d45ab1098f544",
|
||||
"crv": "P-256",
|
||||
"x": "CKRYWVt1R7FzuJ43vEprfIzgB-KgIhRDhxLmd5ixiXY",
|
||||
"y": "QCxTVmK31ee710OYkNqdqEgHH3rqRQNQj3Wyq0xtYq0"
|
||||
}`)
|
||||
testKeyECDSA_256_3_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "aba0a256999af470c8b2449103ae75b257d907da4d1cbfc73c1d45ab1098f544",
|
||||
"crv": "P-256",
|
||||
"x": "CKRYWVt1R7FzuJ43vEprfIzgB-KgIhRDhxLmd5ixiXY",
|
||||
"y": "QCxTVmK31ee710OYkNqdqEgHH3rqRQNQj3Wyq0xtYq0",
|
||||
"d": "c_WflwwUxT_B5izk4iET49qoob0RH5hccnEScfBS9Qk"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_0 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bc271d0a68251171e0c5edfd384b32d154e1717af27c5089bda8fb598a474b7b",
|
||||
"crv": "P-384",
|
||||
"x": "FZEhxw06oB86xCAZCtKTfX3ze9tgxkdN199g-cWrpQTWF-2m6Blg1MN5D60Z9KoX",
|
||||
"y": "EyWjZ46gLlqfoU08iv0zcDWut1nbfoUoTd-7La2VY4PqQeDSFrxPCOyplxFMGJIW"
|
||||
}`)
|
||||
testKeyECDSA_384_0_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "bc271d0a68251171e0c5edfd384b32d154e1717af27c5089bda8fb598a474b7b",
|
||||
"crv": "P-384",
|
||||
"x": "FZEhxw06oB86xCAZCtKTfX3ze9tgxkdN199g-cWrpQTWF-2m6Blg1MN5D60Z9KoX",
|
||||
"y": "EyWjZ46gLlqfoU08iv0zcDWut1nbfoUoTd-7La2VY4PqQeDSFrxPCOyplxFMGJIW",
|
||||
"d": "t6oJHJBH2rvH3uyQkK_JwoUEwE1QHjwTnGLSDMZbNEDrEaR8BBiAo3s0p8rzGz5-"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_1 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "58ef375d6e63cedc637fed59f4012a779cd749a83373237cf3972bba74ebd738",
|
||||
"crv": "P-384",
|
||||
"x": "Gj3zkiRR4RCJb0Tke3lD2spG2jzuXgX50fEwDZTRjlQIzz3Rc96Fw32FCSDectxQ",
|
||||
"y": "6alqN7ilqJAmqCU1BFrJJeivJiM0s1-RqBewRoNkTQinOLLbaiZlBAQxS4iq2dRv"
|
||||
}`)
|
||||
testKeyECDSA_384_1_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "58ef375d6e63cedc637fed59f4012a779cd749a83373237cf3972bba74ebd738",
|
||||
"crv": "P-384",
|
||||
"x": "Gj3zkiRR4RCJb0Tke3lD2spG2jzuXgX50fEwDZTRjlQIzz3Rc96Fw32FCSDectxQ",
|
||||
"y": "6alqN7ilqJAmqCU1BFrJJeivJiM0s1-RqBewRoNkTQinOLLbaiZlBAQxS4iq2dRv",
|
||||
"d": "-4eaoElyb_YANRownMtId_-glX2o45oc4_L_vgo3YOW5hxCq3KIBIdrhvBx1nw8B"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_2 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "a8bab6f438b6cd2080711404549c978d1c00dd77a3c532bba12c964c4883b2ec",
|
||||
"crv": "P-384",
|
||||
"x": "CBKwYgZFLdTBBFnWD20q2YNUnRnOsDgTxG3y-dzCUrb65kOKm0ZFaZQPe5ZPjvDS",
|
||||
"y": "WlubxLv2qH-Aw-LsESKXAwm4HF3l4H1rVn3DZRpqcac6p-QSrXmfKCtxJVHDaTNi"
|
||||
}`)
|
||||
testKeyECDSA_384_2_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "a8bab6f438b6cd2080711404549c978d1c00dd77a3c532bba12c964c4883b2ec",
|
||||
"crv": "P-384",
|
||||
"x": "CBKwYgZFLdTBBFnWD20q2YNUnRnOsDgTxG3y-dzCUrb65kOKm0ZFaZQPe5ZPjvDS",
|
||||
"y": "WlubxLv2qH-Aw-LsESKXAwm4HF3l4H1rVn3DZRpqcac6p-QSrXmfKCtxJVHDaTNi",
|
||||
"d": "XfoOcxV3yfoAcRquJ9eaBvcY-H71B0XzXwx2eidolHDKLK7GHygEt9ToYSY_DvxO"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_384_3 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "32f0cfc686455840530d727fb029002b9757ffff15272f98f53be9f77560718a",
|
||||
"crv": "P-384",
|
||||
"x": "xxED1z8EUCOUQ_jwS9nuVUDVzxs-U1rl19y8jMWrv4TdPeGHTRTgNUE57-YAL3ly",
|
||||
"y": "OsCN6-HmM-LP1itE5eW15WsSQoe3dZBX7AoHyKJUKtjzWKCJNUcyu3Np07xta1Cr"
|
||||
}`)
|
||||
testKeyECDSA_384_3_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "32f0cfc686455840530d727fb029002b9757ffff15272f98f53be9f77560718a",
|
||||
"crv": "P-384",
|
||||
"x": "xxED1z8EUCOUQ_jwS9nuVUDVzxs-U1rl19y8jMWrv4TdPeGHTRTgNUE57-YAL3ly",
|
||||
"y": "OsCN6-HmM-LP1itE5eW15WsSQoe3dZBX7AoHyKJUKtjzWKCJNUcyu3Np07xta1Cr",
|
||||
"d": "gfQA6wn4brWVT3OkeGiaCXGsQyTybZB9SdqTULsiSg8n6FS2T8hvK0doPwMTT5Gw"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_0 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "f7b325c848a6c9fc5b72f131f179d2f37296837262797983c632597a4927726e",
|
||||
"crv": "P-521",
|
||||
"x": "AUaLqCAMEWPqiYgd-D_6F5kxpOgqnbQnjIHZ-NhjRnKKYuij9Iz7bq9pZU4F79wsODFpWxMFfISrveUfgEGt4Hy2",
|
||||
"y": "AeAKfmFsfcFttwQqv2B-fUfgLhw837YoGoNWh5qNE_LqTBxbYKRUkbSLxVRHEcVNnU1t3z9yMMdYXtuMlfJ0bhjr"
|
||||
}`)
|
||||
testKeyECDSA_521_0_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "f7b325c848a6c9fc5b72f131f179d2f37296837262797983c632597a4927726e",
|
||||
"crv": "P-521",
|
||||
"x": "AUaLqCAMEWPqiYgd-D_6F5kxpOgqnbQnjIHZ-NhjRnKKYuij9Iz7bq9pZU4F79wsODFpWxMFfISrveUfgEGt4Hy2",
|
||||
"y": "AeAKfmFsfcFttwQqv2B-fUfgLhw837YoGoNWh5qNE_LqTBxbYKRUkbSLxVRHEcVNnU1t3z9yMMdYXtuMlfJ0bhjr",
|
||||
"d": "AbD3guIvlVd8CZD0xUNuebgnQkE24XJnxCQ69P5VL3etEMmdr4HPJLPMQfMs10Gz8RTmrGKo-bdsU-cjS3d7dKIC"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_1 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "4ea260ba2c9ed5fe9d6adeb998bb68b3edbab839d8bfd2be09fa628680793b90",
|
||||
"crv": "P-521",
|
||||
"x": "AE8-53o64GiywneanVZAHb96NcPbq0Ml6zynIcgLdKUiHGVs2te7SABq_9keFZJC6wooACeNWWT7VDK3kY77fjdh",
|
||||
"y": "AAnrIu0-D7JEd3-mqTR8Rdz53kw7DLAIypv0-_u4rqn0glwTZCkMpQ17wFH71bMInXaTi2Z_uq67NuVxFvUCaTvS"
|
||||
}`)
|
||||
testKeyECDSA_521_1_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "4ea260ba2c9ed5fe9d6adeb998bb68b3edbab839d8bfd2be09fa628680793b90",
|
||||
"crv": "P-521",
|
||||
"x": "AE8-53o64GiywneanVZAHb96NcPbq0Ml6zynIcgLdKUiHGVs2te7SABq_9keFZJC6wooACeNWWT7VDK3kY77fjdh",
|
||||
"y": "AAnrIu0-D7JEd3-mqTR8Rdz53kw7DLAIypv0-_u4rqn0glwTZCkMpQ17wFH71bMInXaTi2Z_uq67NuVxFvUCaTvS",
|
||||
"d": "AVVL9TIWcJCYH5r3QUhHXtsbkVXhLQSpp4sL1ta_H2_3bpRb9ZdVv10YOA-xN7Yz2wa-FMhIhj1ULe9z18ZM8dDF"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_2 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "d69caddc821807ea63a46519b538a7d2f3135dbdda1ba628781f8567a47893d8",
|
||||
"crv": "P-521",
|
||||
"x": "AO618rH8GP78-mi9Z5FaPGqpyc_OVMK-BajZK-pwL89ZQdOvFa0fY0ENpB_KaRf5ELw9IP17lQh3T-O9O7jePDFj",
|
||||
"y": "AT1x9pCMbY-BXqAJPQDQxp6j8Gca7IpdxL8OS4td_XPiwXtX4JKcj_VKxtOw6k64yr_VuFYCs6wImOc72jNRBjA7"
|
||||
}`)
|
||||
testKeyECDSA_521_2_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "d69caddc821807ea63a46519b538a7d2f3135dbdda1ba628781f8567a47893d8",
|
||||
"crv": "P-521",
|
||||
"x": "AO618rH8GP78-mi9Z5FaPGqpyc_OVMK-BajZK-pwL89ZQdOvFa0fY0ENpB_KaRf5ELw9IP17lQh3T-O9O7jePDFj",
|
||||
"y": "AT1x9pCMbY-BXqAJPQDQxp6j8Gca7IpdxL8OS4td_XPiwXtX4JKcj_VKxtOw6k64yr_VuFYCs6wImOc72jNRBjA7",
|
||||
"d": "AYmtaW9ojb0Gb8zSqrlRnEKzRVIBIM5dsb1qWkd3mfr4Wl5tbPuiEctGLN9s6LDtY0JOL3nukOVoDbrmS4qCW64"
|
||||
}`)
|
||||
|
||||
testKeyECDSA_521_3 = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "7193cba4fd9c72153133ce5cffc423857517ab8eb176a827e1a002eb5621edca",
|
||||
"crv": "P-521",
|
||||
"x": "AQfpLehZCER3ZTw1V1pN0RsX8-4WEW4IDxFDSGwrULQ79YHiLNmubrOSlSxiOSv2S-tHq-hxgma1PZlQRghJfemx",
|
||||
"y": "AAF41XT7jptLsy8FAaVRnex2WcSfdebcjjXMGO4rn6IlD3u9qnvrpR8MBp1gz5G1C5S7_NVgIeLSIYbdfd_wjVkd"
|
||||
}`)
|
||||
testKeyECDSA_521_3_Priv = mustLoadJWK(`{
|
||||
"kty": "EC",
|
||||
"kid": "7193cba4fd9c72153133ce5cffc423857517ab8eb176a827e1a002eb5621edca",
|
||||
"crv": "P-521",
|
||||
"x": "AQfpLehZCER3ZTw1V1pN0RsX8-4WEW4IDxFDSGwrULQ79YHiLNmubrOSlSxiOSv2S-tHq-hxgma1PZlQRghJfemx",
|
||||
"y": "AAF41XT7jptLsy8FAaVRnex2WcSfdebcjjXMGO4rn6IlD3u9qnvrpR8MBp1gz5G1C5S7_NVgIeLSIYbdfd_wjVkd",
|
||||
"d": "hzh0loqrhYFUik86SYBv3CC_GKNYankLMK95-Cfr1gLBD1l0M6W-7gn3XlyaQEInz0TBIbaQ1fL78HHjbVsNLrY"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_0 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "979d62e7114052027b11bcb51282d8228790134ef34e746f6372fa5aadaa9bf2",
|
||||
"n": "6zxmGE5X74SUBWfDEo8Tl-YxrkVfvxljQG9vKmNPQ2RhEmJ8eplZpKn9_nlxVDHGLzfJMqqUBS19EarIfDnOqyFBRkyKRbsQdUVU9XLjDIXqImJ8aN-UmShAYoeOClJVDsBJuxBGgS3pdgG7u3YQpvTV_hGuMoJr7UYgIrqb0qc",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_0_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "979d62e7114052027b11bcb51282d8228790134ef34e746f6372fa5aadaa9bf2",
|
||||
"n": "6zxmGE5X74SUBWfDEo8Tl-YxrkVfvxljQG9vKmNPQ2RhEmJ8eplZpKn9_nlxVDHGLzfJMqqUBS19EarIfDnOqyFBRkyKRbsQdUVU9XLjDIXqImJ8aN-UmShAYoeOClJVDsBJuxBGgS3pdgG7u3YQpvTV_hGuMoJr7UYgIrqb0qc",
|
||||
"e": "AQAB",
|
||||
"d": "IARggP5oyZjp7LJqwqPmrs4OBQI8Pe5eq-5-2u4ZY7rN24q8FpO4t8jLYU92NVdw-gxFvjepXesLEtSD5SSZFD7s-5rqmX9tW_t5t1a1sBY6IKz_YBSf2p2LtdTyrqgo4nRD0nYH3sMvGtOKCTV4K_vwfWPD3elXq752trG-HwE",
|
||||
"p": "9tgo12L3earNNrJfyIIDD2dqgKuNfWhQzhbe-Ju17dF37uGF6xnLqR0WXU-agGpUdYTMOd7IQi_bX_xkjQBYlw",
|
||||
"q": "8_YDvufPdccjGM2rAXs-2LbeP_LrzLUk1uGNpEjIt2lXEm6sQKjIfNLcAfVKh9zsqwqroveL2iI1ijsDgNAIcQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_1 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4a3a37dc10aec5f427509e4014683102a0fafa32bec2ff9921ff19e1a55c79e8",
|
||||
"n": "sn7sU7dBEkU1RBIz_LKgrswSS7-68vTlOe7n-lanAqAlczm01_6IWrvcIC7lPv1iHQqWngusskANZirCZGTv6kK8kJLHBVRSROB9VkPTPNFYnSB6dacyPa0ty0otsaYOVM2RFvcCX7lBKKat2Tmst8vITdpvnoEzTgT_eGOKGAs",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_1_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4a3a37dc10aec5f427509e4014683102a0fafa32bec2ff9921ff19e1a55c79e8",
|
||||
"n": "sn7sU7dBEkU1RBIz_LKgrswSS7-68vTlOe7n-lanAqAlczm01_6IWrvcIC7lPv1iHQqWngusskANZirCZGTv6kK8kJLHBVRSROB9VkPTPNFYnSB6dacyPa0ty0otsaYOVM2RFvcCX7lBKKat2Tmst8vITdpvnoEzTgT_eGOKGAs",
|
||||
"e": "AQAB",
|
||||
"d": "KTXqpE1sBaba7HNzc0Vemdzd4IVMyWlHPz_saTz2ZEHLQ7YwDapjmudCpF-PaCKiM2hNbAHwBluJfGwk4372cPHcJyri3Gs4GGj-cOlbXJh9aUp5o8fqn904B1UcPxMZ2DrZAKjseuLj3zyJgCsSJOGU1kJFRAkM8UN4a9cE8sE",
|
||||
"p": "3ntHMGDJEXwqldLNR-DucKGp32aJVAaKnn4j9qy1Tj6KhH70o3HyFVO_TKYxGg-pG3zTV-VzyMqmeh9hDdnyKw",
|
||||
"q": "zWMxEjyxvp-P-mNxhWQe1pJXZi6iPpcnt0SZLfweT3AtAzEaoSs4-4D1jT911LD4xDI8_a7-gYHgD8ME62PhoQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_2 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d1c32aaea6c9527038e589dd94a546ca1beedb90f90e073228986cc258cf1fda",
|
||||
"n": "3mZrDaB5-7e29zok9XkGuu6FXYB00FqFgnGTJAGCMpql5uHz1h9p0DljZL4vsGkkYOZUMvqFS1pCEuzdSsupPNClf0NKMRux6yLv6iIR9C4pE9RBKPUrinzJuYs634rq5JOEP4IpP_fJfKxMw4Na85otd9KposKwP14cCkOibYM",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_2_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d1c32aaea6c9527038e589dd94a546ca1beedb90f90e073228986cc258cf1fda",
|
||||
"n": "3mZrDaB5-7e29zok9XkGuu6FXYB00FqFgnGTJAGCMpql5uHz1h9p0DljZL4vsGkkYOZUMvqFS1pCEuzdSsupPNClf0NKMRux6yLv6iIR9C4pE9RBKPUrinzJuYs634rq5JOEP4IpP_fJfKxMw4Na85otd9KposKwP14cCkOibYM",
|
||||
"e": "AQAB",
|
||||
"d": "Ft2M0B_ZqsmepBh0SFCjIoD3cT-NwwYrh9fJewA0tKM1v2EnwrIEHQZpc6giGw8UUGod6gfbwH2NIYj8z33U7lyrKWPR7F8gJRm1KR5NLCBCnAnz0ukhsg24ktB25LZLZRCStRRhtCev95Vvmew0ip5081hv730Z2T_PsEyOU6E",
|
||||
"p": "8moFzLKJSQuhaIYTo1qNX0w8o4NBFb1atOlthHmq6Y6rdYTm_nyM9Q3mrNBolPS7LHTiBXtCEJ_m4V5hWDuGKw",
|
||||
"q": "6t0_mZKOoZ5NAE--MxkuOCcRhuqNo9VoacfPEH39CeoKAam4v5k56R7aQcb_raQK396pgV-evM2dpfdUaasiCQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_1024_3 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "838742d0e3195b19f974fa30352db79070fa19aaaeb678ec95c499de7bd48d52",
|
||||
"n": "17Uc89-QvCjqBLXDJSCWxUoohjwFPI63Gub8g-lH1GSK3flXqiohz33KfKhqrdKsLrpRjskGTMg3Vo0IcLBnMYdp1i1nceORghtYLQsDNS7tqlHiKx725fLmWldGgiuP_0Ak0Knisw-j_q7Jx3OVAJnuS1o3vPLfJxJdyq6yV1k",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_1024_3_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "838742d0e3195b19f974fa30352db79070fa19aaaeb678ec95c499de7bd48d52",
|
||||
"n": "17Uc89-QvCjqBLXDJSCWxUoohjwFPI63Gub8g-lH1GSK3flXqiohz33KfKhqrdKsLrpRjskGTMg3Vo0IcLBnMYdp1i1nceORghtYLQsDNS7tqlHiKx725fLmWldGgiuP_0Ak0Knisw-j_q7Jx3OVAJnuS1o3vPLfJxJdyq6yV1k",
|
||||
"e": "AQAB",
|
||||
"d": "B8cM-zIVauNixLa1CZKqPQTWfziMy8ktivfHJQ51O5BAfY5u_cC1JWEYuvPrnMba1Hh9VlOjOYOCk0lUg5OotMx5hxym6M5y_2rIrW90a8r3gGttPlZmyHQnFIgj2QZHlEyZGU1SIPTOtoECW5RGk7cYpA1s1_zfz8uyG-MiCPE",
|
||||
"p": "2dwia5iWWLZwFcCVylPh_7QDr3Wxt3kW_TmHIbaRT10Rborj1lAwltyEx7aVpHq-aNfvrYIEBbOXWwUU8PDUrQ",
|
||||
"q": "_XiDT55hn-Txi2C_peMVSDgXozf01qHKvdLirXM2uT_CI8kruYZYjWYn6_cSUptJ60eioM3WNTxjrSxWRS923Q"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_0 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "13b668c7b4f5d46d53de65e4b9f9c522fad4870e4d1656e459c88de6e90984d6",
|
||||
"n": "1j-CxBxkn20C_M24t6ueLp02T4MMAiPLXf5yaDcj7EcsXGbnsGEhrAUwCZwdEJAxeZ0PolmlE0XBOhQfRtsCVJmwu918aknptToyDbOUBr6WtPIK_c_BuGVanLCx3SnczV4jle9Bz7tGfpj2vAXytSBrfnZhdCHNEFeefQTQMnavfMhfWf_njiTa76BRyAHjb-XZIJHKovwBu0y3glmzhSKYNsUrW11RsWx6DbueWEbE3FpsHTiEdnJipcP3UKl3Z2z6t6n9ZYtFWkx4zCVVBQu-RWUQwjr2XnR1LFwXgL9xQocDBmS1O-wMTHqL3_oosNUdV3vuMPdxs_SEoys2rQ",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_0_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "13b668c7b4f5d46d53de65e4b9f9c522fad4870e4d1656e459c88de6e90984d6",
|
||||
"n": "1j-CxBxkn20C_M24t6ueLp02T4MMAiPLXf5yaDcj7EcsXGbnsGEhrAUwCZwdEJAxeZ0PolmlE0XBOhQfRtsCVJmwu918aknptToyDbOUBr6WtPIK_c_BuGVanLCx3SnczV4jle9Bz7tGfpj2vAXytSBrfnZhdCHNEFeefQTQMnavfMhfWf_njiTa76BRyAHjb-XZIJHKovwBu0y3glmzhSKYNsUrW11RsWx6DbueWEbE3FpsHTiEdnJipcP3UKl3Z2z6t6n9ZYtFWkx4zCVVBQu-RWUQwjr2XnR1LFwXgL9xQocDBmS1O-wMTHqL3_oosNUdV3vuMPdxs_SEoys2rQ",
|
||||
"e": "AQAB",
|
||||
"d": "C8F4X2Jfcw_8Nfrjw9A64bvmmv5JzmRAaGvpwyYjZneRS5Cp7demjVXLiPtz7NC8pjuj-_iHQkN1ksY_4RdrTVERjX1dskdT94m17WKJIMWcZ1lQmRSpQIDvM-HOIKCHaQ1dToDOT6Oq_o9OGosJAj9BJrNALasdIWRtYda9xcb7roLl_U3AtOlK9RiFygtt5uVBIPh1rsxaT0Y1MvMk4EMbFnv7NXXk65UM_3p2leSoPpO7LvlYs3WoRRX9ABH7zI-ppwLGEDuxfnwKzAOaRBe9oUh5rTYdazaY9XqofvekBc9Xqa2HpjkYX-L4Zy3oj04u-u5zX8KTh25jFC2a0Q",
|
||||
"p": "6L6icXqV7jLSXHrhMyLpW-tdFFp2XRQ_uKk972jmUJ-sEeh1YYSx_JpK6oaUnYshGbRLfEAOLy03iweAL4uMZJcASOR44TwSnn_qJZ72PkwhD42uKhE0eJRpxVht6jf5qhsynaMNUWc_FIW5ESpQIf6j4rqFV5WrKHAt0ypChTc",
|
||||
"q": "66fAza4rLvyjqQAIGQ07RiRYW4no1h4cK8RH_CDUgI3CCFQSuqTB8ZqM38r2u0tZoKzCNgHcnde6Jk07X6-LSQW2kypMXt3idbgaeVSYSbdZndgG_jTibJvoybxSjo6HfLpPvCrfsihXo7O5M13LE7VqBLbGTLI5iubOxcrfFTs"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_1 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "6d2b0efff0011bbbbf694de684b5b97cf454fd4086fa53b9af92545f3fa65459",
|
||||
"n": "1CmSBUbxU1jjnmaBG0r0cLLmyZgCOMbfpG6Z3HwfVDgCK6P-rU3F6QQazrOgGJJ0sz6vP50VK5u7BR6vSrPBBX5CicJPM2iNdz2JuV9ODEIkDQBLeI6TfIGhNOls-14tXKOPExY8b6JdyDMP31Hwo_0pF1FaunZ7yY1bgoKCtDV5-RKGd2EgylDGNPu0Ilr92MqCsAntBC8eQSkO4CcTcti4t9cX45VY5nPtwQRmp5zIgUHnU4LV3QVTLJnU-uidaAxRVQbS1pVql5xR6nYZHYvFk1IU-wTY6gGk5WvGWWQ440UTTaMAfnJP6VFDggUXeGSlKfKkDcz7JLT2Ma2KXQ",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_1_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "6d2b0efff0011bbbbf694de684b5b97cf454fd4086fa53b9af92545f3fa65459",
|
||||
"n": "1CmSBUbxU1jjnmaBG0r0cLLmyZgCOMbfpG6Z3HwfVDgCK6P-rU3F6QQazrOgGJJ0sz6vP50VK5u7BR6vSrPBBX5CicJPM2iNdz2JuV9ODEIkDQBLeI6TfIGhNOls-14tXKOPExY8b6JdyDMP31Hwo_0pF1FaunZ7yY1bgoKCtDV5-RKGd2EgylDGNPu0Ilr92MqCsAntBC8eQSkO4CcTcti4t9cX45VY5nPtwQRmp5zIgUHnU4LV3QVTLJnU-uidaAxRVQbS1pVql5xR6nYZHYvFk1IU-wTY6gGk5WvGWWQ440UTTaMAfnJP6VFDggUXeGSlKfKkDcz7JLT2Ma2KXQ",
|
||||
"e": "AQAB",
|
||||
"d": "DYJcHuPmh-UYEUT7oY5DRE3P7jQ0qALZyLGWMHji0c0DLl4x4D0chfrR7il33zisH6G1LPrGl1FCNlA-3yXU-5GPkRADVQWqRFZxx5Du-k7X1tAW_iUt9PaYGjNm0hasEsMDYDbBQGZ5TD8cGp8wEHEVRbvTaB4VQb8zfXrr8ad8XCFdtYQF5Sw_VuvUBcn-50kdl7S0MmQiwLx5xkisJHkVdVsrWbq-JJPMYrjYzPGo07kt8pQH2ecxrQD2waTzkLiAg-nytPBkAyMIFQ-XCulWCNiI-V_HJ0pqNctgVpdaSihlPCYhfllxUSU8yg4UvcfFEAN2S5yjvPyrJeJLAQ",
|
||||
"p": "4db4J-vxAyb_3otKidzYISIo8NuPxPXuYeImbvVbY6CWHdAYAkPgbwADh592D1vM6kwqZLot4VQ4XUVtX7Vf8tCaq5BAzcVAslK0rhK86kSmzuvtpS1ruzm1DGwJcQWOl_9qYnaAov8Ny0NG8fTm8iwvWJH7rVa3XNtPL0t_fx0",
|
||||
"q": "8H7_sX4kY3_4t90HbA8IvVkTf3-OGaIjtcDn2J3HLq1wMKAtdxwsbMtjhLYP70PPBe_FBNpcWhE7p-tOVhH1i0N0wwFqwlRQy-3Z4oiLeSsy0Npl29cfP7teO5UTrbrqfmHB0j2u_nEqA4n4iDF5QhPr_9yzxSR4Pg56z4PgFEE"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_2 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "7988e9dea9647281b04d094e4dc5737eaf739a412a570aa4d6deed7ee5640c30",
|
||||
"n": "wWOFgHHiJ54ZjQEKxvfqYDuhYymbfvYxvreroqx7E-cAuU4QBsOvKV3HNnH_vDRQE1AlqihNWmPFLptp7wxdMrLEtDnRFqTxyTXJ7wLCaaaB6Wwx1dhpr9QEG5-8rxLGFYv2w5i0-o76JPHG0tuqf0YNmHp9oWcv524XnDBuji4-u6km1KynT1EQKHYgy57JWgUpukgJGImBEvf0hC2Y5s5mHvVby3xAD9-cFa2o9Vj3G-SBYFsrRIVR8GcVNwo88oj8F7-2nGD_wOOu_qT_5I3vfToUYGj5-2rAK1ja0bZpXFibrkPrW4w9paG-3F7I0sPeL3e_BDC_rQ8TgL03uQ",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_2_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "7988e9dea9647281b04d094e4dc5737eaf739a412a570aa4d6deed7ee5640c30",
|
||||
"n": "wWOFgHHiJ54ZjQEKxvfqYDuhYymbfvYxvreroqx7E-cAuU4QBsOvKV3HNnH_vDRQE1AlqihNWmPFLptp7wxdMrLEtDnRFqTxyTXJ7wLCaaaB6Wwx1dhpr9QEG5-8rxLGFYv2w5i0-o76JPHG0tuqf0YNmHp9oWcv524XnDBuji4-u6km1KynT1EQKHYgy57JWgUpukgJGImBEvf0hC2Y5s5mHvVby3xAD9-cFa2o9Vj3G-SBYFsrRIVR8GcVNwo88oj8F7-2nGD_wOOu_qT_5I3vfToUYGj5-2rAK1ja0bZpXFibrkPrW4w9paG-3F7I0sPeL3e_BDC_rQ8TgL03uQ",
|
||||
"e": "AQAB",
|
||||
"d": "RPC4j-CJUbw_uY-Miv-oMuQvFU2o3Crh8u5BJn28ZozsKiMU_YRW9jUzJkqfczVm8muY8b7qTHXSvlmy-v_6XW9zRhhyXFMyypr9QNJIAifUmiTy4xwCGSdIy5w3RGY57UZ3EqVmpwe_TtpOGa8rabHMePX5wUcqwaLykcCGOPLOFKfPF93GqZYi2StS1IaiijLi2IAMhxQGqS6Ct3dA7yacQwegPiDzjb4Is3V9UQ9k_aS3I1w56tz5qspVmfDEuuWToc-2Qyk-eMKWl1tTDJuGTCiS5IFtMPerRpPq9GCpycV0csIW-6AnW79b038DxWjDAUsNnDPnX0y1dQ1G3Q",
|
||||
"p": "yh2KH_JqU29L2SLG5-ul1EBbaSbt3F5UUZbCvm_MIsiH1TzafVyBd8FeG1d-pMR8bgGjaDSA-DNkOEDAeAlLx-UCTl2Uk2ySoMnZr5JjVLW2DTuF7e8ySKrKQSSLe63aQyKuIZh9P1RNrwrmFwvJgXdzudVjirmdTwxAN0lijE8",
|
||||
"q": "9PJitAE_kk6SoKvJisXbDb7Xursj26xiYIdWuzlzQ1CbwYcJ1oORDpo0bEpy0BfIbZDiJJ79Xrh5Lo1BVysQ-IZJCXK7mavqiSa8g3B8rmqLXmAtjDbwLGsJOayCpYnsGgOLT7XIUYXCFH7C-tSSydhJ1j8JAbsJveMiBPKnUXc"
|
||||
}`)
|
||||
|
||||
testKeyRSA_2048_3 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d214aea9b78d15dd2667f5d19c36df6647fa50023140fd4f5866d285718b897c",
|
||||
"n": "qFnqWpBOZ_5jnIr_XkXnonmHII5gKzxPhUBfvWBhGN2eH8nmnGh6aUnKyKuCLP_qfYLU7cf9bah-e00451iGite8Tg9ZMYAPFX4NM5j0rGWNv9Z6lSn1xXezJv-FU9VUwXm0DG5eVcB8OV99JWxHivQUSBzY0Q3DUlgrD7FhMd7BrrcmTUO07KnW6SxN3oTbT7fNMxfJSTRxmvU-t-6sLhYP4Wbg39zEUgI8M7b7tvHp34klSqOn2DibVBhvWGF1-IgNT7ng6pS5iAZN7Cz7NjPc9ZM_IWyngPKZV49Tf-ikX2O8uiCb4ccgRur6znwkE7MPrDTXSMHALn10sUcO_w",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_2048_3_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d214aea9b78d15dd2667f5d19c36df6647fa50023140fd4f5866d285718b897c",
|
||||
"n": "qFnqWpBOZ_5jnIr_XkXnonmHII5gKzxPhUBfvWBhGN2eH8nmnGh6aUnKyKuCLP_qfYLU7cf9bah-e00451iGite8Tg9ZMYAPFX4NM5j0rGWNv9Z6lSn1xXezJv-FU9VUwXm0DG5eVcB8OV99JWxHivQUSBzY0Q3DUlgrD7FhMd7BrrcmTUO07KnW6SxN3oTbT7fNMxfJSTRxmvU-t-6sLhYP4Wbg39zEUgI8M7b7tvHp34klSqOn2DibVBhvWGF1-IgNT7ng6pS5iAZN7Cz7NjPc9ZM_IWyngPKZV49Tf-ikX2O8uiCb4ccgRur6znwkE7MPrDTXSMHALn10sUcO_w",
|
||||
"e": "AQAB",
|
||||
"d": "cCIT2uarktD6gFaE6cIeGzZfLuwmWiX9wX-zRWxgwDM9E2dj12IvxtmD3E2Ak4CSK69tLEQ9JUFJnc89y7pHQ0uW_VdzzWjCo0omeOu0bO_njpPJanlcXn7wMVWY9NHvdj8eEfmhk_R1ybE0piyNKpyQtcehEv3bz4kyhW1ck936zafn5GWxCEWKIF-7OcotxtOl6z1GrJ7WqglMk8ooLucnAXzaPtcvD6seUhVH0vG60yI2AEInI_jMHR-mfDxrebG2xPPJLsqH3GChqTsxG5vjuaq71sNBiY_TbaUDbmWZxV66zdjhN93Rw-lc3vCPwG5vmuA2igWH7SKsHmQOAQ",
|
||||
"p": "xvTQi8nCJGyZQm3fr7HU23FkSUYkKFUN1FRDWqjyz7kFj5rJxq5dSsNrrgVBvIBNY4TwDDcYia4rvx7KSRRwfV_rsU2-TCOxBebqVlbeV0HI7xMcVZXsv61Eugz-dznUU4wqmP_rCQ8vyNcVvCBbBLBW92n-IRQXsfuSUfuHnT8",
|
||||
"q": "2J64YbgvH62PB4h-0iYuaykgUzWVSrXENg3_GaF8877AMTe98gjcH7HzTDW1fOhIcNZtmYTwlA2SgFudLsIJLoOn0-kmHzZjZJTWcsZsfTVwKhHD8Lzic7QkrrlbTIZlVu4mfT2f0kvaQiZp6zDCke3SLvVjlD-ebqTFCDIlXkE"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_0 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4941c1e95df518587e54ddde3510c084fedf92098473537fb3fe022eaece9b42",
|
||||
"n": "ypJYaH9_PLdEgGN3WFPL1V9qhC2BRXr24f1kGocaQe7wORFlZGX6gRpOCQ1lLmziLafERoSqZuBWF4vSGLeanCRQ7UKObYalMRR_rTJk6D_VD95LNOmtR4DrucdZvjQrAuLXhM5dNLGVoSq_zQowLDMeLWDUBB_TK4WlofoxI0RVoUOt4UXnSev8M_6yIYASpOAk8gG4FAqRfmU-3JhgkZOQCD0BhKYZVw_kEhRBrS3aik-1pQkan9hYIxWwc4KKtrLHNls7--vk5xDk2Vod5sZYRLlimbqHavN2IBeAeJGJqt1grXOVlnagKqmyq2MoPKufwptJBiVrVsTplyUB9FZe9FxUfxrkkxYJHufwP-3wXhaXpPFdL86TCUuOz-jTfng1rsTpwzmwm3RqFzz01yMc1RhaeWininQqj42bhW4bgFGVRP2QqSFbCbRZ4WMW3qWr3aR2QpJ7b8ac7JUhAJoh7-UtMmyGx9UJP0gjA8Wm-O81UENoDjMMdNUaVTfpSUKB7xZppg244jNZDIm1ptq4QyvvWkr0brp9Ymxpu0e3g2HyywyPjbeyNrIelb4E2tU5vCR4Fs_zGFG71AieruJGfzPTXE7ZaiLhP8n1652NCzIH76Y7OGz4ap2D55-RKpUkSI3KqWxUKxkM0tuZ7LS2F-1wEVs8P01K6RuQpxE",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_0_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "4941c1e95df518587e54ddde3510c084fedf92098473537fb3fe022eaece9b42",
|
||||
"n": "ypJYaH9_PLdEgGN3WFPL1V9qhC2BRXr24f1kGocaQe7wORFlZGX6gRpOCQ1lLmziLafERoSqZuBWF4vSGLeanCRQ7UKObYalMRR_rTJk6D_VD95LNOmtR4DrucdZvjQrAuLXhM5dNLGVoSq_zQowLDMeLWDUBB_TK4WlofoxI0RVoUOt4UXnSev8M_6yIYASpOAk8gG4FAqRfmU-3JhgkZOQCD0BhKYZVw_kEhRBrS3aik-1pQkan9hYIxWwc4KKtrLHNls7--vk5xDk2Vod5sZYRLlimbqHavN2IBeAeJGJqt1grXOVlnagKqmyq2MoPKufwptJBiVrVsTplyUB9FZe9FxUfxrkkxYJHufwP-3wXhaXpPFdL86TCUuOz-jTfng1rsTpwzmwm3RqFzz01yMc1RhaeWininQqj42bhW4bgFGVRP2QqSFbCbRZ4WMW3qWr3aR2QpJ7b8ac7JUhAJoh7-UtMmyGx9UJP0gjA8Wm-O81UENoDjMMdNUaVTfpSUKB7xZppg244jNZDIm1ptq4QyvvWkr0brp9Ymxpu0e3g2HyywyPjbeyNrIelb4E2tU5vCR4Fs_zGFG71AieruJGfzPTXE7ZaiLhP8n1652NCzIH76Y7OGz4ap2D55-RKpUkSI3KqWxUKxkM0tuZ7LS2F-1wEVs8P01K6RuQpxE",
|
||||
"e": "AQAB",
|
||||
"d": "VQagPRxm16FFC260hUqG4ASwvNIs1HEMd0bYYZobl1knU4zNthpnzxCveHU65wWk2ez1IXRF4fB_slpp0R4fszI7FZs-FRLS-4rTHGtul11TnNl9T7RVmxGt38ihDojvFMMKGyBTVu7DE2bSIsoH9kVugTWHSEPjav0pzJcrUNY56vpxXYDt18VJkrlxI0aSjMnYOAwoq6DT-O2eORFsVy5M4mhY3sipEjYFUOFXv8zjUfKrF55-omE4fWF5MsK0XoMjwtkAkHkvFx2sMN72dgsCubXmgQgeFvIhvs6eifzsf99z2NoPC5y3FbEs4Ws5VF3lLNXpDL9gEoeMVHigHKNoztIzbJnFLjzEag4wOBqbig4nWIlYEcLwd5-E0oQ8GHAhWtJn5AJQKOwTcasRWiUnRAulCcI8f9R2ATTSjAGU-juFUfhProp4w3ZlnUbO6U3tbh90KdFSJa-Bapts6ijPgEp6MHubVCHIxh1KGmod_CuGGjze1GuISEwI_4Yh0SrFlp4Wy6ecg7mKNnXvkBMd6h90LJaTzubnts33cCs-5UzCtYqmWHwXrMA6dRJuicY6su3NXxStuZn2bxU_Dn8LrS1vx_lhDU__NqMNbYj5ZvHkPvZiJNBI6Z1R5SY3pQzpH6vh9W2KRKF8cKOkushIaHNnHo7W5o4eZ9HjJFE",
|
||||
"p": "7Bxd2wTrXfeSZAEGZEnfoJaMh6hKFG-fx0wLmF9U-Myq1fCIQ-gdl_Atqy0xQxYtQl2lOPUWfySegJSxpdRF8pwvLq9Yt7xFQDrV0B8d5-FjYJ_Mk2bbyHv_PhNmnfcYHqE_VdADeSaU-MRV1iknvjdbxSxYUF-U2C6llfJhn-ZbGPmZJyz8fTWHSh8aKLPJkuYV84wcNL04hpFPJq7Bhy7HAFhRYNpxXyDO3I36DCU94uvUCY758VKLl8IYMMSqjh-thluKJSkWibo85ZOJR38XFksMr70pH-DkT0WMv3PpLtNu6ac6Ry4CEkZexSWmbVk-pduRooo0On1CMsrsLw",
|
||||
"q": "26K4gFJ0Ygqr4KaJ4QcRGN29XcjDpX5XTlHy3hCs_wEWc5wedydVgIH4tadiZcu0WinTtl0I6FYewWNpI8nFh8XJXsLOLepdKKR798zW8kEhzxdYdP1MTtGfy12KUCMeS2RQRsBJlmNdgrI0_m0JvW2LlGeK0EqvrqeS06L8bKGXkfY2aFGHl6ipSfUd5OpuSUqgfrj4-HgB8zywm-yAvn7UK-ySyQrP3K4PuOiY5QZmcPDxl8yqDAjorStrjPieYrlMqREHMsyq2FtAXhx4FzpKN7OljbE3EpgyFKkFN-wDTWRGxu3au0hQJx0-XthZ9i5r8zGcEbArQ5jZH7CQvw"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_1 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d01929d205e83facdc5080a0a4ade80853978298a5c73780e863c035d32127c9",
|
||||
"n": "ve_rSTi1vwfV2Oj7YNu1kv8Xz2ImAEqf7qo2RehTYW4FJpbj0wkMBVGmAulm4dz-1knnaPdpbrrIwkEYr1XR6kSIeB8aXkCZqDGZATxLSRqGEzu2J8Xt9z_qTQLWYD-NuMEf9H3B1CiP3Q2RnoWUlGvOr_KI5h6anzeqgZxlQLgqQujXscwqWpX7MVh3sheZ5SbyTkDcFWvQS_NEPaBGso-Au9X-yhZsHU1Ky02Nd_DPOrrRzl7uymE07hy3bIbxmrh4ZeEz6P2ixsHHYbd15GNMRlr1cWbg91RBB-akSxX0VYoLjjuqwo33UHk1hBbSATbobfpOKRruuZPZ_xOiPi-m0tUdD1Pj-h6xRcA5sZ1d55IdL8IY_9kgLc_WyU2RWFTXV6zA2SDDdE6EdEB_8q6U0oLU5T-YRxd-V2qOTqW1388qUaL5BalSvqM0g8kVfBYIM3uwLqQI_hCer4CL7_0DGlUtheye3qcoyqWVJd9iqfcWC-1S8NljAJwM9sehx6kOSM85UuUTH89VM35oAVp0rSPcLy20dPzEVQ0LAcy_iRHTkqy9nZ1z6mo-IWQE2ZyPCuESEfG7nFJ3YlUfwBJ5uZnk0N1FVYX5zgEKdkP322vShrv1blB_JtUedpbCcuS-qCaywpwjL0pzTDKpJMEqHds0-DFT7AbULcujw_U",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_1_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "d01929d205e83facdc5080a0a4ade80853978298a5c73780e863c035d32127c9",
|
||||
"n": "ve_rSTi1vwfV2Oj7YNu1kv8Xz2ImAEqf7qo2RehTYW4FJpbj0wkMBVGmAulm4dz-1knnaPdpbrrIwkEYr1XR6kSIeB8aXkCZqDGZATxLSRqGEzu2J8Xt9z_qTQLWYD-NuMEf9H3B1CiP3Q2RnoWUlGvOr_KI5h6anzeqgZxlQLgqQujXscwqWpX7MVh3sheZ5SbyTkDcFWvQS_NEPaBGso-Au9X-yhZsHU1Ky02Nd_DPOrrRzl7uymE07hy3bIbxmrh4ZeEz6P2ixsHHYbd15GNMRlr1cWbg91RBB-akSxX0VYoLjjuqwo33UHk1hBbSATbobfpOKRruuZPZ_xOiPi-m0tUdD1Pj-h6xRcA5sZ1d55IdL8IY_9kgLc_WyU2RWFTXV6zA2SDDdE6EdEB_8q6U0oLU5T-YRxd-V2qOTqW1388qUaL5BalSvqM0g8kVfBYIM3uwLqQI_hCer4CL7_0DGlUtheye3qcoyqWVJd9iqfcWC-1S8NljAJwM9sehx6kOSM85UuUTH89VM35oAVp0rSPcLy20dPzEVQ0LAcy_iRHTkqy9nZ1z6mo-IWQE2ZyPCuESEfG7nFJ3YlUfwBJ5uZnk0N1FVYX5zgEKdkP322vShrv1blB_JtUedpbCcuS-qCaywpwjL0pzTDKpJMEqHds0-DFT7AbULcujw_U",
|
||||
"e": "AQAB",
|
||||
"d": "mCjZ3wDVaMJIKMsMhx28KpS9aGACfX1K_pHRhNOH6KeQ7Mc4oFnBDYnJas-8ofi_FsCB6G88QX7VUfmAYwZncjuQ8FpKb3NlJX8GSh0ZWukqu8G8PcSszMShWSyKvPRs_rOIe_87BlGwXrB-FfaBfx2WqRGtZlziFecsa0T1QJHJGW0bTs52p7c7Ut7ClSOfIBrBRrtjFK4YYp_x7US3HlkkElZvFUo9NoQzBQeN66Y4_Z2ocqFOv0Z8drz-nKzGZOKfYU62nVKD0qJurfOhOGPsOPipZD28v6b5qfC1cYmXAefjNgDK3a2JkShpHPaDKoHoViKN9xQiZvzxSQ1bjQCgB6xQWk61YwmiB44gFLshXvXkx_wcccO2XC4m-Pk0r-Uj9Ugvgizk8HYp1H9eqnp8A6sqU44mrmdt14vM68SGzEqYpLoUkcxPttHvNoORAzgQfuK3SOIFyuwFqKTMBupR4A42XvxLj_PuKEKFekS2JEK8fON2t_LuUDVemjMxwXD0gjljHSKD9HnguihI5IEd6Kgr-HlTwiiDQfzcmWQdoFUs_Je4tVCSbGRrJYju01gLouDu7gzN14pZcEyoBLPkj-_MDiiymvlBLOBU2s5nQRZCaC_0IKgHLaT_rzQaXwmVhU-OURdwdoViMVc_cdXtle4TqU1g41nNE_0tiwE",
|
||||
"p": "2h_9HZCOpf3S9qpAkNS2ncMsRjBlWCpRltoCs-XBF_IgOJlCkJ-42k_V1zaf6YrgMy00XD4Ij5MMiUOharvc3w_WKJF-AwGu9JEpi38Wzj1nkY86sdB1ZPu4ihSRZm81jIjuLZ2siILqkupXaY0S_0CeNLKPoVpvfPWCb3psCWuLVRDhYECPCx9FYg2tzisbFpVAPPqNCFswMYNvhyJ2NQ0hzueKDc1uHBUanCSG6gIbeY1bQvYYFGySYkWZcQg98RSeDbLysHalCSQCgPjss3likTT9OjWLv23vpXURFhgywv6Phx4He0yWB8ZRrnskfW0S76kZ325SPUlnOhf31Q",
|
||||
"q": "3urwELOa7TDpwLMeMEOf2aspz1gkMjoN-V4SMzRGxIoPy93-bQ62Z8nPduma1gK0zHOIs0gU8dDqjy8P8Z7vudJqRFJIrzjD-RnDqQDz7KM_6x0kbEN4GLQiNGVAckRhoEmYjDXXkG3teD2ST5NqlYwxGvFmCvw5RCJZG7eNjXY3KnJQrDyx61NIFEvSm3sBlJkOVhSanuqHBL6T-efaBkUcQ7mY7_iYtCt7cjMG8qQtF0KovVsMF6BUc9KDobpUvDsvPrSTAzsYJvVNkzGJtF8Strr-61VA6qZnRcDW3ukYvmJp_SdAcv3KzSkWwEmJEaAtaiOh2jWkRG9QpV_LoQ"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_2 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "822512e8098b9fa56c9152a56d2607bda912c89f6f4fe1b6ccf41627bf06de29",
|
||||
"n": "3bcg0diA0TPvK283P02o5UT8cBf5q48uUsfuCkIbLqNFtskGuoft8OJLmik7c7pLNSK3Jad_-xRlfsrcV1fDBs8EJDFnoY-4r_xk_-GQl-OsHzuz7HMvjVYUSYeVZMtzPAfCIFJxSIaiIW9MEwCwYyrtRefedfKUV7Ax6hjOUXtyRZ5DRHj2FnNl6MjE8mTSJ8OQI9ETErg0wF448fJb6hYCidVHfeBSCOceljXMg8a9iDYHVnzsUb9ETl7xlRZDvUpIoG0jU-aC3oZdM0YgXspvw4FcXg1-ad-TbgRjEm_iJ-4KUhAYso6-Y6eimDT_TMhbKBLGE86pUjRPIXVNl6odjkXmcmh7bz9v0-gIfHB9zVbrqE8i8iIwkux-Uhq_VMiIFikjtjmDo5W-7qA_cjvq1dA1QqOJ54ijbdvglUtneuA5CnwfGHAvf94lEPebgP5eCMZjz_Dtl0FTX0u5lOVBs4qeyEfV1XANOq_h1gHmwJDlspGZVuPfSk4-YMCeBy5Ua_gNDqOIQo3EQbmjyN5yD9byFh3WDSQJN1kKT3BZSou-Q8-KT2lu9KT_CpTfVMaNXnPpXJ_H0S9Q7sbUzA6dF1h0Q_mu_bOlWTRlH3vXfZ3_3Vikjk-jhQdaRv8yjTdhX33wAVHk7omKlo76G3QJdnvjysJ6aagFPZ3qhmc",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_2_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "822512e8098b9fa56c9152a56d2607bda912c89f6f4fe1b6ccf41627bf06de29",
|
||||
"n": "3bcg0diA0TPvK283P02o5UT8cBf5q48uUsfuCkIbLqNFtskGuoft8OJLmik7c7pLNSK3Jad_-xRlfsrcV1fDBs8EJDFnoY-4r_xk_-GQl-OsHzuz7HMvjVYUSYeVZMtzPAfCIFJxSIaiIW9MEwCwYyrtRefedfKUV7Ax6hjOUXtyRZ5DRHj2FnNl6MjE8mTSJ8OQI9ETErg0wF448fJb6hYCidVHfeBSCOceljXMg8a9iDYHVnzsUb9ETl7xlRZDvUpIoG0jU-aC3oZdM0YgXspvw4FcXg1-ad-TbgRjEm_iJ-4KUhAYso6-Y6eimDT_TMhbKBLGE86pUjRPIXVNl6odjkXmcmh7bz9v0-gIfHB9zVbrqE8i8iIwkux-Uhq_VMiIFikjtjmDo5W-7qA_cjvq1dA1QqOJ54ijbdvglUtneuA5CnwfGHAvf94lEPebgP5eCMZjz_Dtl0FTX0u5lOVBs4qeyEfV1XANOq_h1gHmwJDlspGZVuPfSk4-YMCeBy5Ua_gNDqOIQo3EQbmjyN5yD9byFh3WDSQJN1kKT3BZSou-Q8-KT2lu9KT_CpTfVMaNXnPpXJ_H0S9Q7sbUzA6dF1h0Q_mu_bOlWTRlH3vXfZ3_3Vikjk-jhQdaRv8yjTdhX33wAVHk7omKlo76G3QJdnvjysJ6aagFPZ3qhmc",
|
||||
"e": "AQAB",
|
||||
"d": "wcO4mAxJUAu-OsxgkR9SusPWhjQ9y5Q_XLNDso1hahng5ES9b6k55mouvlTIk3Q9I_vp6auAKrMBnJS3ilG1rK6hJOxUcBrFwm-m6QV9s3CSzV0E-mEULsYKxtQKWOOBGvaAznSeck7PRL8a0gSpIpGyeYSRo6zTverLRJZXQVjMXlFY4m-ASdCiQJWtoVVBYOUFhHfE3nhECdaOl8xCTcrcfw75AuZXa1ZpIcd0q7m1jGQDd6-HbE3m6UMKiEvD-ZsA68tVs45h0w3ER_pCcfUjRc45Ji1OzEJLezu0RbmoAVOEi4FrxCkB9N_dNn4inD0BhX0axNa4nZH_kfMNUh06081FaBiBq5bNBPQF7lWIYxAhtd2VgsUTZtNxMfHDTllt5fvbCogYngU5-Wj3UM33R_es_aakt_CFndJPmyenP0J7KEBmf4qnlrbxun-jQNV_cbEzgQA_Pt5RIhB5jgofYzT72Ib-lViZUolXpxg8mFQ5BPghqriuaX8eSc85y5rbu-nEvheDkIC7xjTtDBShXMvKKokx6t4d-x_W4sWDuLKsVNn3Veg6mbbl3O74Fr-joEM9unMg-9KCapAuBKmMv4GejOVOIj43i0lm8dsuMslNKsThWpjApE50-VBuySi1f0jD2HNEzjMTt5ZrlNi9bRFzAht46kdc_g4TWLE",
|
||||
"p": "7cl5QebQldiOrfe2Z7E2aP4d1GIuX4b3u-kXUDa73HI4S2u9TooJF8lfsbrtzJIG60iIzio9Pej8R4ss2_1TPC_F7gQS67ST5yY2zuwUH6jwpt8KtVO3NKd9SNfVJse_mZLp7eAeH8CMq4bqkDig8ZI_Sp1LQtWXvhvhju40i0h1ef-MD36wbc26BE1L6tQMAoJIU-pMDawmWMGG3Q5_LxKHb1cxvV8gVfFgsJbAHMPXxcmpCdp1FqeqpvRs3bch3AMxHwjy1SFRK6lhvliS2ZvD7fdupA09PGJ-cNO3S9iHdCvsnyOHg9pMbxxcYW8Io_t1ihk6JYFvZlDIYvukXw",
|
||||
"q": "7rKFf6190MlunvlLSdMvN_E2Xuow35_EThaxQ9e_7FS32LKPy847vFreXzVivVW1IVXrRSDgU8VIEyBQzftliLSriefKYdx2jtd_A84baha4p6CAK9SwfZcVEcIuU2Ul8XcUpbg53_bxUWDv4mYewZW_AqaZ0ZR1Ug14gCGHELvjs7MmWkCkJB6lEenRQZvzwcmA8tWzZ6Dlqb_RyLtxcVPbeSuc3t6YxbB1-pquwXoQLB9-XvgR_4L6vuGZrp1D-C0lzboUPoftkC_hKYb_xY6LPJTsL8LUypATcTrAnD0TBrqj5-Oy_4dMin6OcsXrfdxflxaJqkh7B-kz20oa-Q"
|
||||
}`)
|
||||
|
||||
testKeyRSA_4096_3 = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "ad60df152305985e6bdd8cb1d1f496f766aed097b7464b8b821a09b27f054dcb",
|
||||
"n": "q8mHub9-A7LH2ykklO52CRQ9KYeM9FlHaoLJCMokmwdb8FF8cAMOPDQ4lx7rB107vwX5oHS6T4uhOUH6ppgZnvB083-f5cBfvZPSwvKg1csOPI3Llp-hIO3vnu7v4M-dXRJevmNdTAoHINXP8mJ1KfGL6BuxckxLEOoIX0suSmyudAE_lc6ioMAfwehkH7qTWwllIuReGwxHHYapM0AFIYysJ0z96l-WNkO3ssLm6Q7txpumM_b0d58OkdezBLujEfn0t5H8hsml_LUSE4TfWcGwm3oDBB2q5tsI2_QmVwdV6BcP43Sm8R7EbJvTQq3YXKLlC-Et4-3CDGaMV6z1eFmHBs_FMGzto-kg9MUFockOe0vkfjHj6AafNw7AFyBJRvV3EdMM-O1ysiC5cs45aowbfQIz_9H9RVbR9iMiEjq6nM34bhgfu-FvOmAcliCOJnDlBy2wWe2XyXTLQVkmn1C_w2mitcQAkP-LiktypUwSIbyDqfBai1_imO1SIVzomRLvzSju5qGrcm0ROV6o9zKXCVc546g9la9FUTTPZsI0_s3hcVRVMaF3fa122hE848serjCqNJ0Nb3CYOlVCc6JrkUdeuCj0Y-on6V6aeCFAQxFb1z_p88STsNJkrcNZp87f1JUaSB4POF01dLNQ2HTe7xJCMRmK-fpNuDCOzNM",
|
||||
"e": "AQAB"
|
||||
}`)
|
||||
testKeyRSA_4096_3_Priv = mustLoadJWK(`{
|
||||
"kty": "RSA",
|
||||
"kid": "ad60df152305985e6bdd8cb1d1f496f766aed097b7464b8b821a09b27f054dcb",
|
||||
"n": "q8mHub9-A7LH2ykklO52CRQ9KYeM9FlHaoLJCMokmwdb8FF8cAMOPDQ4lx7rB107vwX5oHS6T4uhOUH6ppgZnvB083-f5cBfvZPSwvKg1csOPI3Llp-hIO3vnu7v4M-dXRJevmNdTAoHINXP8mJ1KfGL6BuxckxLEOoIX0suSmyudAE_lc6ioMAfwehkH7qTWwllIuReGwxHHYapM0AFIYysJ0z96l-WNkO3ssLm6Q7txpumM_b0d58OkdezBLujEfn0t5H8hsml_LUSE4TfWcGwm3oDBB2q5tsI2_QmVwdV6BcP43Sm8R7EbJvTQq3YXKLlC-Et4-3CDGaMV6z1eFmHBs_FMGzto-kg9MUFockOe0vkfjHj6AafNw7AFyBJRvV3EdMM-O1ysiC5cs45aowbfQIz_9H9RVbR9iMiEjq6nM34bhgfu-FvOmAcliCOJnDlBy2wWe2XyXTLQVkmn1C_w2mitcQAkP-LiktypUwSIbyDqfBai1_imO1SIVzomRLvzSju5qGrcm0ROV6o9zKXCVc546g9la9FUTTPZsI0_s3hcVRVMaF3fa122hE848serjCqNJ0Nb3CYOlVCc6JrkUdeuCj0Y-on6V6aeCFAQxFb1z_p88STsNJkrcNZp87f1JUaSB4POF01dLNQ2HTe7xJCMRmK-fpNuDCOzNM",
|
||||
"e": "AQAB",
|
||||
"d": "QFcw8I8aQYRaemlEfEt8BhaAeed9EZ_GscveQ96CK1ZsRuweMU3TrRTaBS_dU1rGH9u7DS_rABQKBIoDuRXKss7Y3sJ0Pvb4ZObSz5VUS_7LjD6HfBi5nr2_O8W-LnNUOyHAPoq0zOAMn221ftEFlPoVLpAAvBB7JRCiph5gbhuak3RMPm2wV4jd3CCQL5oPys8QBCuIW5UTpalkAf_-a_xmFiouB_RZLGXcjaWWGsAuqm5tp5TdJ1h5eoJRWHp2ryrxTzfsXwdzldyzsn_Xr6Rt4y2lp4r9EY4EGW2uVnY25MCOgOCWDkU5yHvselLmcHvKUdK6_11zinV2Jvhuz1FaW10P6lRXxhjuuT4bT7XmY6WkJCUvWf8w_NYrGwDbRvQa6YZcZZWKZ1l2Enkgd_P4qwtrnROQSCe0dJdNG3lSq90lrAwuvb8AhKhpQ8nJSaSQc_h2pa4NJZ-R__9m0_7CRUuEEg9k47AtgdIe09KLSpcACc3W5cBXEw2pL8ihqcf9AVgM0TFQQVrUdIst3YjUiB6r2zLVCRx8KjtT8Pmz6YtMQwDIFTrUopwwai5PEP3QEdxdNF39W1iwkqjA8uw4IlXgZAr4-9s3x617XUL0BQ4TgMpTsEghpV1U8U2HQfYGUKBcAlSqIlAi0MU4QRwcsAJrcoTIi-e34NFMbHE",
|
||||
"p": "xvZ1BKzaRfrmQT2mmbK1MzKdr4amHrx4EJ_4fRsCRBj8MqB92y4Bp0iuO8rZ3iK_yOOgQQTcr4UP5UEACLOqGDPNa92UUpHu1U5XR3MiIY0kGcdovpkkGU8fq78VRpyofc1b9kvZsy4eL0e7W7jApjGu479D_evnpT7lqSOGRl1Z0QHdI3ctKmKw48-AmQWL4BibXTyaXOfRgTHm4AtbrvFshwCZ43QgzrCrwbhZlOfiIIW9wXa_OqqOhV11BLF72qTglecfTgUOxY0W5GWgbwXCVZ8Lwr6cxYKGrKjmny9UNOIjABGsJjZm5egwDNUhhoaEeXXyzXbCKynvUCDxZw",
|
||||
"q": "3Qi1bRzj3TYW3Iw9KSDCuuHWBJRO_3Ke-JLB7PHEXc1hsPwF_XDqXPaBbIUtgKaqNzUehYAQbtHHhJVGqZadTKjsNkO4sO_r5nRoxUpFuGgUEmKNN0QeJa_llHzAZ9JpvUrtoyzVZX-2Em_3aAhtV5pZ6t22YToPDjZIBgqL96MQRCyKsv2FS_dbpoYKdXlG6phzkzKPn3oaWkh-VwmgAsFg7uXdiquQEsXYcOq3-77Umiuke6SBbaHLryLflTzOV7YvY7Kw3s3NycS9MDBESKYXqqX3YKvS25ZFFjYbrVOx5AluLiwajZu2biIPZb9rNbSXE77Hll3tAbmA5syJtQ"
|
||||
}`)
|
||||
)
|
||||
198
vendor/github.com/coreos/go-oidc/jwks.go
generated
vendored
198
vendor/github.com/coreos/go-oidc/jwks.go
generated
vendored
@@ -3,6 +3,7 @@ package oidc
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -38,147 +39,158 @@ type remoteKeySet struct {
|
||||
// guard all other fields
|
||||
mu sync.Mutex
|
||||
|
||||
// inflightCtx suppresses parallel execution of updateKeys and allows
|
||||
// inflight suppresses parallel execution of updateKeys and allows
|
||||
// multiple goroutines to wait for its result.
|
||||
// Its Err() method returns any errors encountered during updateKeys.
|
||||
//
|
||||
// If nil, there is no inflight updateKeys request.
|
||||
inflightCtx *inflight
|
||||
inflight *inflight
|
||||
|
||||
// A set of cached keys and their expiry.
|
||||
cachedKeys []jose.JSONWebKey
|
||||
expiry time.Time
|
||||
}
|
||||
|
||||
// inflight is used to wait on some in-flight request from multiple goroutines
|
||||
// inflight is used to wait on some in-flight request from multiple goroutines.
|
||||
type inflight struct {
|
||||
done chan struct{}
|
||||
doneCh chan struct{}
|
||||
|
||||
keys []jose.JSONWebKey
|
||||
err error
|
||||
}
|
||||
|
||||
// Done returns a channel that is closed when the inflight request finishes.
|
||||
func (i *inflight) Done() <-chan struct{} {
|
||||
return i.done
|
||||
func newInflight() *inflight {
|
||||
return &inflight{doneCh: make(chan struct{})}
|
||||
}
|
||||
|
||||
// Err returns any error encountered during request execution. May be nil.
|
||||
func (i *inflight) Err() error {
|
||||
return i.err
|
||||
// wait returns a channel that multiple goroutines can receive on. Once it returns
|
||||
// a value, the inflight request is done and result() can be inspected.
|
||||
func (i *inflight) wait() <-chan struct{} {
|
||||
return i.doneCh
|
||||
}
|
||||
|
||||
// Cancel signals completion of the inflight request with error err.
|
||||
// Must be called only once for particular inflight instance.
|
||||
func (i *inflight) Cancel(err error) {
|
||||
// done can only be called by a single goroutine. It records the result of the
|
||||
// inflight request and signals other goroutines that the result is safe to
|
||||
// inspect.
|
||||
func (i *inflight) done(keys []jose.JSONWebKey, err error) {
|
||||
i.keys = keys
|
||||
i.err = err
|
||||
close(i.done)
|
||||
close(i.doneCh)
|
||||
}
|
||||
|
||||
func (r *remoteKeySet) keysWithIDFromCache(keyIDs []string) ([]jose.JSONWebKey, bool) {
|
||||
r.mu.Lock()
|
||||
keys, expiry := r.cachedKeys, r.expiry
|
||||
r.mu.Unlock()
|
||||
// result cannot be called until the wait() channel has returned a value.
|
||||
func (i *inflight) result() ([]jose.JSONWebKey, error) {
|
||||
return i.keys, i.err
|
||||
}
|
||||
|
||||
// Have the keys expired?
|
||||
if expiry.Add(keysExpiryDelta).Before(r.now()) {
|
||||
return nil, false
|
||||
func (r *remoteKeySet) verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) {
|
||||
// We don't support JWTs signed with multiple signatures.
|
||||
keyID := ""
|
||||
for _, sig := range jws.Signatures {
|
||||
keyID = sig.Header.KeyID
|
||||
break
|
||||
}
|
||||
|
||||
var signingKeys []jose.JSONWebKey
|
||||
keys, expiry := r.keysFromCache()
|
||||
|
||||
// Don't check expiry yet. This optimizes for when the provider is unavailable.
|
||||
for _, key := range keys {
|
||||
if contains(keyIDs, key.KeyID) {
|
||||
signingKeys = append(signingKeys, key)
|
||||
if keyID == "" || key.KeyID == keyID {
|
||||
if payload, err := jws.Verify(&key); err == nil {
|
||||
return payload, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(signingKeys) == 0 {
|
||||
// Are the keys about to expire?
|
||||
if r.now().Add(keysExpiryDelta).After(expiry) {
|
||||
return nil, false
|
||||
}
|
||||
if !r.now().Add(keysExpiryDelta).After(expiry) {
|
||||
// Keys haven't expired, don't refresh.
|
||||
return nil, errors.New("failed to verify id token signature")
|
||||
}
|
||||
|
||||
return signingKeys, true
|
||||
keys, err := r.keysFromRemote(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetching keys %v", err)
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
if keyID == "" || key.KeyID == keyID {
|
||||
if payload, err := jws.Verify(&key); err == nil {
|
||||
return payload, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New("failed to verify id token signature")
|
||||
}
|
||||
func (r *remoteKeySet) keysWithID(ctx context.Context, keyIDs []string) ([]jose.JSONWebKey, error) {
|
||||
keys, ok := r.keysWithIDFromCache(keyIDs)
|
||||
if ok {
|
||||
return keys, nil
|
||||
|
||||
func (r *remoteKeySet) keysFromCache() (keys []jose.JSONWebKey, expiry time.Time) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
return r.cachedKeys, r.expiry
|
||||
}
|
||||
|
||||
// keysFromRemote syncs the key set from the remote set, records the values in the
|
||||
// cache, and returns the key set.
|
||||
func (r *remoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, error) {
|
||||
// Need to lock to inspect the inflight request field.
|
||||
r.mu.Lock()
|
||||
// If there's not a current inflight request, create one.
|
||||
if r.inflight == nil {
|
||||
r.inflight = newInflight()
|
||||
|
||||
// This goroutine has exclusive ownership over the current inflight
|
||||
// request. It releases the resource by nil'ing the inflight field
|
||||
// once the goroutine is done.
|
||||
go func() {
|
||||
// Sync keys and finish inflight when that's done.
|
||||
keys, expiry, err := r.updateKeys()
|
||||
|
||||
r.inflight.done(keys, err)
|
||||
|
||||
// Lock to update the keys and indicate that there is no longer an
|
||||
// inflight request.
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if err == nil {
|
||||
r.cachedKeys = keys
|
||||
r.expiry = expiry
|
||||
}
|
||||
|
||||
// Free inflight so a different request can run.
|
||||
r.inflight = nil
|
||||
}()
|
||||
}
|
||||
|
||||
var inflightCtx *inflight
|
||||
func() {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// If there's not a current inflight request, create one.
|
||||
if r.inflightCtx == nil {
|
||||
inflightCtx := &inflight{make(chan struct{}), nil}
|
||||
r.inflightCtx = inflightCtx
|
||||
|
||||
go func() {
|
||||
// TODO(ericchiang): Upstream Kubernetes request that we recover every time
|
||||
// we spawn a goroutine, because panics in a goroutine will bring down the
|
||||
// entire program. There's no way to recover from another goroutine's panic.
|
||||
//
|
||||
// Most users actually want to let the panic propagate and bring down the
|
||||
// program because it implies some unrecoverable state.
|
||||
//
|
||||
// Add a context key to allow the recover behavior.
|
||||
//
|
||||
// See: https://github.com/coreos/go-oidc/issues/89
|
||||
|
||||
// Sync keys and close inflightCtx when that's done.
|
||||
// Use the remoteKeySet's context instead of the requests context
|
||||
// because a re-sync is unique to the keys set and will span multiple
|
||||
// requests.
|
||||
inflightCtx.Cancel(r.updateKeys(r.ctx))
|
||||
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.inflightCtx = nil
|
||||
}()
|
||||
}
|
||||
|
||||
inflightCtx = r.inflightCtx
|
||||
}()
|
||||
inflight := r.inflight
|
||||
r.mu.Unlock()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-inflightCtx.Done():
|
||||
if err := inflightCtx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case <-inflight.wait():
|
||||
return inflight.result()
|
||||
}
|
||||
|
||||
// Since we've just updated keys, we don't care about the cache miss.
|
||||
keys, _ = r.keysWithIDFromCache(keyIDs)
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (r *remoteKeySet) updateKeys(ctx context.Context) error {
|
||||
func (r *remoteKeySet) updateKeys() ([]jose.JSONWebKey, time.Time, error) {
|
||||
req, err := http.NewRequest("GET", r.jwksURL, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oidc: can't create request: %v", err)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: can't create request: %v", err)
|
||||
}
|
||||
|
||||
resp, err := doRequest(ctx, req)
|
||||
resp, err := doRequest(r.ctx, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oidc: get keys failed %v", err)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: get keys failed %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oidc: read response body: %v", err)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: read response body: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("oidc: get keys failed: %s %s", resp.Status, body)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: get keys failed: %s %s", resp.Status, body)
|
||||
}
|
||||
|
||||
var keySet jose.JSONWebKeySet
|
||||
if err := json.Unmarshal(body, &keySet); err != nil {
|
||||
return fmt.Errorf("oidc: failed to decode keys: %v %s", err, body)
|
||||
return nil, time.Time{}, fmt.Errorf("oidc: failed to decode keys: %v %s", err, body)
|
||||
}
|
||||
|
||||
// If the server doesn't provide cache control headers, assume the
|
||||
@@ -189,11 +201,5 @@ func (r *remoteKeySet) updateKeys(ctx context.Context) error {
|
||||
if err == nil && e.After(expiry) {
|
||||
expiry = e
|
||||
}
|
||||
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.cachedKeys = keySet.Keys
|
||||
r.expiry = expiry
|
||||
|
||||
return nil
|
||||
return keySet.Keys, expiry, nil
|
||||
}
|
||||
|
||||
293
vendor/github.com/coreos/go-oidc/jwks_test.go
generated
vendored
293
vendor/github.com/coreos/go-oidc/jwks_test.go
generated
vendored
@@ -1,99 +1,250 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
type keyServer struct {
|
||||
keys jose.JSONWebKeySet
|
||||
keys jose.JSONWebKeySet
|
||||
setHeaders func(h http.Header)
|
||||
}
|
||||
|
||||
func newKeyServer(keys ...jose.JSONWebKey) keyServer {
|
||||
return keyServer{
|
||||
keys: jose.JSONWebKeySet{Keys: keys},
|
||||
func (k *keyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if k.setHeaders != nil {
|
||||
k.setHeaders(w.Header())
|
||||
}
|
||||
}
|
||||
|
||||
func (k keyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewEncoder(w).Encode(k.keys); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeysFormID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
keys []jose.JSONWebKey
|
||||
keyIDs []string
|
||||
wantKeys []jose.JSONWebKey
|
||||
}{
|
||||
{
|
||||
name: "single key",
|
||||
keys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
testKeyECDSA_256_0,
|
||||
},
|
||||
keyIDs: []string{
|
||||
testKeyRSA_2048_0.KeyID,
|
||||
},
|
||||
wantKeys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one key id matches",
|
||||
keys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
testKeyECDSA_256_0,
|
||||
},
|
||||
keyIDs: []string{
|
||||
testKeyRSA_2048_0.KeyID,
|
||||
testKeyRSA_2048_1.KeyID,
|
||||
},
|
||||
wantKeys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no valid keys",
|
||||
keys: []jose.JSONWebKey{
|
||||
testKeyRSA_2048_1,
|
||||
testKeyECDSA_256_0,
|
||||
},
|
||||
keyIDs: []string{
|
||||
testKeyRSA_2048_0.KeyID,
|
||||
},
|
||||
},
|
||||
type signingKey struct {
|
||||
keyID string // optional
|
||||
priv interface{}
|
||||
pub interface{}
|
||||
alg jose.SignatureAlgorithm
|
||||
}
|
||||
|
||||
// sign creates a JWS using the private key from the provided payload.
|
||||
func (s *signingKey) sign(t *testing.T, payload []byte) string {
|
||||
privKey := &jose.JSONWebKey{Key: s.priv, Algorithm: string(s.alg), KeyID: s.keyID}
|
||||
|
||||
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: s.alg, Key: privKey}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jws, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
now := func() time.Time { return t0 }
|
||||
data, err := jws.CompactSerialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
func() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
// jwk returns the public part of the signing key.
|
||||
func (s *signingKey) jwk() jose.JSONWebKey {
|
||||
return jose.JSONWebKey{Key: s.pub, Use: "sig", Algorithm: string(s.alg), KeyID: s.keyID}
|
||||
}
|
||||
|
||||
server := httptest.NewServer(newKeyServer(test.keys...))
|
||||
defer server.Close()
|
||||
func newRSAKey(t *testing.T) *signingKey {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 1028)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &signingKey{"", priv, priv.Public(), jose.RS256}
|
||||
}
|
||||
|
||||
keySet := newRemoteKeySet(ctx, server.URL, now)
|
||||
gotKeys, err := keySet.keysWithID(ctx, test.keyIDs)
|
||||
if err != nil {
|
||||
t.Errorf("%s: %v", test.name, err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotKeys, test.wantKeys) {
|
||||
t.Errorf("%s: expected keys=%#v, got=%#v", test.name, test.wantKeys, gotKeys)
|
||||
}
|
||||
}()
|
||||
func newECDSAKey(t *testing.T) *signingKey {
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &signingKey{"", priv, priv.Public(), jose.ES256}
|
||||
}
|
||||
|
||||
func TestRSAVerify(t *testing.T) {
|
||||
good := newRSAKey(t)
|
||||
bad := newRSAKey(t)
|
||||
|
||||
testKeyVerify(t, good, bad, good)
|
||||
}
|
||||
|
||||
func TestECDSAVerify(t *testing.T) {
|
||||
good := newECDSAKey(t)
|
||||
bad := newECDSAKey(t)
|
||||
testKeyVerify(t, good, bad, good)
|
||||
}
|
||||
|
||||
func TestMultipleKeysVerify(t *testing.T) {
|
||||
key1 := newRSAKey(t)
|
||||
key2 := newRSAKey(t)
|
||||
bad := newECDSAKey(t)
|
||||
|
||||
key1.keyID = "key1"
|
||||
key2.keyID = "key2"
|
||||
bad.keyID = "key3"
|
||||
|
||||
testKeyVerify(t, key2, bad, key1, key2)
|
||||
}
|
||||
|
||||
func TestMismatchedKeyID(t *testing.T) {
|
||||
key1 := newRSAKey(t)
|
||||
key2 := newRSAKey(t)
|
||||
|
||||
// shallow copy
|
||||
bad := new(signingKey)
|
||||
*bad = *key1
|
||||
|
||||
// The bad key is a valid key this time, but has a different Key ID.
|
||||
// It shouldn't match key1 because of the mismatched ID, even though
|
||||
// it would confirm the signature just fine.
|
||||
bad.keyID = "key3"
|
||||
|
||||
key1.keyID = "key1"
|
||||
key2.keyID = "key2"
|
||||
|
||||
testKeyVerify(t, key2, bad, key1, key2)
|
||||
}
|
||||
|
||||
func testKeyVerify(t *testing.T, good, bad *signingKey, verification ...*signingKey) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
keySet := jose.JSONWebKeySet{}
|
||||
for _, v := range verification {
|
||||
keySet.Keys = append(keySet.Keys, v.jwk())
|
||||
}
|
||||
|
||||
payload := []byte("a secret")
|
||||
|
||||
jws, err := jose.ParseSigned(good.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
badJWS, err := jose.ParseSigned(bad.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s := httptest.NewServer(&keyServer{keys: keySet})
|
||||
defer s.Close()
|
||||
|
||||
rks := newRemoteKeySet(ctx, s.URL, nil)
|
||||
|
||||
// Ensure the token verifies.
|
||||
gotPayload, err := rks.verify(ctx, jws)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(gotPayload, payload) {
|
||||
t.Errorf("expected payload %s got %s", payload, gotPayload)
|
||||
}
|
||||
|
||||
// Ensure the token verifies from the cache.
|
||||
gotPayload, err = rks.verify(ctx, jws)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(gotPayload, payload) {
|
||||
t.Errorf("expected payload %s got %s", payload, gotPayload)
|
||||
}
|
||||
|
||||
// Ensure item signed by wrong token doesn't verify.
|
||||
if _, err := rks.verify(context.Background(), badJWS); err == nil {
|
||||
t.Errorf("incorrectly verified signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheControl(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
key1 := newRSAKey(t)
|
||||
key2 := newRSAKey(t)
|
||||
|
||||
key1.keyID = "key1"
|
||||
key2.keyID = "key2"
|
||||
|
||||
payload := []byte("a secret")
|
||||
jws1, err := jose.ParseSigned(key1.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jws2, err := jose.ParseSigned(key2.sign(t, payload))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cacheForSeconds := 1200
|
||||
now := time.Now()
|
||||
|
||||
server := &keyServer{
|
||||
keys: jose.JSONWebKeySet{
|
||||
Keys: []jose.JSONWebKey{key1.jwk()},
|
||||
},
|
||||
setHeaders: func(h http.Header) {
|
||||
h.Set("Cache-Control", "max-age="+strconv.Itoa(cacheForSeconds))
|
||||
},
|
||||
}
|
||||
s := httptest.NewServer(server)
|
||||
defer s.Close()
|
||||
|
||||
rks := newRemoteKeySet(ctx, s.URL, func() time.Time { return now })
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err == nil {
|
||||
t.Errorf("incorrectly verified signature")
|
||||
}
|
||||
|
||||
// Add second key to public list.
|
||||
server.keys = jose.JSONWebKeySet{
|
||||
Keys: []jose.JSONWebKey{key1.jwk(), key2.jwk()},
|
||||
}
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err == nil {
|
||||
t.Errorf("incorrectly verified signature, still within cache limit")
|
||||
}
|
||||
|
||||
// Move time forward. Remote key set should not query the remote server.
|
||||
now = now.Add(time.Duration(cacheForSeconds) * time.Second)
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
|
||||
// Kill server and move time forward again. Keys should still verify.
|
||||
s.Close()
|
||||
now = now.Add(time.Duration(cacheForSeconds) * time.Second)
|
||||
|
||||
if _, err := rks.verify(ctx, jws1); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
if _, err := rks.verify(ctx, jws2); err != nil {
|
||||
t.Errorf("failed to verify valid signature: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
14
vendor/github.com/coreos/go-oidc/oidc.go
generated
vendored
14
vendor/github.com/coreos/go-oidc/oidc.go
generated
vendored
@@ -232,7 +232,8 @@ type IDToken struct {
|
||||
|
||||
// Initial nonce provided during the authentication redirect.
|
||||
//
|
||||
// If present, this package ensures this is a valid nonce.
|
||||
// This package does NOT provided verification on the value of this field
|
||||
// and it's the user's responsibility to ensure it contains a valid value.
|
||||
Nonce string
|
||||
|
||||
// Raw payload of the id_token.
|
||||
@@ -285,13 +286,6 @@ func (a *audience) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a audience) MarshalJSON() ([]byte, error) {
|
||||
if len(a) == 1 {
|
||||
return json.Marshal(a[0])
|
||||
}
|
||||
return json.Marshal([]string(a))
|
||||
}
|
||||
|
||||
type jsonTime time.Time
|
||||
|
||||
func (j *jsonTime) UnmarshalJSON(b []byte) error {
|
||||
@@ -313,7 +307,3 @@ func (j *jsonTime) UnmarshalJSON(b []byte) error {
|
||||
*j = jsonTime(time.Unix(unix, 0))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j jsonTime) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(time.Time(j).Unix())
|
||||
}
|
||||
|
||||
1
vendor/github.com/coreos/go-oidc/test
generated
vendored
1
vendor/github.com/coreos/go-oidc/test
generated
vendored
@@ -13,3 +13,4 @@ go test -v -i -race github.com/coreos/go-oidc/...
|
||||
go test -v -race github.com/coreos/go-oidc/...
|
||||
golint $LINTABLE
|
||||
go vet github.com/coreos/go-oidc/...
|
||||
go build -v ./example/...
|
||||
|
||||
74
vendor/github.com/coreos/go-oidc/verify.go
generated
vendored
74
vendor/github.com/coreos/go-oidc/verify.go
generated
vendored
@@ -19,9 +19,15 @@ const (
|
||||
issuerGoogleAccountsNoScheme = "accounts.google.com"
|
||||
)
|
||||
|
||||
// keySet is an interface that lets us stub out verification policies for
|
||||
// testing. Outside of testing, it's always backed by a remoteKeySet.
|
||||
type keySet interface {
|
||||
verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error)
|
||||
}
|
||||
|
||||
// IDTokenVerifier provides verification for ID Tokens.
|
||||
type IDTokenVerifier struct {
|
||||
keySet *remoteKeySet
|
||||
keySet keySet
|
||||
config *Config
|
||||
issuer string
|
||||
}
|
||||
@@ -34,12 +40,6 @@ type Config struct {
|
||||
//
|
||||
// If not provided, users must explicitly set SkipClientIDCheck.
|
||||
ClientID string
|
||||
// Method to verify the ID Token nonce. If a nonce is present and this method
|
||||
// is nil, users must explicitly set SkipNonceCheck.
|
||||
//
|
||||
// If the ID Token nonce is empty, for example if the client didn't provide a nonce in
|
||||
// the initial redirect, this may be nil.
|
||||
ClaimNonce func(nonce string) error
|
||||
// If specified, only this set of algorithms may be used to sign the JWT.
|
||||
//
|
||||
// Since many providers only support RS256, SupportedSigningAlgs defaults to this value.
|
||||
@@ -49,8 +49,6 @@ type Config struct {
|
||||
SkipClientIDCheck bool
|
||||
// If true, token expiry is not checked.
|
||||
SkipExpiryCheck bool
|
||||
// If true, nonce claim is not checked. Must be true if ClaimNonce field is empty.
|
||||
SkipNonceCheck bool
|
||||
|
||||
// Time function to check Token expiry. Defaults to time.Now
|
||||
Now func() time.Time
|
||||
@@ -65,7 +63,7 @@ func (p *Provider) Verifier(config *Config) *IDTokenVerifier {
|
||||
return newVerifier(p.remoteKeySet, config, p.issuer)
|
||||
}
|
||||
|
||||
func newVerifier(keySet *remoteKeySet, config *Config, issuer string) *IDTokenVerifier {
|
||||
func newVerifier(keySet keySet, config *Config, issuer string) *IDTokenVerifier {
|
||||
// If SupportedSigningAlgs is empty defaults to only support RS256.
|
||||
if len(config.SupportedSigningAlgs) == 0 {
|
||||
config.SupportedSigningAlgs = []string{RS256}
|
||||
@@ -102,6 +100,8 @@ func contains(sli []string, ele string) bool {
|
||||
// Verify parses a raw ID Token, verifies it's been signed by the provider, preforms
|
||||
// any additional checks depending on the Config, and returns the payload.
|
||||
//
|
||||
// Verify does NOT do nonce validation, which is the callers responsibility.
|
||||
//
|
||||
// See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
//
|
||||
// oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
|
||||
@@ -181,37 +181,22 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
|
||||
}
|
||||
}
|
||||
|
||||
// If a set of required algorithms has been provided, ensure that the signatures use those.
|
||||
var keyIDs, gotAlgs []string
|
||||
for _, sig := range jws.Signatures {
|
||||
if len(v.config.SupportedSigningAlgs) == 0 || contains(v.config.SupportedSigningAlgs, sig.Header.Algorithm) {
|
||||
keyIDs = append(keyIDs, sig.Header.KeyID)
|
||||
} else {
|
||||
gotAlgs = append(gotAlgs, sig.Header.Algorithm)
|
||||
}
|
||||
}
|
||||
if len(keyIDs) == 0 {
|
||||
return nil, fmt.Errorf("oidc: no signatures use a supported algorithm, expected %q got %q", v.config.SupportedSigningAlgs, gotAlgs)
|
||||
switch len(jws.Signatures) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("oidc: id token not signed")
|
||||
case 1:
|
||||
default:
|
||||
return nil, fmt.Errorf("oidc: multiple signatures on id token not supported")
|
||||
}
|
||||
|
||||
// Get keys from the remote key set. This may trigger a re-sync.
|
||||
keys, err := v.keySet.keysWithID(ctx, keyIDs)
|
||||
sig := jws.Signatures[0]
|
||||
if len(v.config.SupportedSigningAlgs) != 0 && !contains(v.config.SupportedSigningAlgs, sig.Header.Algorithm) {
|
||||
return nil, fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", v.config.SupportedSigningAlgs, sig.Header.Algorithm)
|
||||
}
|
||||
|
||||
gotPayload, err := v.keySet.verify(ctx, jws)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: get keys for id token: %v", err)
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return nil, fmt.Errorf("oidc: no keys match signature ID(s) %q", keyIDs)
|
||||
}
|
||||
|
||||
// Try to use a key to validate the signature.
|
||||
var gotPayload []byte
|
||||
for _, key := range keys {
|
||||
if p, err := jws.Verify(&key); err == nil {
|
||||
gotPayload = p
|
||||
}
|
||||
}
|
||||
if len(gotPayload) == 0 {
|
||||
return nil, fmt.Errorf("oidc: failed to verify id token")
|
||||
return nil, fmt.Errorf("failed to verify signature: %v", err)
|
||||
}
|
||||
|
||||
// Ensure that the payload returned by the square actually matches the payload parsed earlier.
|
||||
@@ -219,19 +204,6 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
|
||||
return nil, errors.New("oidc: internal error, payload parsed did not match previous payload")
|
||||
}
|
||||
|
||||
// Check the nonce after we've verified the token. We don't want to allow unverified
|
||||
// payloads to trigger a nonce lookup.
|
||||
// If SkipNonceCheck is not set ClaimNonce cannot be Nil.
|
||||
if !v.config.SkipNonceCheck && t.Nonce != "" {
|
||||
if v.config.ClaimNonce != nil {
|
||||
if err := v.config.ClaimNonce(t.Nonce); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("oidc: Invalid configuration. ClaimNonce must be provided or SkipNonceCheck must be set.")
|
||||
}
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
||||
274
vendor/github.com/coreos/go-oidc/verify_test.go
generated
vendored
274
vendor/github.com/coreos/go-oidc/verify_test.go
generated
vendored
@@ -1,311 +1,229 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"context"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
jose "gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
type testVerifier struct {
|
||||
jwk jose.JSONWebKey
|
||||
}
|
||||
|
||||
func (t *testVerifier) verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) {
|
||||
return jws.Verify(&t.jwk)
|
||||
}
|
||||
|
||||
func TestVerify(t *testing.T) {
|
||||
tests := []verificationTest{
|
||||
{
|
||||
name: "good token",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "good token",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "invalid issuer",
|
||||
idToken: idToken{
|
||||
Issuer: "foo",
|
||||
},
|
||||
name: "invalid issuer",
|
||||
issuer: "https://bar",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "google accounts without scheme",
|
||||
issuer: "https://accounts.google.com",
|
||||
idToken: idToken{
|
||||
Issuer: "accounts.google.com",
|
||||
},
|
||||
name: "invalid sig",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
verificationKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "expired token",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Expiry: jsonTime(time.Now().Add(-time.Hour)),
|
||||
},
|
||||
name: "google accounts without scheme",
|
||||
issuer: "https://accounts.google.com",
|
||||
idToken: `{"iss":"accounts.google.com"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "expired token",
|
||||
idToken: `{"iss":"https://foo","exp":` + strconv.FormatInt(time.Now().Add(-time.Hour).Unix(), 10) + `}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
},
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid signature",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "unexpired token",
|
||||
idToken: `{"iss":"https://foo","exp":` + strconv.FormatInt(time.Now().Add(time.Hour).Unix(), 10) + `}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_1},
|
||||
wantErr: true,
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "expiry as float",
|
||||
idToken: `{"iss":"https://foo","exp":` +
|
||||
strconv.FormatFloat(float64(time.Now().Add(time.Hour).Unix()), 'E', -1, 64) +
|
||||
`}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test.run(t)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyAudience(t *testing.T) {
|
||||
tests := []verificationTest{
|
||||
{
|
||||
name: "good audience",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Audience: []string{"client1"},
|
||||
},
|
||||
name: "good audience",
|
||||
idToken: `{"iss":"https://foo","aud":"client1"}`,
|
||||
config: Config{
|
||||
ClientID: "client1",
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "mismatched audience",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Audience: []string{"client2"},
|
||||
},
|
||||
name: "mismatched audience",
|
||||
idToken: `{"iss":"https://foo","aud":"client2"}`,
|
||||
config: Config{
|
||||
ClientID: "client1",
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "multiple audiences, one matches",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
Audience: []string{"client2", "client1"},
|
||||
},
|
||||
name: "multiple audiences, one matches",
|
||||
idToken: `{"iss":"https://foo","aud":["client1","client2"]}`,
|
||||
config: Config{
|
||||
ClientID: "client1",
|
||||
SkipNonceCheck: true,
|
||||
ClientID: "client2",
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test.run(t)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifySigningAlg(t *testing.T) {
|
||||
tests := []verificationTest{
|
||||
{
|
||||
name: "default signing alg",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "default signing alg",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
signAlg: RS256, // By default we only support RS256.
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "bad signing alg",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "bad signing alg",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signKey: testKeyRSA_2048_0_Priv,
|
||||
signAlg: RS512,
|
||||
pubKeys: []jose.JSONWebKey{testKeyRSA_2048_0},
|
||||
signKey: newECDSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "ecdsa signing",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "ecdsa signing",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SupportedSigningAlgs: []string{ES384},
|
||||
SupportedSigningAlgs: []string{ES256},
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signAlg: ES384,
|
||||
signKey: testKeyECDSA_384_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyECDSA_384_0},
|
||||
signKey: newECDSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "one of many supported",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "one of many supported",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
SupportedSigningAlgs: []string{RS256, ES384},
|
||||
SupportedSigningAlgs: []string{RS256, ES256},
|
||||
},
|
||||
signAlg: ES384,
|
||||
signKey: testKeyECDSA_384_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyECDSA_384_0},
|
||||
signKey: newECDSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "not in requiredAlgs",
|
||||
idToken: idToken{
|
||||
Issuer: "https://foo",
|
||||
},
|
||||
name: "not in requiredAlgs",
|
||||
idToken: `{"iss":"https://foo"}`,
|
||||
config: Config{
|
||||
SupportedSigningAlgs: []string{RS256, ES512},
|
||||
SkipClientIDCheck: true,
|
||||
SkipNonceCheck: true,
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
signAlg: ES384,
|
||||
signKey: testKeyECDSA_384_0_Priv,
|
||||
pubKeys: []jose.JSONWebKey{testKeyECDSA_384_0},
|
||||
signKey: newECDSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test.run(t)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
type verificationTest struct {
|
||||
// Name of the subtest.
|
||||
name string
|
||||
|
||||
// if not provided defaults to "https://foo"
|
||||
// If not provided defaults to "https://foo"
|
||||
issuer string
|
||||
|
||||
// ID token claims and a signing key to create the JWT.
|
||||
idToken idToken
|
||||
signKey jose.JSONWebKey
|
||||
// If supplied use this signing algorithm. If not, guess
|
||||
// from the signingKey.
|
||||
signAlg string
|
||||
// JWT payload (just the claims).
|
||||
idToken string
|
||||
|
||||
// Key to sign the ID Token with.
|
||||
signKey *signingKey
|
||||
// If not provided defaults to signKey. Only useful when
|
||||
// testing invalid signatures.
|
||||
verificationKey *signingKey
|
||||
|
||||
config Config
|
||||
pubKeys []jose.JSONWebKey
|
||||
|
||||
wantErr bool
|
||||
}
|
||||
|
||||
func algForKey(t *testing.T, k jose.JSONWebKey) string {
|
||||
switch key := k.Key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return RS256
|
||||
case *ecdsa.PrivateKey:
|
||||
name := key.PublicKey.Params().Name
|
||||
switch name {
|
||||
case elliptic.P256().Params().Name:
|
||||
return ES256
|
||||
case elliptic.P384().Params().Name:
|
||||
return ES384
|
||||
case elliptic.P521().Params().Name:
|
||||
return ES512
|
||||
}
|
||||
t.Fatalf("unsupported ecdsa curve: %s", name)
|
||||
default:
|
||||
t.Fatalf("unsupported key type %T", key)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v verificationTest) run(t *testing.T) {
|
||||
payload, err := json.Marshal(v.idToken)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
signingAlg := v.signAlg
|
||||
if signingAlg == "" {
|
||||
signingAlg = algForKey(t, v.signKey)
|
||||
}
|
||||
|
||||
signer, err := jose.NewSigner(jose.SigningKey{
|
||||
Algorithm: jose.SignatureAlgorithm(signingAlg),
|
||||
Key: &v.signKey,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
jws, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
token, err := jws.CompactSerialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
now := func() time.Time { return t0 }
|
||||
token := v.signKey.sign(t, []byte(v.idToken))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
server := httptest.NewServer(newKeyServer(v.pubKeys...))
|
||||
defer server.Close()
|
||||
|
||||
issuer := "https://foo"
|
||||
if v.issuer != "" {
|
||||
issuer = v.issuer
|
||||
}
|
||||
verifier := newVerifier(newRemoteKeySet(ctx, server.URL, now), &v.config, issuer)
|
||||
var ks keySet
|
||||
if v.verificationKey == nil {
|
||||
ks = &testVerifier{v.signKey.jwk()}
|
||||
} else {
|
||||
ks = &testVerifier{v.verificationKey.jwk()}
|
||||
}
|
||||
verifier := newVerifier(ks, &v.config, issuer)
|
||||
|
||||
if _, err := verifier.Verify(ctx, token); err != nil {
|
||||
if !v.wantErr {
|
||||
|
||||
21
vendor/github.com/flynn/go-shlex/Makefile
generated
vendored
21
vendor/github.com/flynn/go-shlex/Makefile
generated
vendored
@@ -1,21 +0,0 @@
|
||||
# Copyright 2011 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
include $(GOROOT)/src/Make.inc
|
||||
|
||||
TARG=shlex
|
||||
GOFILES=\
|
||||
shlex.go\
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
||||
2
vendor/github.com/flynn/go-shlex/README.md
generated
vendored
2
vendor/github.com/flynn/go-shlex/README.md
generated
vendored
@@ -1,2 +0,0 @@
|
||||
go-shlex is a simple lexer for go that supports shell-style quoting,
|
||||
commenting, and escaping.
|
||||
457
vendor/github.com/flynn/go-shlex/shlex.go
generated
vendored
457
vendor/github.com/flynn/go-shlex/shlex.go
generated
vendored
@@ -1,457 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
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 shlex
|
||||
|
||||
/*
|
||||
Package shlex implements a simple lexer which splits input in to tokens using
|
||||
shell-style rules for quoting and commenting.
|
||||
*/
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
A TokenType is a top-level token; a word, space, comment, unknown.
|
||||
*/
|
||||
type TokenType int
|
||||
|
||||
/*
|
||||
A RuneTokenType is the type of a UTF-8 character; a character, quote, space, escape.
|
||||
*/
|
||||
type RuneTokenType int
|
||||
|
||||
type lexerState int
|
||||
|
||||
type Token struct {
|
||||
tokenType TokenType
|
||||
value string
|
||||
}
|
||||
|
||||
/*
|
||||
Two tokens are equal if both their types and values are equal. A nil token can
|
||||
never equal another token.
|
||||
*/
|
||||
func (a *Token) Equal(b *Token) bool {
|
||||
if a == nil || b == nil {
|
||||
return false
|
||||
}
|
||||
if a.tokenType != b.tokenType {
|
||||
return false
|
||||
}
|
||||
return a.value == b.value
|
||||
}
|
||||
|
||||
const (
|
||||
RUNE_CHAR string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-,/@$*()+=><:;&^%~|!?[]{}"
|
||||
RUNE_SPACE string = " \t\r\n"
|
||||
RUNE_ESCAPING_QUOTE string = "\""
|
||||
RUNE_NONESCAPING_QUOTE string = "'"
|
||||
RUNE_ESCAPE = "\\"
|
||||
RUNE_COMMENT = "#"
|
||||
|
||||
RUNETOKEN_UNKNOWN RuneTokenType = 0
|
||||
RUNETOKEN_CHAR RuneTokenType = 1
|
||||
RUNETOKEN_SPACE RuneTokenType = 2
|
||||
RUNETOKEN_ESCAPING_QUOTE RuneTokenType = 3
|
||||
RUNETOKEN_NONESCAPING_QUOTE RuneTokenType = 4
|
||||
RUNETOKEN_ESCAPE RuneTokenType = 5
|
||||
RUNETOKEN_COMMENT RuneTokenType = 6
|
||||
RUNETOKEN_EOF RuneTokenType = 7
|
||||
|
||||
TOKEN_UNKNOWN TokenType = 0
|
||||
TOKEN_WORD TokenType = 1
|
||||
TOKEN_SPACE TokenType = 2
|
||||
TOKEN_COMMENT TokenType = 3
|
||||
|
||||
STATE_START lexerState = 0
|
||||
STATE_INWORD lexerState = 1
|
||||
STATE_ESCAPING lexerState = 2
|
||||
STATE_ESCAPING_QUOTED lexerState = 3
|
||||
STATE_QUOTED_ESCAPING lexerState = 4
|
||||
STATE_QUOTED lexerState = 5
|
||||
STATE_COMMENT lexerState = 6
|
||||
|
||||
INITIAL_TOKEN_CAPACITY int = 100
|
||||
)
|
||||
|
||||
/*
|
||||
A type for classifying characters. This allows for different sorts of
|
||||
classifiers - those accepting extended non-ascii chars, or strict posix
|
||||
compatibility, for example.
|
||||
*/
|
||||
type TokenClassifier struct {
|
||||
typeMap map[int32]RuneTokenType
|
||||
}
|
||||
|
||||
func addRuneClass(typeMap *map[int32]RuneTokenType, runes string, tokenType RuneTokenType) {
|
||||
for _, rune := range runes {
|
||||
(*typeMap)[int32(rune)] = tokenType
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create a new classifier for basic ASCII characters.
|
||||
*/
|
||||
func NewDefaultClassifier() *TokenClassifier {
|
||||
typeMap := map[int32]RuneTokenType{}
|
||||
addRuneClass(&typeMap, RUNE_CHAR, RUNETOKEN_CHAR)
|
||||
addRuneClass(&typeMap, RUNE_SPACE, RUNETOKEN_SPACE)
|
||||
addRuneClass(&typeMap, RUNE_ESCAPING_QUOTE, RUNETOKEN_ESCAPING_QUOTE)
|
||||
addRuneClass(&typeMap, RUNE_NONESCAPING_QUOTE, RUNETOKEN_NONESCAPING_QUOTE)
|
||||
addRuneClass(&typeMap, RUNE_ESCAPE, RUNETOKEN_ESCAPE)
|
||||
addRuneClass(&typeMap, RUNE_COMMENT, RUNETOKEN_COMMENT)
|
||||
return &TokenClassifier{
|
||||
typeMap: typeMap}
|
||||
}
|
||||
|
||||
func (classifier *TokenClassifier) ClassifyRune(rune int32) RuneTokenType {
|
||||
return classifier.typeMap[rune]
|
||||
}
|
||||
|
||||
/*
|
||||
A type for turning an input stream in to a sequence of strings. Whitespace and
|
||||
comments are skipped.
|
||||
*/
|
||||
type Lexer struct {
|
||||
tokenizer *Tokenizer
|
||||
}
|
||||
|
||||
/*
|
||||
Create a new lexer.
|
||||
*/
|
||||
func NewLexer(r io.Reader) (*Lexer, error) {
|
||||
|
||||
tokenizer, err := NewTokenizer(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lexer := &Lexer{tokenizer: tokenizer}
|
||||
return lexer, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Return the next word, and an error value. If there are no more words, the error
|
||||
will be io.EOF.
|
||||
*/
|
||||
func (l *Lexer) NextWord() (string, error) {
|
||||
var token *Token
|
||||
var err error
|
||||
for {
|
||||
token, err = l.tokenizer.NextToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch token.tokenType {
|
||||
case TOKEN_WORD:
|
||||
{
|
||||
return token.value, nil
|
||||
}
|
||||
case TOKEN_COMMENT:
|
||||
{
|
||||
// skip comments
|
||||
}
|
||||
default:
|
||||
{
|
||||
panic(fmt.Sprintf("Unknown token type: %v", token.tokenType))
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", io.EOF
|
||||
}
|
||||
|
||||
/*
|
||||
A type for turning an input stream in to a sequence of typed tokens.
|
||||
*/
|
||||
type Tokenizer struct {
|
||||
input *bufio.Reader
|
||||
classifier *TokenClassifier
|
||||
}
|
||||
|
||||
/*
|
||||
Create a new tokenizer.
|
||||
*/
|
||||
func NewTokenizer(r io.Reader) (*Tokenizer, error) {
|
||||
input := bufio.NewReader(r)
|
||||
classifier := NewDefaultClassifier()
|
||||
tokenizer := &Tokenizer{
|
||||
input: input,
|
||||
classifier: classifier}
|
||||
return tokenizer, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Scan the stream for the next token.
|
||||
|
||||
This uses an internal state machine. It will panic if it encounters a character
|
||||
which it does not know how to handle.
|
||||
*/
|
||||
func (t *Tokenizer) scanStream() (*Token, error) {
|
||||
state := STATE_START
|
||||
var tokenType TokenType
|
||||
value := make([]int32, 0, INITIAL_TOKEN_CAPACITY)
|
||||
var (
|
||||
nextRune int32
|
||||
nextRuneType RuneTokenType
|
||||
err error
|
||||
)
|
||||
SCAN:
|
||||
for {
|
||||
nextRune, _, err = t.input.ReadRune()
|
||||
nextRuneType = t.classifier.ClassifyRune(nextRune)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
nextRuneType = RUNETOKEN_EOF
|
||||
err = nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
switch state {
|
||||
case STATE_START: // no runes read yet
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
return nil, io.EOF
|
||||
}
|
||||
case RUNETOKEN_CHAR:
|
||||
{
|
||||
tokenType = TOKEN_WORD
|
||||
value = append(value, nextRune)
|
||||
state = STATE_INWORD
|
||||
}
|
||||
case RUNETOKEN_SPACE:
|
||||
{
|
||||
}
|
||||
case RUNETOKEN_ESCAPING_QUOTE:
|
||||
{
|
||||
tokenType = TOKEN_WORD
|
||||
state = STATE_QUOTED_ESCAPING
|
||||
}
|
||||
case RUNETOKEN_NONESCAPING_QUOTE:
|
||||
{
|
||||
tokenType = TOKEN_WORD
|
||||
state = STATE_QUOTED
|
||||
}
|
||||
case RUNETOKEN_ESCAPE:
|
||||
{
|
||||
tokenType = TOKEN_WORD
|
||||
state = STATE_ESCAPING
|
||||
}
|
||||
case RUNETOKEN_COMMENT:
|
||||
{
|
||||
tokenType = TOKEN_COMMENT
|
||||
state = STATE_COMMENT
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Unknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
case STATE_INWORD: // in a regular word
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_CHAR, RUNETOKEN_COMMENT:
|
||||
{
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
case RUNETOKEN_SPACE:
|
||||
{
|
||||
t.input.UnreadRune()
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_ESCAPING_QUOTE:
|
||||
{
|
||||
state = STATE_QUOTED_ESCAPING
|
||||
}
|
||||
case RUNETOKEN_NONESCAPING_QUOTE:
|
||||
{
|
||||
state = STATE_QUOTED
|
||||
}
|
||||
case RUNETOKEN_ESCAPE:
|
||||
{
|
||||
state = STATE_ESCAPING
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
case STATE_ESCAPING: // the next rune after an escape character
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
err = errors.New("EOF found after escape character")
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_CHAR, RUNETOKEN_SPACE, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_NONESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT:
|
||||
{
|
||||
state = STATE_INWORD
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
case STATE_ESCAPING_QUOTED: // the next rune after an escape character, in double quotes
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
err = errors.New("EOF found after escape character")
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_CHAR, RUNETOKEN_SPACE, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_NONESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT:
|
||||
{
|
||||
state = STATE_QUOTED_ESCAPING
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
case STATE_QUOTED_ESCAPING: // in escaping double quotes
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
err = errors.New("EOF found when expecting closing quote.")
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_CHAR, RUNETOKEN_UNKNOWN, RUNETOKEN_SPACE, RUNETOKEN_NONESCAPING_QUOTE, RUNETOKEN_COMMENT:
|
||||
{
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
case RUNETOKEN_ESCAPING_QUOTE:
|
||||
{
|
||||
state = STATE_INWORD
|
||||
}
|
||||
case RUNETOKEN_ESCAPE:
|
||||
{
|
||||
state = STATE_ESCAPING_QUOTED
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
case STATE_QUOTED: // in non-escaping single quotes
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
err = errors.New("EOF found when expecting closing quote.")
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_CHAR, RUNETOKEN_UNKNOWN, RUNETOKEN_SPACE, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT:
|
||||
{
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
case RUNETOKEN_NONESCAPING_QUOTE:
|
||||
{
|
||||
state = STATE_INWORD
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
case STATE_COMMENT:
|
||||
{
|
||||
switch nextRuneType {
|
||||
case RUNETOKEN_EOF:
|
||||
{
|
||||
break SCAN
|
||||
}
|
||||
case RUNETOKEN_CHAR, RUNETOKEN_UNKNOWN, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT, RUNETOKEN_NONESCAPING_QUOTE:
|
||||
{
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
case RUNETOKEN_SPACE:
|
||||
{
|
||||
if nextRune == '\n' {
|
||||
state = STATE_START
|
||||
break SCAN
|
||||
} else {
|
||||
value = append(value, nextRune)
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune))
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
panic(fmt.Sprintf("Unexpected state: %v", state))
|
||||
}
|
||||
}
|
||||
}
|
||||
token := &Token{
|
||||
tokenType: tokenType,
|
||||
value: string(value)}
|
||||
return token, err
|
||||
}
|
||||
|
||||
/*
|
||||
Return the next token in the stream, and an error value. If there are no more
|
||||
tokens available, the error value will be io.EOF.
|
||||
*/
|
||||
func (t *Tokenizer) NextToken() (*Token, error) {
|
||||
return t.scanStream()
|
||||
}
|
||||
|
||||
/*
|
||||
Split a string in to a slice of strings, based upon shell-style rules for
|
||||
quoting, escaping, and spaces.
|
||||
*/
|
||||
func Split(s string) ([]string, error) {
|
||||
l, err := NewLexer(strings.NewReader(s))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
subStrings := []string{}
|
||||
for {
|
||||
word, err := l.NextWord()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return subStrings, nil
|
||||
}
|
||||
return subStrings, err
|
||||
}
|
||||
subStrings = append(subStrings, word)
|
||||
}
|
||||
return subStrings, nil
|
||||
}
|
||||
162
vendor/github.com/flynn/go-shlex/shlex_test.go
generated
vendored
162
vendor/github.com/flynn/go-shlex/shlex_test.go
generated
vendored
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
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 shlex
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func checkError(err error, t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifier(t *testing.T) {
|
||||
classifier := NewDefaultClassifier()
|
||||
runeTests := map[int32]RuneTokenType{
|
||||
'a': RUNETOKEN_CHAR,
|
||||
' ': RUNETOKEN_SPACE,
|
||||
'"': RUNETOKEN_ESCAPING_QUOTE,
|
||||
'\'': RUNETOKEN_NONESCAPING_QUOTE,
|
||||
'#': RUNETOKEN_COMMENT}
|
||||
for rune, expectedType := range runeTests {
|
||||
foundType := classifier.ClassifyRune(rune)
|
||||
if foundType != expectedType {
|
||||
t.Logf("Expected type: %v for rune '%c'(%v). Found type: %v.", expectedType, rune, rune, foundType)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenizer(t *testing.T) {
|
||||
testInput := strings.NewReader("one two \"three four\" \"five \\\"six\\\"\" seven#eight # nine # ten\n eleven")
|
||||
expectedTokens := []*Token{
|
||||
&Token{
|
||||
tokenType: TOKEN_WORD,
|
||||
value: "one"},
|
||||
&Token{
|
||||
tokenType: TOKEN_WORD,
|
||||
value: "two"},
|
||||
&Token{
|
||||
tokenType: TOKEN_WORD,
|
||||
value: "three four"},
|
||||
&Token{
|
||||
tokenType: TOKEN_WORD,
|
||||
value: "five \"six\""},
|
||||
&Token{
|
||||
tokenType: TOKEN_WORD,
|
||||
value: "seven#eight"},
|
||||
&Token{
|
||||
tokenType: TOKEN_COMMENT,
|
||||
value: " nine # ten"},
|
||||
&Token{
|
||||
tokenType: TOKEN_WORD,
|
||||
value: "eleven"}}
|
||||
|
||||
tokenizer, err := NewTokenizer(testInput)
|
||||
checkError(err, t)
|
||||
for _, expectedToken := range expectedTokens {
|
||||
foundToken, err := tokenizer.NextToken()
|
||||
checkError(err, t)
|
||||
if !foundToken.Equal(expectedToken) {
|
||||
t.Error("Expected token:", expectedToken, ". Found:", foundToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLexer(t *testing.T) {
|
||||
testInput := strings.NewReader("one")
|
||||
expectedWord := "one"
|
||||
lexer, err := NewLexer(testInput)
|
||||
checkError(err, t)
|
||||
foundWord, err := lexer.NextWord()
|
||||
checkError(err, t)
|
||||
if expectedWord != foundWord {
|
||||
t.Error("Expected word:", expectedWord, ". Found:", foundWord)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitSimple(t *testing.T) {
|
||||
testInput := "one two three"
|
||||
expectedOutput := []string{"one", "two", "three"}
|
||||
foundOutput, err := Split(testInput)
|
||||
if err != nil {
|
||||
t.Error("Split returned error:", err)
|
||||
}
|
||||
if len(expectedOutput) != len(foundOutput) {
|
||||
t.Error("Split expected:", len(expectedOutput), "results. Found:", len(foundOutput), "results")
|
||||
}
|
||||
for i := range foundOutput {
|
||||
if foundOutput[i] != expectedOutput[i] {
|
||||
t.Error("Item:", i, "(", foundOutput[i], ") differs from the expected value:", expectedOutput[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitEscapingQuotes(t *testing.T) {
|
||||
testInput := "one \"два ${three}\" four"
|
||||
expectedOutput := []string{"one", "два ${three}", "four"}
|
||||
foundOutput, err := Split(testInput)
|
||||
if err != nil {
|
||||
t.Error("Split returned error:", err)
|
||||
}
|
||||
if len(expectedOutput) != len(foundOutput) {
|
||||
t.Error("Split expected:", len(expectedOutput), "results. Found:", len(foundOutput), "results")
|
||||
}
|
||||
for i := range foundOutput {
|
||||
if foundOutput[i] != expectedOutput[i] {
|
||||
t.Error("Item:", i, "(", foundOutput[i], ") differs from the expected value:", expectedOutput[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobbingExpressions(t *testing.T) {
|
||||
testInput := "onefile *file one?ile onefil[de]"
|
||||
expectedOutput := []string{"onefile", "*file", "one?ile", "onefil[de]"}
|
||||
foundOutput, err := Split(testInput)
|
||||
if err != nil {
|
||||
t.Error("Split returned error", err)
|
||||
}
|
||||
if len(expectedOutput) != len(foundOutput) {
|
||||
t.Error("Split expected:", len(expectedOutput), "results. Found:", len(foundOutput), "results")
|
||||
}
|
||||
for i := range foundOutput {
|
||||
if foundOutput[i] != expectedOutput[i] {
|
||||
t.Error("Item:", i, "(", foundOutput[i], ") differs from the expected value:", expectedOutput[i])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSplitNonEscapingQuotes(t *testing.T) {
|
||||
testInput := "one 'два ${three}' four"
|
||||
expectedOutput := []string{"one", "два ${three}", "four"}
|
||||
foundOutput, err := Split(testInput)
|
||||
if err != nil {
|
||||
t.Error("Split returned error:", err)
|
||||
}
|
||||
if len(expectedOutput) != len(foundOutput) {
|
||||
t.Error("Split expected:", len(expectedOutput), "results. Found:", len(foundOutput), "results")
|
||||
}
|
||||
for i := range foundOutput {
|
||||
if foundOutput[i] != expectedOutput[i] {
|
||||
t.Error("Item:", i, "(", foundOutput[i], ") differs from the expected value:", expectedOutput[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
141
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
141
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
@@ -20,6 +20,9 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
@@ -40,48 +43,150 @@ func YAMLToJSON(data interface{}) (json.RawMessage, error) {
|
||||
}
|
||||
|
||||
func BytesToYAMLDoc(data []byte) (interface{}, error) {
|
||||
var document map[interface{}]interface{}
|
||||
if err := yaml.Unmarshal(data, &document); err != nil {
|
||||
var canary map[interface{}]interface{} // validate this is an object and not a different type
|
||||
if err := yaml.Unmarshal(data, &canary); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var document yaml.MapSlice // preserve order that is present in the document
|
||||
if err := yaml.Unmarshal(data, &document); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return document, nil
|
||||
}
|
||||
|
||||
func transformData(in interface{}) (out interface{}, err error) {
|
||||
switch in.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
o := make(map[string]interface{})
|
||||
for k, v := range in.(map[interface{}]interface{}) {
|
||||
sk := ""
|
||||
switch k.(type) {
|
||||
type JSONMapSlice []JSONMapItem
|
||||
|
||||
func (s JSONMapSlice) MarshalJSON() ([]byte, error) {
|
||||
w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
|
||||
s.MarshalEasyJSON(w)
|
||||
return w.BuildBytes()
|
||||
}
|
||||
|
||||
func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
w.RawByte('{')
|
||||
|
||||
ln := len(s)
|
||||
last := ln - 1
|
||||
for i := 0; i < ln; i++ {
|
||||
s[i].MarshalEasyJSON(w)
|
||||
if i != last { // last item
|
||||
w.RawByte(',')
|
||||
}
|
||||
}
|
||||
|
||||
w.RawByte('}')
|
||||
}
|
||||
|
||||
func (s *JSONMapSlice) UnmarshalJSON(data []byte) error {
|
||||
l := jlexer.Lexer{Data: data}
|
||||
s.UnmarshalEasyJSON(&l)
|
||||
return l.Error()
|
||||
}
|
||||
func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
|
||||
var result JSONMapSlice
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
var mi JSONMapItem
|
||||
mi.UnmarshalEasyJSON(in)
|
||||
result = append(result, mi)
|
||||
}
|
||||
*s = result
|
||||
}
|
||||
|
||||
type JSONMapItem struct {
|
||||
Key string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (s JSONMapItem) MarshalJSON() ([]byte, error) {
|
||||
w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
|
||||
s.MarshalEasyJSON(w)
|
||||
return w.BuildBytes()
|
||||
}
|
||||
|
||||
func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
w.String(s.Key)
|
||||
w.RawByte(':')
|
||||
w.Raw(WriteJSON(s.Value))
|
||||
}
|
||||
|
||||
func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
key := in.UnsafeString()
|
||||
in.WantColon()
|
||||
value := in.Interface()
|
||||
in.WantComma()
|
||||
s.Key = key
|
||||
s.Value = value
|
||||
}
|
||||
func (s *JSONMapItem) UnmarshalJSON(data []byte) error {
|
||||
l := jlexer.Lexer{Data: data}
|
||||
s.UnmarshalEasyJSON(&l)
|
||||
return l.Error()
|
||||
}
|
||||
|
||||
func transformData(input interface{}) (out interface{}, err error) {
|
||||
switch in := input.(type) {
|
||||
case yaml.MapSlice:
|
||||
|
||||
o := make(JSONMapSlice, len(in))
|
||||
for i, mi := range in {
|
||||
var nmi JSONMapItem
|
||||
switch k := mi.Key.(type) {
|
||||
case string:
|
||||
sk = k.(string)
|
||||
nmi.Key = k
|
||||
case int:
|
||||
sk = strconv.Itoa(k.(int))
|
||||
nmi.Key = strconv.Itoa(k)
|
||||
default:
|
||||
return nil, fmt.Errorf("types don't match: expect map key string or int get: %T", k)
|
||||
return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key)
|
||||
}
|
||||
v, err = transformData(v)
|
||||
|
||||
v, err := transformData(mi.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
o[sk] = v
|
||||
nmi.Value = v
|
||||
o[i] = nmi
|
||||
}
|
||||
return o, nil
|
||||
case map[interface{}]interface{}:
|
||||
o := make(JSONMapSlice, 0, len(in))
|
||||
for ke, va := range in {
|
||||
var nmi JSONMapItem
|
||||
switch k := ke.(type) {
|
||||
case string:
|
||||
nmi.Key = k
|
||||
case int:
|
||||
nmi.Key = strconv.Itoa(k)
|
||||
default:
|
||||
return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke)
|
||||
}
|
||||
|
||||
v, err := transformData(va)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nmi.Value = v
|
||||
o = append(o, nmi)
|
||||
}
|
||||
return o, nil
|
||||
case []interface{}:
|
||||
in1 := in.([]interface{})
|
||||
len1 := len(in1)
|
||||
len1 := len(in)
|
||||
o := make([]interface{}, len1)
|
||||
for i := 0; i < len1; i++ {
|
||||
o[i], err = transformData(in1[i])
|
||||
o[i], err = transformData(in[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
return in, nil
|
||||
return input, nil
|
||||
}
|
||||
|
||||
// YAMLDoc loads a yaml document from either http or a file and converts it to json
|
||||
|
||||
29
vendor/github.com/go-openapi/swag/yaml_test.go
generated
vendored
29
vendor/github.com/go-openapi/swag/yaml_test.go
generated
vendored
@@ -21,6 +21,8 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -56,34 +58,35 @@ func TestLoadHTTPBytes(t *testing.T) {
|
||||
|
||||
func TestYAMLToJSON(t *testing.T) {
|
||||
|
||||
data := make(map[interface{}]interface{})
|
||||
data[1] = "the int key value"
|
||||
data["name"] = "a string value"
|
||||
data["y"] = "some value"
|
||||
sd := `---
|
||||
1: the int key value
|
||||
name: a string value
|
||||
'y': some value
|
||||
`
|
||||
var data yaml.MapSlice
|
||||
yaml.Unmarshal([]byte(sd), &data)
|
||||
|
||||
d, err := YAMLToJSON(data)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, `{"1":"the int key value","name":"a string value","y":"some value"}`, string(d))
|
||||
}
|
||||
|
||||
data[true] = "the bool value"
|
||||
data = append(data, yaml.MapItem{Key: true, Value: "the bool value"})
|
||||
d, err = YAMLToJSON(data)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, d)
|
||||
|
||||
delete(data, true)
|
||||
data = data[:len(data)-1]
|
||||
|
||||
tag := make(map[interface{}]interface{})
|
||||
tag["name"] = "tag name"
|
||||
data["tag"] = tag
|
||||
tag := yaml.MapSlice{{Key: "name", Value: "tag name"}}
|
||||
data = append(data, yaml.MapItem{Key: "tag", Value: tag})
|
||||
|
||||
d, err = YAMLToJSON(data)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `{"1":"the int key value","name":"a string value","tag":{"name":"tag name"},"y":"some value"}`, string(d))
|
||||
assert.Equal(t, `{"1":"the int key value","name":"a string value","y":"some value","tag":{"name":"tag name"}}`, string(d))
|
||||
|
||||
tag = make(map[interface{}]interface{})
|
||||
tag[true] = "bool tag name"
|
||||
data["tag"] = tag
|
||||
tag = yaml.MapSlice{{Key: true, Value: "bool tag name"}}
|
||||
data = append(data[:len(data)-1], yaml.MapItem{Key: "tag", Value: tag})
|
||||
|
||||
d, err = YAMLToJSON(data)
|
||||
assert.Error(t, err)
|
||||
|
||||
3
vendor/github.com/golang/protobuf/README.md
generated
vendored
3
vendor/github.com/golang/protobuf/README.md
generated
vendored
@@ -22,7 +22,7 @@ To use this software, you must:
|
||||
for details or, if you are using gccgo, follow the instructions at
|
||||
https://golang.org/doc/install/gccgo
|
||||
- Grab the code from the repository and install the proto package.
|
||||
The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`.
|
||||
The simplest way is to run `go get -u github.com/golang/protobuf/protoc-gen-go`.
|
||||
The compiler plugin, protoc-gen-go, will be installed in $GOBIN,
|
||||
defaulting to $GOPATH/bin. It must be in your $PATH for the protocol
|
||||
compiler, protoc, to find it.
|
||||
@@ -104,7 +104,6 @@ for a protocol buffer variable v:
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
- Non-repeated fields of non-message type are values instead of pointers.
|
||||
- Getters are only generated for message and oneof fields.
|
||||
- Enum types do not get an Enum method.
|
||||
|
||||
Consider file test.proto, containing
|
||||
|
||||
2
vendor/github.com/golang/protobuf/proto/decode_test.go
generated
vendored
2
vendor/github.com/golang/protobuf/proto/decode_test.go
generated
vendored
@@ -29,6 +29,8 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package proto_test
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/github.com/golang/protobuf/proto/encode_test.go
generated
vendored
2
vendor/github.com/golang/protobuf/proto/encode_test.go
generated
vendored
@@ -29,6 +29,8 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package proto_test
|
||||
|
||||
import (
|
||||
|
||||
1
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
1
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
@@ -73,7 +73,6 @@ for a protocol buffer variable v:
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
- Non-repeated fields of non-message type are values instead of pointers.
|
||||
- Getters are only generated for message and oneof fields.
|
||||
- Enum types do not get an Enum method.
|
||||
|
||||
The simplest way to describe this is to see an example.
|
||||
|
||||
136
vendor/github.com/golang/protobuf/ptypes/any.go
generated
vendored
Normal file
136
vendor/github.com/golang/protobuf/ptypes/any.go
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ptypes
|
||||
|
||||
// This file implements functions to marshal proto.Message to/from
|
||||
// google.protobuf.Any message.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
)
|
||||
|
||||
const googleApis = "type.googleapis.com/"
|
||||
|
||||
// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
|
||||
//
|
||||
// Note that regular type assertions should be done using the Is
|
||||
// function. AnyMessageName is provided for less common use cases like filtering a
|
||||
// sequence of Any messages based on a set of allowed message type names.
|
||||
func AnyMessageName(any *any.Any) (string, error) {
|
||||
slash := strings.LastIndex(any.TypeUrl, "/")
|
||||
if slash < 0 {
|
||||
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
|
||||
}
|
||||
return any.TypeUrl[slash+1:], nil
|
||||
}
|
||||
|
||||
// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
|
||||
func MarshalAny(pb proto.Message) (*any.Any, error) {
|
||||
value, err := proto.Marshal(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
|
||||
}
|
||||
|
||||
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
|
||||
// allocate a proto.Message for the type specified in a google.protobuf.Any
|
||||
// message. The allocated message is stored in the embedded proto.Message.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var x ptypes.DynamicAny
|
||||
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
|
||||
// fmt.Printf("unmarshaled message: %v", x.Message)
|
||||
type DynamicAny struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
// Empty returns a new proto.Message of the type specified in a
|
||||
// google.protobuf.Any message. It returns an error if corresponding message
|
||||
// type isn't linked in.
|
||||
func Empty(any *any.Any) (proto.Message, error) {
|
||||
aname, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t := proto.MessageType(aname)
|
||||
if t == nil {
|
||||
return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
|
||||
}
|
||||
return reflect.New(t.Elem()).Interface().(proto.Message), nil
|
||||
}
|
||||
|
||||
// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
|
||||
// message and places the decoded result in pb. It returns an error if type of
|
||||
// contents of Any message does not match type of pb message.
|
||||
//
|
||||
// pb can be a proto.Message, or a *DynamicAny.
|
||||
func UnmarshalAny(any *any.Any, pb proto.Message) error {
|
||||
if d, ok := pb.(*DynamicAny); ok {
|
||||
if d.Message == nil {
|
||||
var err error
|
||||
d.Message, err = Empty(any)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return UnmarshalAny(any, d.Message)
|
||||
}
|
||||
|
||||
aname, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mname := proto.MessageName(pb)
|
||||
if aname != mname {
|
||||
return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
|
||||
}
|
||||
return proto.Unmarshal(any.Value, pb)
|
||||
}
|
||||
|
||||
// Is returns true if any value contains a given message type.
|
||||
func Is(any *any.Any, pb proto.Message) bool {
|
||||
aname, err := AnyMessageName(any)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return aname == proto.MessageName(pb)
|
||||
}
|
||||
168
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
Normal file
168
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/any/any.proto
|
||||
|
||||
/*
|
||||
Package any is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/golang/protobuf/ptypes/any/any.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Any
|
||||
*/
|
||||
package any
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// `Any` contains an arbitrary serialized protocol buffer message along with a
|
||||
// URL that describes the type of the serialized message.
|
||||
//
|
||||
// Protobuf library provides support to pack/unpack Any values in the form
|
||||
// of utility functions or additional generated methods of the Any type.
|
||||
//
|
||||
// Example 1: Pack and unpack a message in C++.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any;
|
||||
// any.PackFrom(foo);
|
||||
// ...
|
||||
// if (any.UnpackTo(&foo)) {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// Example 2: Pack and unpack a message in Java.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any = Any.pack(foo);
|
||||
// ...
|
||||
// if (any.is(Foo.class)) {
|
||||
// foo = any.unpack(Foo.class);
|
||||
// }
|
||||
//
|
||||
// Example 3: Pack and unpack a message in Python.
|
||||
//
|
||||
// foo = Foo(...)
|
||||
// any = Any()
|
||||
// any.Pack(foo)
|
||||
// ...
|
||||
// if any.Is(Foo.DESCRIPTOR):
|
||||
// any.Unpack(foo)
|
||||
// ...
|
||||
//
|
||||
// The pack methods provided by protobuf library will by default use
|
||||
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
// methods only use the fully qualified type name after the last '/'
|
||||
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
|
||||
// name "y.z".
|
||||
//
|
||||
//
|
||||
// JSON
|
||||
// ====
|
||||
// The JSON representation of an `Any` value uses the regular
|
||||
// representation of the deserialized, embedded message, with an
|
||||
// additional field `@type` which contains the type URL. Example:
|
||||
//
|
||||
// package google.profile;
|
||||
// message Person {
|
||||
// string first_name = 1;
|
||||
// string last_name = 2;
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.profile.Person",
|
||||
// "firstName": <string>,
|
||||
// "lastName": <string>
|
||||
// }
|
||||
//
|
||||
// If the embedded message type is well-known and has a custom JSON
|
||||
// representation, that representation will be embedded adding a field
|
||||
// `value` which holds the custom JSON in addition to the `@type`
|
||||
// field. Example (for message [google.protobuf.Duration][]):
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.protobuf.Duration",
|
||||
// "value": "1.212s"
|
||||
// }
|
||||
//
|
||||
type Any struct {
|
||||
// A URL/resource name whose content describes the type of the
|
||||
// serialized protocol buffer message.
|
||||
//
|
||||
// For URLs which use the scheme `http`, `https`, or no scheme, the
|
||||
// following restrictions and interpretations apply:
|
||||
//
|
||||
// * If no scheme is provided, `https` is assumed.
|
||||
// * The last segment of the URL's path must represent the fully
|
||||
// qualified name of the type (as in `path/google.protobuf.Duration`).
|
||||
// The name should be in a canonical form (e.g., leading "." is
|
||||
// not accepted).
|
||||
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
|
||||
// value in binary format, or produce an error.
|
||||
// * Applications are allowed to cache lookup results based on the
|
||||
// URL, or have them precompiled into a binary to avoid any
|
||||
// lookup. Therefore, binary compatibility needs to be preserved
|
||||
// on changes to types. (Use versioned type names to manage
|
||||
// breaking changes.)
|
||||
//
|
||||
// Schemes other than `http`, `https` (or the empty scheme) might be
|
||||
// used with implementation specific semantics.
|
||||
//
|
||||
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"`
|
||||
// Must be a valid serialized protocol buffer of the above specified type.
|
||||
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Any) Reset() { *m = Any{} }
|
||||
func (m *Any) String() string { return proto.CompactTextString(m) }
|
||||
func (*Any) ProtoMessage() {}
|
||||
func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
func (*Any) XXX_WellKnownType() string { return "Any" }
|
||||
|
||||
func (m *Any) GetTypeUrl() string {
|
||||
if m != nil {
|
||||
return m.TypeUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Any) GetValue() []byte {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Any)(nil), "google.protobuf.Any")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 184 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9,
|
||||
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
|
||||
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcc,
|
||||
0xab, 0x04, 0x61, 0x3d, 0xb0, 0xb8, 0x10, 0x7f, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x1e, 0x4c,
|
||||
0x95, 0x92, 0x19, 0x17, 0xb3, 0x63, 0x5e, 0xa5, 0x90, 0x24, 0x17, 0x07, 0x48, 0x79, 0x7c, 0x69,
|
||||
0x51, 0x8e, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24,
|
||||
0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13, 0x04, 0xe1,
|
||||
0x38, 0xe5, 0x73, 0x09, 0x27, 0xe7, 0xe7, 0xea, 0xa1, 0x19, 0xe7, 0xc4, 0xe1, 0x98, 0x57, 0x19,
|
||||
0x00, 0xe2, 0x04, 0x30, 0x46, 0xa9, 0x12, 0xe5, 0xb8, 0x45, 0x4c, 0xcc, 0xee, 0x01, 0x4e, 0xab,
|
||||
0x98, 0xe4, 0xdc, 0x21, 0x46, 0x05, 0x40, 0x95, 0xe8, 0x85, 0xa7, 0xe6, 0xe4, 0x78, 0xe7, 0xe5,
|
||||
0x97, 0xe7, 0x85, 0x80, 0x94, 0x26, 0xb1, 0x81, 0xf5, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff,
|
||||
0x45, 0x1f, 0x1a, 0xf2, 0xf3, 0x00, 0x00, 0x00,
|
||||
}
|
||||
139
vendor/github.com/golang/protobuf/ptypes/any/any.proto
generated
vendored
Normal file
139
vendor/github.com/golang/protobuf/ptypes/any/any.proto
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
||||
option go_package = "github.com/golang/protobuf/ptypes/any";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "AnyProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
// `Any` contains an arbitrary serialized protocol buffer message along with a
|
||||
// URL that describes the type of the serialized message.
|
||||
//
|
||||
// Protobuf library provides support to pack/unpack Any values in the form
|
||||
// of utility functions or additional generated methods of the Any type.
|
||||
//
|
||||
// Example 1: Pack and unpack a message in C++.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any;
|
||||
// any.PackFrom(foo);
|
||||
// ...
|
||||
// if (any.UnpackTo(&foo)) {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// Example 2: Pack and unpack a message in Java.
|
||||
//
|
||||
// Foo foo = ...;
|
||||
// Any any = Any.pack(foo);
|
||||
// ...
|
||||
// if (any.is(Foo.class)) {
|
||||
// foo = any.unpack(Foo.class);
|
||||
// }
|
||||
//
|
||||
// Example 3: Pack and unpack a message in Python.
|
||||
//
|
||||
// foo = Foo(...)
|
||||
// any = Any()
|
||||
// any.Pack(foo)
|
||||
// ...
|
||||
// if any.Is(Foo.DESCRIPTOR):
|
||||
// any.Unpack(foo)
|
||||
// ...
|
||||
//
|
||||
// The pack methods provided by protobuf library will by default use
|
||||
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
// methods only use the fully qualified type name after the last '/'
|
||||
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
|
||||
// name "y.z".
|
||||
//
|
||||
//
|
||||
// JSON
|
||||
// ====
|
||||
// The JSON representation of an `Any` value uses the regular
|
||||
// representation of the deserialized, embedded message, with an
|
||||
// additional field `@type` which contains the type URL. Example:
|
||||
//
|
||||
// package google.profile;
|
||||
// message Person {
|
||||
// string first_name = 1;
|
||||
// string last_name = 2;
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.profile.Person",
|
||||
// "firstName": <string>,
|
||||
// "lastName": <string>
|
||||
// }
|
||||
//
|
||||
// If the embedded message type is well-known and has a custom JSON
|
||||
// representation, that representation will be embedded adding a field
|
||||
// `value` which holds the custom JSON in addition to the `@type`
|
||||
// field. Example (for message [google.protobuf.Duration][]):
|
||||
//
|
||||
// {
|
||||
// "@type": "type.googleapis.com/google.protobuf.Duration",
|
||||
// "value": "1.212s"
|
||||
// }
|
||||
//
|
||||
message Any {
|
||||
// A URL/resource name whose content describes the type of the
|
||||
// serialized protocol buffer message.
|
||||
//
|
||||
// For URLs which use the scheme `http`, `https`, or no scheme, the
|
||||
// following restrictions and interpretations apply:
|
||||
//
|
||||
// * If no scheme is provided, `https` is assumed.
|
||||
// * The last segment of the URL's path must represent the fully
|
||||
// qualified name of the type (as in `path/google.protobuf.Duration`).
|
||||
// The name should be in a canonical form (e.g., leading "." is
|
||||
// not accepted).
|
||||
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
|
||||
// value in binary format, or produce an error.
|
||||
// * Applications are allowed to cache lookup results based on the
|
||||
// URL, or have them precompiled into a binary to avoid any
|
||||
// lookup. Therefore, binary compatibility needs to be preserved
|
||||
// on changes to types. (Use versioned type names to manage
|
||||
// breaking changes.)
|
||||
//
|
||||
// Schemes other than `http`, `https` (or the empty scheme) might be
|
||||
// used with implementation specific semantics.
|
||||
//
|
||||
string type_url = 1;
|
||||
|
||||
// Must be a valid serialized protocol buffer of the above specified type.
|
||||
bytes value = 2;
|
||||
}
|
||||
113
vendor/github.com/golang/protobuf/ptypes/any_test.go
generated
vendored
Normal file
113
vendor/github.com/golang/protobuf/ptypes/any_test.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ptypes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
)
|
||||
|
||||
func TestMarshalUnmarshal(t *testing.T) {
|
||||
orig := &any.Any{Value: []byte("test")}
|
||||
|
||||
packed, err := MarshalAny(orig)
|
||||
if err != nil {
|
||||
t.Errorf("MarshalAny(%+v): got: _, %v exp: _, nil", orig, err)
|
||||
}
|
||||
|
||||
unpacked := &any.Any{}
|
||||
err = UnmarshalAny(packed, unpacked)
|
||||
if err != nil || !proto.Equal(unpacked, orig) {
|
||||
t.Errorf("got: %v, %+v; want nil, %+v", err, unpacked, orig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIs(t *testing.T) {
|
||||
a, err := MarshalAny(&pb.FileDescriptorProto{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if Is(a, &pb.DescriptorProto{}) {
|
||||
t.Error("FileDescriptorProto is not a DescriptorProto, but Is says it is")
|
||||
}
|
||||
if !Is(a, &pb.FileDescriptorProto{}) {
|
||||
t.Error("FileDescriptorProto is indeed a FileDescriptorProto, but Is says it is not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDifferentUrlPrefixes(t *testing.T) {
|
||||
m := &pb.FileDescriptorProto{}
|
||||
a := &any.Any{TypeUrl: "foo/bar/" + proto.MessageName(m)}
|
||||
if !Is(a, m) {
|
||||
t.Errorf("message with type url %q didn't satisfy Is for type %q", a.TypeUrl, proto.MessageName(m))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalDynamic(t *testing.T) {
|
||||
want := &pb.FileDescriptorProto{Name: proto.String("foo")}
|
||||
a, err := MarshalAny(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var got DynamicAny
|
||||
if err := UnmarshalAny(a, &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !proto.Equal(got.Message, want) {
|
||||
t.Errorf("invalid result from UnmarshalAny, got %q want %q", got.Message, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
want := &pb.FileDescriptorProto{}
|
||||
a, err := MarshalAny(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := Empty(a)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !proto.Equal(got, want) {
|
||||
t.Errorf("unequal empty message, got %q, want %q", got, want)
|
||||
}
|
||||
|
||||
// that's a valid type_url for a message which shouldn't be linked into this
|
||||
// test binary. We want an error.
|
||||
a.TypeUrl = "type.googleapis.com/google.protobuf.FieldMask"
|
||||
if _, err := Empty(a); err == nil {
|
||||
t.Errorf("got no error for an attempt to create a message of type %q, which shouldn't be linked in", a.TypeUrl)
|
||||
}
|
||||
}
|
||||
35
vendor/github.com/golang/protobuf/ptypes/doc.go
generated
vendored
Normal file
35
vendor/github.com/golang/protobuf/ptypes/doc.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/*
|
||||
Package ptypes contains code for interacting with well-known types.
|
||||
*/
|
||||
package ptypes
|
||||
102
vendor/github.com/golang/protobuf/ptypes/duration.go
generated
vendored
Normal file
102
vendor/github.com/golang/protobuf/ptypes/duration.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ptypes
|
||||
|
||||
// This file implements conversions between google.protobuf.Duration
|
||||
// and time.Duration.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
durpb "github.com/golang/protobuf/ptypes/duration"
|
||||
)
|
||||
|
||||
const (
|
||||
// Range of a durpb.Duration in seconds, as specified in
|
||||
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
|
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
|
||||
minSeconds = -maxSeconds
|
||||
)
|
||||
|
||||
// validateDuration determines whether the durpb.Duration is valid according to the
|
||||
// definition in google/protobuf/duration.proto. A valid durpb.Duration
|
||||
// may still be too large to fit into a time.Duration (the range of durpb.Duration
|
||||
// is about 10,000 years, and the range of time.Duration is about 290).
|
||||
func validateDuration(d *durpb.Duration) error {
|
||||
if d == nil {
|
||||
return errors.New("duration: nil Duration")
|
||||
}
|
||||
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
|
||||
return fmt.Errorf("duration: %v: seconds out of range", d)
|
||||
}
|
||||
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
|
||||
return fmt.Errorf("duration: %v: nanos out of range", d)
|
||||
}
|
||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
|
||||
return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Duration converts a durpb.Duration to a time.Duration. Duration
|
||||
// returns an error if the durpb.Duration is invalid or is too large to be
|
||||
// represented in a time.Duration.
|
||||
func Duration(p *durpb.Duration) (time.Duration, error) {
|
||||
if err := validateDuration(p); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d := time.Duration(p.Seconds) * time.Second
|
||||
if int64(d/time.Second) != p.Seconds {
|
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
|
||||
}
|
||||
if p.Nanos != 0 {
|
||||
d += time.Duration(p.Nanos)
|
||||
if (d < 0) != (p.Nanos < 0) {
|
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// DurationProto converts a time.Duration to a durpb.Duration.
|
||||
func DurationProto(d time.Duration) *durpb.Duration {
|
||||
nanos := d.Nanoseconds()
|
||||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
return &durpb.Duration{
|
||||
Seconds: secs,
|
||||
Nanos: int32(nanos),
|
||||
}
|
||||
}
|
||||
121
vendor/github.com/golang/protobuf/ptypes/duration_test.go
generated
vendored
Normal file
121
vendor/github.com/golang/protobuf/ptypes/duration_test.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ptypes
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
durpb "github.com/golang/protobuf/ptypes/duration"
|
||||
)
|
||||
|
||||
const (
|
||||
minGoSeconds = math.MinInt64 / int64(1e9)
|
||||
maxGoSeconds = math.MaxInt64 / int64(1e9)
|
||||
)
|
||||
|
||||
var durationTests = []struct {
|
||||
proto *durpb.Duration
|
||||
isValid bool
|
||||
inRange bool
|
||||
dur time.Duration
|
||||
}{
|
||||
// The zero duration.
|
||||
{&durpb.Duration{0, 0}, true, true, 0},
|
||||
// Some ordinary non-zero durations.
|
||||
{&durpb.Duration{100, 0}, true, true, 100 * time.Second},
|
||||
{&durpb.Duration{-100, 0}, true, true, -100 * time.Second},
|
||||
{&durpb.Duration{100, 987}, true, true, 100*time.Second + 987},
|
||||
{&durpb.Duration{-100, -987}, true, true, -(100*time.Second + 987)},
|
||||
// The largest duration representable in Go.
|
||||
{&durpb.Duration{maxGoSeconds, int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, true, math.MaxInt64},
|
||||
// The smallest duration representable in Go.
|
||||
{&durpb.Duration{minGoSeconds, int32(math.MinInt64 - 1e9*minGoSeconds)}, true, true, math.MinInt64},
|
||||
{nil, false, false, 0},
|
||||
{&durpb.Duration{-100, 987}, false, false, 0},
|
||||
{&durpb.Duration{100, -987}, false, false, 0},
|
||||
{&durpb.Duration{math.MinInt64, 0}, false, false, 0},
|
||||
{&durpb.Duration{math.MaxInt64, 0}, false, false, 0},
|
||||
// The largest valid duration.
|
||||
{&durpb.Duration{maxSeconds, 1e9 - 1}, true, false, 0},
|
||||
// The smallest valid duration.
|
||||
{&durpb.Duration{minSeconds, -(1e9 - 1)}, true, false, 0},
|
||||
// The smallest invalid duration above the valid range.
|
||||
{&durpb.Duration{maxSeconds + 1, 0}, false, false, 0},
|
||||
// The largest invalid duration below the valid range.
|
||||
{&durpb.Duration{minSeconds - 1, -(1e9 - 1)}, false, false, 0},
|
||||
// One nanosecond past the largest duration representable in Go.
|
||||
{&durpb.Duration{maxGoSeconds, int32(math.MaxInt64-1e9*maxGoSeconds) + 1}, true, false, 0},
|
||||
// One nanosecond past the smallest duration representable in Go.
|
||||
{&durpb.Duration{minGoSeconds, int32(math.MinInt64-1e9*minGoSeconds) - 1}, true, false, 0},
|
||||
// One second past the largest duration representable in Go.
|
||||
{&durpb.Duration{maxGoSeconds + 1, int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, false, 0},
|
||||
// One second past the smallest duration representable in Go.
|
||||
{&durpb.Duration{minGoSeconds - 1, int32(math.MinInt64 - 1e9*minGoSeconds)}, true, false, 0},
|
||||
}
|
||||
|
||||
func TestValidateDuration(t *testing.T) {
|
||||
for _, test := range durationTests {
|
||||
err := validateDuration(test.proto)
|
||||
gotValid := (err == nil)
|
||||
if gotValid != test.isValid {
|
||||
t.Errorf("validateDuration(%v) = %t, want %t", test.proto, gotValid, test.isValid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDuration(t *testing.T) {
|
||||
for _, test := range durationTests {
|
||||
got, err := Duration(test.proto)
|
||||
gotOK := (err == nil)
|
||||
wantOK := test.isValid && test.inRange
|
||||
if gotOK != wantOK {
|
||||
t.Errorf("Duration(%v) ok = %t, want %t", test.proto, gotOK, wantOK)
|
||||
}
|
||||
if err == nil && got != test.dur {
|
||||
t.Errorf("Duration(%v) = %v, want %v", test.proto, got, test.dur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationProto(t *testing.T) {
|
||||
for _, test := range durationTests {
|
||||
if test.isValid && test.inRange {
|
||||
got := DurationProto(test.dur)
|
||||
if !proto.Equal(got, test.proto) {
|
||||
t.Errorf("DurationProto(%v) = %v, want %v", test.dur, got, test.proto)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
vendor/github.com/golang/protobuf/ptypes/regen.sh
generated
vendored
Executable file
66
vendor/github.com/golang/protobuf/ptypes/regen.sh
generated
vendored
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# This script fetches and rebuilds the "well-known types" protocol buffers.
|
||||
# To run this you will need protoc and goprotobuf installed;
|
||||
# see https://github.com/golang/protobuf for instructions.
|
||||
# You also need Go and Git installed.
|
||||
|
||||
PKG=github.com/golang/protobuf/ptypes
|
||||
UPSTREAM=https://github.com/google/protobuf
|
||||
UPSTREAM_SUBDIR=src/google/protobuf
|
||||
PROTO_FILES='
|
||||
any.proto
|
||||
duration.proto
|
||||
empty.proto
|
||||
struct.proto
|
||||
timestamp.proto
|
||||
wrappers.proto
|
||||
'
|
||||
|
||||
function die() {
|
||||
echo 1>&2 $*
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Sanity check that the right tools are accessible.
|
||||
for tool in go git protoc protoc-gen-go; do
|
||||
q=$(which $tool) || die "didn't find $tool"
|
||||
echo 1>&2 "$tool: $q"
|
||||
done
|
||||
|
||||
tmpdir=$(mktemp -d -t regen-wkt.XXXXXX)
|
||||
trap 'rm -rf $tmpdir' EXIT
|
||||
|
||||
echo -n 1>&2 "finding package dir... "
|
||||
pkgdir=$(go list -f '{{.Dir}}' $PKG)
|
||||
echo 1>&2 $pkgdir
|
||||
base=$(echo $pkgdir | sed "s,/$PKG\$,,")
|
||||
echo 1>&2 "base: $base"
|
||||
cd $base
|
||||
|
||||
echo 1>&2 "fetching latest protos... "
|
||||
git clone -q $UPSTREAM $tmpdir
|
||||
# Pass 1: build mapping from upstream filename to our filename.
|
||||
declare -A filename_map
|
||||
for f in $(cd $PKG && find * -name '*.proto'); do
|
||||
echo -n 1>&2 "looking for latest version of $f... "
|
||||
up=$(cd $tmpdir/$UPSTREAM_SUBDIR && find * -name $(basename $f) | grep -v /testdata/)
|
||||
echo 1>&2 $up
|
||||
if [ $(echo $up | wc -w) != "1" ]; then
|
||||
die "not exactly one match"
|
||||
fi
|
||||
filename_map[$up]=$f
|
||||
done
|
||||
# Pass 2: copy files
|
||||
for up in "${!filename_map[@]}"; do
|
||||
f=${filename_map[$up]}
|
||||
shortname=$(basename $f | sed 's,\.proto$,,')
|
||||
cp $tmpdir/$UPSTREAM_SUBDIR/$up $PKG/$f
|
||||
done
|
||||
|
||||
# Run protoc once per package.
|
||||
for dir in $(find $PKG -name '*.proto' | xargs dirname | sort | uniq); do
|
||||
echo 1>&2 "* $dir"
|
||||
protoc --go_out=. $dir/*.proto
|
||||
done
|
||||
echo 1>&2 "All OK"
|
||||
125
vendor/github.com/golang/protobuf/ptypes/timestamp.go
generated
vendored
Normal file
125
vendor/github.com/golang/protobuf/ptypes/timestamp.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ptypes
|
||||
|
||||
// This file implements operations on google.protobuf.Timestamp.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
tspb "github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
const (
|
||||
// Seconds field of the earliest valid Timestamp.
|
||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
minValidSeconds = -62135596800
|
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800
|
||||
)
|
||||
|
||||
// validateTimestamp determines whether a Timestamp is valid.
|
||||
// A valid timestamp represents a time in the range
|
||||
// [0001-01-01, 10000-01-01) and has a Nanos field
|
||||
// in the range [0, 1e9).
|
||||
//
|
||||
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||
// Otherwise, it returns an error that describes
|
||||
// the problem.
|
||||
//
|
||||
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
|
||||
func validateTimestamp(ts *tspb.Timestamp) error {
|
||||
if ts == nil {
|
||||
return errors.New("timestamp: nil Timestamp")
|
||||
}
|
||||
if ts.Seconds < minValidSeconds {
|
||||
return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
|
||||
}
|
||||
if ts.Seconds >= maxValidSeconds {
|
||||
return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
|
||||
}
|
||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
|
||||
return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
|
||||
// It returns an error if the argument is invalid.
|
||||
//
|
||||
// Unlike most Go functions, if Timestamp returns an error, the first return value
|
||||
// is not the zero time.Time. Instead, it is the value obtained from the
|
||||
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||
// do map to valid time.Times.
|
||||
//
|
||||
// A nil Timestamp returns an error. The first return value in that case is
|
||||
// undefined.
|
||||
func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
|
||||
// Don't return the zero value on error, because corresponds to a valid
|
||||
// timestamp. Instead return whatever time.Unix gives us.
|
||||
var t time.Time
|
||||
if ts == nil {
|
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else {
|
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
|
||||
}
|
||||
return t, validateTimestamp(ts)
|
||||
}
|
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
|
||||
seconds := t.Unix()
|
||||
nanos := int32(t.Sub(time.Unix(seconds, 0)))
|
||||
ts := &tspb.Timestamp{
|
||||
Seconds: seconds,
|
||||
Nanos: nanos,
|
||||
}
|
||||
if err := validateTimestamp(ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
|
||||
// Timestamps, it returns an error message in parentheses.
|
||||
func TimestampString(ts *tspb.Timestamp) string {
|
||||
t, err := Timestamp(ts)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("(%v)", err)
|
||||
}
|
||||
return t.Format(time.RFC3339Nano)
|
||||
}
|
||||
138
vendor/github.com/golang/protobuf/ptypes/timestamp_test.go
generated
vendored
Normal file
138
vendor/github.com/golang/protobuf/ptypes/timestamp_test.go
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ptypes
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
tspb "github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
var tests = []struct {
|
||||
ts *tspb.Timestamp
|
||||
valid bool
|
||||
t time.Time
|
||||
}{
|
||||
// The timestamp representing the Unix epoch date.
|
||||
{&tspb.Timestamp{0, 0}, true, utcDate(1970, 1, 1)},
|
||||
// The smallest representable timestamp.
|
||||
{&tspb.Timestamp{math.MinInt64, math.MinInt32}, false,
|
||||
time.Unix(math.MinInt64, math.MinInt32).UTC()},
|
||||
// The smallest representable timestamp with non-negative nanos.
|
||||
{&tspb.Timestamp{math.MinInt64, 0}, false, time.Unix(math.MinInt64, 0).UTC()},
|
||||
// The earliest valid timestamp.
|
||||
{&tspb.Timestamp{minValidSeconds, 0}, true, utcDate(1, 1, 1)},
|
||||
//"0001-01-01T00:00:00Z"},
|
||||
// The largest representable timestamp.
|
||||
{&tspb.Timestamp{math.MaxInt64, math.MaxInt32}, false,
|
||||
time.Unix(math.MaxInt64, math.MaxInt32).UTC()},
|
||||
// The largest representable timestamp with nanos in range.
|
||||
{&tspb.Timestamp{math.MaxInt64, 1e9 - 1}, false,
|
||||
time.Unix(math.MaxInt64, 1e9-1).UTC()},
|
||||
// The largest valid timestamp.
|
||||
{&tspb.Timestamp{maxValidSeconds - 1, 1e9 - 1}, true,
|
||||
time.Date(9999, 12, 31, 23, 59, 59, 1e9-1, time.UTC)},
|
||||
// The smallest invalid timestamp that is larger than the valid range.
|
||||
{&tspb.Timestamp{maxValidSeconds, 0}, false, time.Unix(maxValidSeconds, 0).UTC()},
|
||||
// A date before the epoch.
|
||||
{&tspb.Timestamp{-281836800, 0}, true, utcDate(1961, 1, 26)},
|
||||
// A date after the epoch.
|
||||
{&tspb.Timestamp{1296000000, 0}, true, utcDate(2011, 1, 26)},
|
||||
// A date after the epoch, in the middle of the day.
|
||||
{&tspb.Timestamp{1296012345, 940483}, true,
|
||||
time.Date(2011, 1, 26, 3, 25, 45, 940483, time.UTC)},
|
||||
}
|
||||
|
||||
func TestValidateTimestamp(t *testing.T) {
|
||||
for _, s := range tests {
|
||||
got := validateTimestamp(s.ts)
|
||||
if (got == nil) != s.valid {
|
||||
t.Errorf("validateTimestamp(%v) = %v, want %v", s.ts, got, s.valid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestamp(t *testing.T) {
|
||||
for _, s := range tests {
|
||||
got, err := Timestamp(s.ts)
|
||||
if (err == nil) != s.valid {
|
||||
t.Errorf("Timestamp(%v) error = %v, but valid = %t", s.ts, err, s.valid)
|
||||
} else if s.valid && got != s.t {
|
||||
t.Errorf("Timestamp(%v) = %v, want %v", s.ts, got, s.t)
|
||||
}
|
||||
}
|
||||
// Special case: a nil Timestamp is an error, but returns the 0 Unix time.
|
||||
got, err := Timestamp(nil)
|
||||
want := time.Unix(0, 0).UTC()
|
||||
if got != want {
|
||||
t.Errorf("Timestamp(nil) = %v, want %v", got, want)
|
||||
}
|
||||
if err == nil {
|
||||
t.Errorf("Timestamp(nil) error = nil, expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestampProto(t *testing.T) {
|
||||
for _, s := range tests {
|
||||
got, err := TimestampProto(s.t)
|
||||
if (err == nil) != s.valid {
|
||||
t.Errorf("TimestampProto(%v) error = %v, but valid = %t", s.t, err, s.valid)
|
||||
} else if s.valid && !proto.Equal(got, s.ts) {
|
||||
t.Errorf("TimestampProto(%v) = %v, want %v", s.t, got, s.ts)
|
||||
}
|
||||
}
|
||||
// No corresponding special case here: no time.Time results in a nil Timestamp.
|
||||
}
|
||||
|
||||
func TestTimestampString(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
ts *tspb.Timestamp
|
||||
want string
|
||||
}{
|
||||
// Not much testing needed because presumably time.Format is
|
||||
// well-tested.
|
||||
{&tspb.Timestamp{0, 0}, "1970-01-01T00:00:00Z"},
|
||||
{&tspb.Timestamp{minValidSeconds - 1, 0}, "(timestamp: seconds:-62135596801 before 0001-01-01)"},
|
||||
} {
|
||||
got := TimestampString(test.ts)
|
||||
if got != test.want {
|
||||
t.Errorf("TimestampString(%v) = %q, want %q", test.ts, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func utcDate(year, month, day int) time.Time {
|
||||
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
8
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go
generated
vendored
8
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go
generated
vendored
@@ -50,7 +50,7 @@ func OpenTracingClientInterceptor(tracer opentracing.Tracer, optFuncs ...Option)
|
||||
gRPCComponentTag,
|
||||
)
|
||||
defer clientSpan.Finish()
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
md, ok := metadata.FromOutgoingContext(ctx)
|
||||
if !ok {
|
||||
md = metadata.New(nil)
|
||||
} else {
|
||||
@@ -62,7 +62,7 @@ func OpenTracingClientInterceptor(tracer opentracing.Tracer, optFuncs ...Option)
|
||||
if err != nil {
|
||||
clientSpan.LogFields(log.String("event", "Tracer.Inject() failed"), log.Error(err))
|
||||
}
|
||||
ctx = metadata.NewContext(ctx, md)
|
||||
ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
if otgrpcOpts.logPayloads {
|
||||
clientSpan.LogFields(log.Object("gRPC request", req))
|
||||
}
|
||||
@@ -72,8 +72,8 @@ func OpenTracingClientInterceptor(tracer opentracing.Tracer, optFuncs ...Option)
|
||||
clientSpan.LogFields(log.Object("gRPC response", resp))
|
||||
}
|
||||
} else {
|
||||
clientSpan.LogFields(log.String("event", "gRPC error"), log.Error(err))
|
||||
ext.Error.Set(clientSpan, true)
|
||||
SetSpanTags(clientSpan, err, true)
|
||||
clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error()))
|
||||
}
|
||||
if otgrpcOpts.decorator != nil {
|
||||
otgrpcOpts.decorator(clientSpan, method, req, resp, err)
|
||||
|
||||
69
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go
generated
vendored
Normal file
69
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package otgrpc
|
||||
|
||||
import (
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// A Class is a set of types of outcomes (including errors) that will often
|
||||
// be handled in the same way.
|
||||
type Class string
|
||||
|
||||
const (
|
||||
Unknown Class = "0xx"
|
||||
// Success represents outcomes that achieved the desired results.
|
||||
Success Class = "2xx"
|
||||
// ClientError represents errors that were the client's fault.
|
||||
ClientError Class = "4xx"
|
||||
// ServerError represents errors that were the server's fault.
|
||||
ServerError Class = "5xx"
|
||||
)
|
||||
|
||||
// ErrorClass returns the class of the given error
|
||||
func ErrorClass(err error) Class {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
switch s.Code() {
|
||||
// Success or "success"
|
||||
case codes.OK, codes.Canceled:
|
||||
return Success
|
||||
|
||||
// Client errors
|
||||
case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists,
|
||||
codes.PermissionDenied, codes.Unauthenticated, codes.FailedPrecondition,
|
||||
codes.OutOfRange:
|
||||
return ClientError
|
||||
|
||||
// Server errors
|
||||
case codes.DeadlineExceeded, codes.ResourceExhausted, codes.Aborted,
|
||||
codes.Unimplemented, codes.Internal, codes.Unavailable, codes.DataLoss:
|
||||
return ServerError
|
||||
|
||||
// Not sure
|
||||
case codes.Unknown:
|
||||
fallthrough
|
||||
default:
|
||||
return Unknown
|
||||
}
|
||||
}
|
||||
return Unknown
|
||||
}
|
||||
|
||||
// SetSpanTags sets one or more tags on the given span according to the
|
||||
// error.
|
||||
func SetSpanTags(span opentracing.Span, err error, client bool) {
|
||||
c := ErrorClass(err)
|
||||
code := codes.Unknown
|
||||
if s, ok := status.FromError(err); ok {
|
||||
code = s.Code()
|
||||
}
|
||||
span.SetTag("response_code", code)
|
||||
span.SetTag("response_class", c)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
if client || c == ServerError {
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
}
|
||||
57
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors_test.go
generated
vendored
Normal file
57
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors_test.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package otgrpc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/opentracing/opentracing-go/mocktracer"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
firstCode = codes.OK
|
||||
lastCode = codes.DataLoss
|
||||
)
|
||||
|
||||
func TestSpanTags(t *testing.T) {
|
||||
tracer := mocktracer.New()
|
||||
for code := firstCode; code <= lastCode; code++ {
|
||||
// Client error
|
||||
tracer.Reset()
|
||||
span := tracer.StartSpan("test-trace-client")
|
||||
err := status.Error(code, "")
|
||||
SetSpanTags(span, err, true)
|
||||
span.Finish()
|
||||
|
||||
// Assert added tags
|
||||
rawSpan := tracer.FinishedSpans()[0]
|
||||
expectedTags := map[string]interface{}{
|
||||
"response_code": code,
|
||||
"response_class": ErrorClass(err),
|
||||
}
|
||||
if err != nil {
|
||||
expectedTags["error"] = true
|
||||
}
|
||||
assert.Equal(t, expectedTags, rawSpan.Tags())
|
||||
|
||||
// Server error
|
||||
tracer.Reset()
|
||||
span = tracer.StartSpan("test-trace-server")
|
||||
err = status.Error(code, "")
|
||||
SetSpanTags(span, err, false)
|
||||
span.Finish()
|
||||
|
||||
// Assert added tags
|
||||
rawSpan = tracer.FinishedSpans()[0]
|
||||
expectedTags = map[string]interface{}{
|
||||
"response_code": code,
|
||||
"response_class": ErrorClass(err),
|
||||
}
|
||||
if err != nil && ErrorClass(err) == ServerError {
|
||||
expectedTags["error"] = true
|
||||
}
|
||||
assert.Equal(t, expectedTags, rawSpan.Tags())
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go
generated
vendored
6
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go
generated
vendored
@@ -33,7 +33,7 @@ func OpenTracingServerInterceptor(tracer opentracing.Tracer, optFuncs ...Option)
|
||||
info *grpc.UnaryServerInfo,
|
||||
handler grpc.UnaryHandler,
|
||||
) (resp interface{}, err error) {
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
md = metadata.New(nil)
|
||||
}
|
||||
@@ -64,8 +64,8 @@ func OpenTracingServerInterceptor(tracer opentracing.Tracer, optFuncs ...Option)
|
||||
serverSpan.LogFields(log.Object("gRPC response", resp))
|
||||
}
|
||||
} else {
|
||||
ext.Error.Set(serverSpan, true)
|
||||
serverSpan.LogFields(log.String("event", "gRPC error"), log.Error(err))
|
||||
SetSpanTags(serverSpan, err, false)
|
||||
serverSpan.LogFields(log.String("event", "error"), log.String("message", err.Error()))
|
||||
}
|
||||
if otgrpcOpts.decorator != nil {
|
||||
otgrpcOpts.decorator(serverSpan, info.FullMethod, req, resp, err)
|
||||
|
||||
6
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go
generated
vendored
6
vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go
generated
vendored
@@ -32,11 +32,7 @@ func (w metadataReaderWriter) Set(key, val string) {
|
||||
func (w metadataReaderWriter) ForeachKey(handler func(key, val string) error) error {
|
||||
for k, vals := range w.MD {
|
||||
for _, v := range vals {
|
||||
if dk, dv, err := metadata.DecodeKeyValue(k, v); err == nil {
|
||||
if err = handler(dk, dv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := handler(k, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
57
vendor/github.com/juju/ratelimit/ratelimit.go
generated
vendored
57
vendor/github.com/juju/ratelimit/ratelimit.go
generated
vendored
@@ -21,6 +21,7 @@ type Bucket struct {
|
||||
capacity int64
|
||||
quantum int64
|
||||
fillInterval time.Duration
|
||||
clock Clock
|
||||
|
||||
// The mutex guards the fields following it.
|
||||
mu sync.Mutex
|
||||
@@ -33,12 +34,37 @@ type Bucket struct {
|
||||
availTick int64
|
||||
}
|
||||
|
||||
// Clock is used to inject testable fakes.
|
||||
type Clock interface {
|
||||
Now() time.Time
|
||||
Sleep(d time.Duration)
|
||||
}
|
||||
|
||||
// realClock implements Clock in terms of standard time functions.
|
||||
type realClock struct{}
|
||||
|
||||
// Now is identical to time.Now.
|
||||
func (realClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// Sleep is identical to time.Sleep.
|
||||
func (realClock) Sleep(d time.Duration) {
|
||||
time.Sleep(d)
|
||||
}
|
||||
|
||||
// NewBucket returns a new token bucket that fills at the
|
||||
// rate of one token every fillInterval, up to the given
|
||||
// maximum capacity. Both arguments must be
|
||||
// positive. The bucket is initially full.
|
||||
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket {
|
||||
return NewBucketWithQuantum(fillInterval, capacity, 1)
|
||||
return NewBucketWithClock(fillInterval, capacity, realClock{})
|
||||
}
|
||||
|
||||
// NewBucketWithClock is identical to NewBucket but injects a testable clock
|
||||
// interface.
|
||||
func NewBucketWithClock(fillInterval time.Duration, capacity int64, clock Clock) *Bucket {
|
||||
return NewBucketWithQuantumAndClock(fillInterval, capacity, 1, clock)
|
||||
}
|
||||
|
||||
// rateMargin specifes the allowed variance of actual
|
||||
@@ -51,12 +77,18 @@ const rateMargin = 0.01
|
||||
// at high rates, the actual rate may be up to 1% different from the
|
||||
// specified rate.
|
||||
func NewBucketWithRate(rate float64, capacity int64) *Bucket {
|
||||
return NewBucketWithRateAndClock(rate, capacity, realClock{})
|
||||
}
|
||||
|
||||
// NewBucketWithRateAndClock is identical to NewBucketWithRate but injects a
|
||||
// testable clock interface.
|
||||
func NewBucketWithRateAndClock(rate float64, capacity int64, clock Clock) *Bucket {
|
||||
for quantum := int64(1); quantum < 1<<50; quantum = nextQuantum(quantum) {
|
||||
fillInterval := time.Duration(1e9 * float64(quantum) / rate)
|
||||
if fillInterval <= 0 {
|
||||
continue
|
||||
}
|
||||
tb := NewBucketWithQuantum(fillInterval, capacity, quantum)
|
||||
tb := NewBucketWithQuantumAndClock(fillInterval, capacity, quantum, clock)
|
||||
if diff := math.Abs(tb.Rate() - rate); diff/rate <= rateMargin {
|
||||
return tb
|
||||
}
|
||||
@@ -79,6 +111,12 @@ func nextQuantum(q int64) int64 {
|
||||
// the specification of the quantum size - quantum tokens
|
||||
// are added every fillInterval.
|
||||
func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *Bucket {
|
||||
return NewBucketWithQuantumAndClock(fillInterval, capacity, quantum, realClock{})
|
||||
}
|
||||
|
||||
// NewBucketWithQuantumAndClock is identical to NewBucketWithQuantum but injects
|
||||
// a testable clock interface.
|
||||
func NewBucketWithQuantumAndClock(fillInterval time.Duration, capacity, quantum int64, clock Clock) *Bucket {
|
||||
if fillInterval <= 0 {
|
||||
panic("token bucket fill interval is not > 0")
|
||||
}
|
||||
@@ -89,7 +127,8 @@ func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *
|
||||
panic("token bucket quantum is not > 0")
|
||||
}
|
||||
return &Bucket{
|
||||
startTime: time.Now(),
|
||||
clock: clock,
|
||||
startTime: clock.Now(),
|
||||
capacity: capacity,
|
||||
quantum: quantum,
|
||||
avail: capacity,
|
||||
@@ -101,7 +140,7 @@ func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *
|
||||
// available.
|
||||
func (tb *Bucket) Wait(count int64) {
|
||||
if d := tb.Take(count); d > 0 {
|
||||
time.Sleep(d)
|
||||
tb.clock.Sleep(d)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +152,7 @@ func (tb *Bucket) Wait(count int64) {
|
||||
func (tb *Bucket) WaitMaxDuration(count int64, maxWait time.Duration) bool {
|
||||
d, ok := tb.TakeMaxDuration(count, maxWait)
|
||||
if d > 0 {
|
||||
time.Sleep(d)
|
||||
tb.clock.Sleep(d)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
@@ -127,7 +166,7 @@ const infinityDuration time.Duration = 0x7fffffffffffffff
|
||||
// Note that if the request is irrevocable - there is no way to return
|
||||
// tokens to the bucket once this method commits us to taking them.
|
||||
func (tb *Bucket) Take(count int64) time.Duration {
|
||||
d, _ := tb.take(time.Now(), count, infinityDuration)
|
||||
d, _ := tb.take(tb.clock.Now(), count, infinityDuration)
|
||||
return d
|
||||
}
|
||||
|
||||
@@ -141,14 +180,14 @@ func (tb *Bucket) Take(count int64) time.Duration {
|
||||
// wait until the tokens are actually available, and reports
|
||||
// true.
|
||||
func (tb *Bucket) TakeMaxDuration(count int64, maxWait time.Duration) (time.Duration, bool) {
|
||||
return tb.take(time.Now(), count, maxWait)
|
||||
return tb.take(tb.clock.Now(), count, maxWait)
|
||||
}
|
||||
|
||||
// TakeAvailable takes up to count immediately available tokens from the
|
||||
// bucket. It returns the number of tokens removed, or zero if there are
|
||||
// no available tokens. It does not block.
|
||||
func (tb *Bucket) TakeAvailable(count int64) int64 {
|
||||
return tb.takeAvailable(time.Now(), count)
|
||||
return tb.takeAvailable(tb.clock.Now(), count)
|
||||
}
|
||||
|
||||
// takeAvailable is the internal version of TakeAvailable - it takes the
|
||||
@@ -178,7 +217,7 @@ func (tb *Bucket) takeAvailable(now time.Time, count int64) int64 {
|
||||
// tokens could have changed in the meantime. This method is intended
|
||||
// primarily for metrics reporting and debugging.
|
||||
func (tb *Bucket) Available() int64 {
|
||||
return tb.available(time.Now())
|
||||
return tb.available(tb.clock.Now())
|
||||
}
|
||||
|
||||
// available is the internal version of available - it takes the current time as
|
||||
|
||||
24
vendor/github.com/klauspost/crc32/.gitignore
generated
vendored
24
vendor/github.com/klauspost/crc32/.gitignore
generated
vendored
@@ -1,24 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
13
vendor/github.com/klauspost/crc32/.travis.yml
generated
vendored
13
vendor/github.com/klauspost/crc32/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v .
|
||||
- go test -v -race .
|
||||
28
vendor/github.com/klauspost/crc32/LICENSE
generated
vendored
28
vendor/github.com/klauspost/crc32/LICENSE
generated
vendored
@@ -1,28 +0,0 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
Copyright (c) 2015 Klaus Post
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
87
vendor/github.com/klauspost/crc32/README.md
generated
vendored
87
vendor/github.com/klauspost/crc32/README.md
generated
vendored
@@ -1,87 +0,0 @@
|
||||
# crc32
|
||||
CRC32 hash with x64 optimizations
|
||||
|
||||
This package is a drop-in replacement for the standard library `hash/crc32` package, that features SSE 4.2 optimizations on x64 platforms, for a 10x speedup.
|
||||
|
||||
[](https://travis-ci.org/klauspost/crc32)
|
||||
|
||||
# usage
|
||||
|
||||
Install using `go get github.com/klauspost/crc32`. This library is based on Go 1.5 code and requires Go 1.3 or newer.
|
||||
|
||||
Replace `import "hash/crc32"` with `import "github.com/klauspost/crc32"` and you are good to go.
|
||||
|
||||
# changes
|
||||
* Oct 20, 2016: Changes have been merged to upstream Go. Package updated to match.
|
||||
* Dec 4, 2015: Uses the "slice-by-8" trick more extensively, which gives a 1.5 to 2.5x speedup if assembler is unavailable.
|
||||
|
||||
|
||||
# performance
|
||||
|
||||
For *Go 1.7* performance is equivalent to the standard library. So if you use this package for Go 1.7 you can switch back.
|
||||
|
||||
|
||||
For IEEE tables (the most common), there is approximately a factor 10 speedup with "CLMUL" (Carryless multiplication) instruction:
|
||||
```
|
||||
benchmark old ns/op new ns/op delta
|
||||
BenchmarkCrc32KB 99955 10258 -89.74%
|
||||
|
||||
benchmark old MB/s new MB/s speedup
|
||||
BenchmarkCrc32KB 327.83 3194.20 9.74x
|
||||
```
|
||||
|
||||
For other tables and "CLMUL" capable machines the performance is the same as the standard library.
|
||||
|
||||
Here are some detailed benchmarks, comparing to go 1.5 standard library with and without assembler enabled.
|
||||
|
||||
```
|
||||
Std: Standard Go 1.5 library
|
||||
Crc: Indicates IEEE type CRC.
|
||||
40B: Size of each slice encoded.
|
||||
NoAsm: Assembler was disabled (ie. not an AMD64 or SSE 4.2+ capable machine).
|
||||
Castagnoli: Castagnoli CRC type.
|
||||
|
||||
BenchmarkStdCrc40B-4 10000000 158 ns/op 252.88 MB/s
|
||||
BenchmarkCrc40BNoAsm-4 20000000 105 ns/op 377.38 MB/s (slice8)
|
||||
BenchmarkCrc40B-4 20000000 105 ns/op 378.77 MB/s (slice8)
|
||||
|
||||
BenchmarkStdCrc1KB-4 500000 3604 ns/op 284.10 MB/s
|
||||
BenchmarkCrc1KBNoAsm-4 1000000 1463 ns/op 699.79 MB/s (slice8)
|
||||
BenchmarkCrc1KB-4 3000000 396 ns/op 2583.69 MB/s (asm)
|
||||
|
||||
BenchmarkStdCrc8KB-4 200000 11417 ns/op 717.48 MB/s (slice8)
|
||||
BenchmarkCrc8KBNoAsm-4 200000 11317 ns/op 723.85 MB/s (slice8)
|
||||
BenchmarkCrc8KB-4 500000 2919 ns/op 2805.73 MB/s (asm)
|
||||
|
||||
BenchmarkStdCrc32KB-4 30000 45749 ns/op 716.24 MB/s (slice8)
|
||||
BenchmarkCrc32KBNoAsm-4 30000 45109 ns/op 726.42 MB/s (slice8)
|
||||
BenchmarkCrc32KB-4 100000 11497 ns/op 2850.09 MB/s (asm)
|
||||
|
||||
BenchmarkStdNoAsmCastagnol40B-4 10000000 161 ns/op 246.94 MB/s
|
||||
BenchmarkStdCastagnoli40B-4 50000000 28.4 ns/op 1410.69 MB/s (asm)
|
||||
BenchmarkCastagnoli40BNoAsm-4 20000000 100 ns/op 398.01 MB/s (slice8)
|
||||
BenchmarkCastagnoli40B-4 50000000 28.2 ns/op 1419.54 MB/s (asm)
|
||||
|
||||
BenchmarkStdNoAsmCastagnoli1KB-4 500000 3622 ns/op 282.67 MB/s
|
||||
BenchmarkStdCastagnoli1KB-4 10000000 144 ns/op 7099.78 MB/s (asm)
|
||||
BenchmarkCastagnoli1KBNoAsm-4 1000000 1475 ns/op 694.14 MB/s (slice8)
|
||||
BenchmarkCastagnoli1KB-4 10000000 146 ns/op 6993.35 MB/s (asm)
|
||||
|
||||
BenchmarkStdNoAsmCastagnoli8KB-4 50000 28781 ns/op 284.63 MB/s
|
||||
BenchmarkStdCastagnoli8KB-4 1000000 1029 ns/op 7957.89 MB/s (asm)
|
||||
BenchmarkCastagnoli8KBNoAsm-4 200000 11410 ns/op 717.94 MB/s (slice8)
|
||||
BenchmarkCastagnoli8KB-4 1000000 1000 ns/op 8188.71 MB/s (asm)
|
||||
|
||||
BenchmarkStdNoAsmCastagnoli32KB-4 10000 115426 ns/op 283.89 MB/s
|
||||
BenchmarkStdCastagnoli32KB-4 300000 4065 ns/op 8059.13 MB/s (asm)
|
||||
BenchmarkCastagnoli32KBNoAsm-4 30000 45171 ns/op 725.41 MB/s (slice8)
|
||||
BenchmarkCastagnoli32KB-4 500000 4077 ns/op 8035.89 MB/s (asm)
|
||||
```
|
||||
|
||||
The IEEE assembler optimizations has been submitted and will be part of the Go 1.6 standard library.
|
||||
|
||||
However, the improved use of slice-by-8 has not, but will probably be submitted for Go 1.7.
|
||||
|
||||
# license
|
||||
|
||||
Standard Go license. Changes are Copyright (c) 2015 Klaus Post under same conditions.
|
||||
207
vendor/github.com/klauspost/crc32/crc32.go
generated
vendored
207
vendor/github.com/klauspost/crc32/crc32.go
generated
vendored
@@ -1,207 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32,
|
||||
// checksum. See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for
|
||||
// information.
|
||||
//
|
||||
// Polynomials are represented in LSB-first form also known as reversed representation.
|
||||
//
|
||||
// See http://en.wikipedia.org/wiki/Mathematics_of_cyclic_redundancy_checks#Reversed_representations_and_reciprocal_polynomials
|
||||
// for information.
|
||||
package crc32
|
||||
|
||||
import (
|
||||
"hash"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// The size of a CRC-32 checksum in bytes.
|
||||
const Size = 4
|
||||
|
||||
// Predefined polynomials.
|
||||
const (
|
||||
// IEEE is by far and away the most common CRC-32 polynomial.
|
||||
// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ...
|
||||
IEEE = 0xedb88320
|
||||
|
||||
// Castagnoli's polynomial, used in iSCSI.
|
||||
// Has better error detection characteristics than IEEE.
|
||||
// http://dx.doi.org/10.1109/26.231911
|
||||
Castagnoli = 0x82f63b78
|
||||
|
||||
// Koopman's polynomial.
|
||||
// Also has better error detection characteristics than IEEE.
|
||||
// http://dx.doi.org/10.1109/DSN.2002.1028931
|
||||
Koopman = 0xeb31d82e
|
||||
)
|
||||
|
||||
// Table is a 256-word table representing the polynomial for efficient processing.
|
||||
type Table [256]uint32
|
||||
|
||||
// This file makes use of functions implemented in architecture-specific files.
|
||||
// The interface that they implement is as follows:
|
||||
//
|
||||
// // archAvailableIEEE reports whether an architecture-specific CRC32-IEEE
|
||||
// // algorithm is available.
|
||||
// archAvailableIEEE() bool
|
||||
//
|
||||
// // archInitIEEE initializes the architecture-specific CRC3-IEEE algorithm.
|
||||
// // It can only be called if archAvailableIEEE() returns true.
|
||||
// archInitIEEE()
|
||||
//
|
||||
// // archUpdateIEEE updates the given CRC32-IEEE. It can only be called if
|
||||
// // archInitIEEE() was previously called.
|
||||
// archUpdateIEEE(crc uint32, p []byte) uint32
|
||||
//
|
||||
// // archAvailableCastagnoli reports whether an architecture-specific
|
||||
// // CRC32-C algorithm is available.
|
||||
// archAvailableCastagnoli() bool
|
||||
//
|
||||
// // archInitCastagnoli initializes the architecture-specific CRC32-C
|
||||
// // algorithm. It can only be called if archAvailableCastagnoli() returns
|
||||
// // true.
|
||||
// archInitCastagnoli()
|
||||
//
|
||||
// // archUpdateCastagnoli updates the given CRC32-C. It can only be called
|
||||
// // if archInitCastagnoli() was previously called.
|
||||
// archUpdateCastagnoli(crc uint32, p []byte) uint32
|
||||
|
||||
// castagnoliTable points to a lazily initialized Table for the Castagnoli
|
||||
// polynomial. MakeTable will always return this value when asked to make a
|
||||
// Castagnoli table so we can compare against it to find when the caller is
|
||||
// using this polynomial.
|
||||
var castagnoliTable *Table
|
||||
var castagnoliTable8 *slicing8Table
|
||||
var castagnoliArchImpl bool
|
||||
var updateCastagnoli func(crc uint32, p []byte) uint32
|
||||
var castagnoliOnce sync.Once
|
||||
|
||||
func castagnoliInit() {
|
||||
castagnoliTable = simpleMakeTable(Castagnoli)
|
||||
castagnoliArchImpl = archAvailableCastagnoli()
|
||||
|
||||
if castagnoliArchImpl {
|
||||
archInitCastagnoli()
|
||||
updateCastagnoli = archUpdateCastagnoli
|
||||
} else {
|
||||
// Initialize the slicing-by-8 table.
|
||||
castagnoliTable8 = slicingMakeTable(Castagnoli)
|
||||
updateCastagnoli = func(crc uint32, p []byte) uint32 {
|
||||
return slicingUpdate(crc, castagnoliTable8, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IEEETable is the table for the IEEE polynomial.
|
||||
var IEEETable = simpleMakeTable(IEEE)
|
||||
|
||||
// ieeeTable8 is the slicing8Table for IEEE
|
||||
var ieeeTable8 *slicing8Table
|
||||
var ieeeArchImpl bool
|
||||
var updateIEEE func(crc uint32, p []byte) uint32
|
||||
var ieeeOnce sync.Once
|
||||
|
||||
func ieeeInit() {
|
||||
ieeeArchImpl = archAvailableIEEE()
|
||||
|
||||
if ieeeArchImpl {
|
||||
archInitIEEE()
|
||||
updateIEEE = archUpdateIEEE
|
||||
} else {
|
||||
// Initialize the slicing-by-8 table.
|
||||
ieeeTable8 = slicingMakeTable(IEEE)
|
||||
updateIEEE = func(crc uint32, p []byte) uint32 {
|
||||
return slicingUpdate(crc, ieeeTable8, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MakeTable returns a Table constructed from the specified polynomial.
|
||||
// The contents of this Table must not be modified.
|
||||
func MakeTable(poly uint32) *Table {
|
||||
switch poly {
|
||||
case IEEE:
|
||||
ieeeOnce.Do(ieeeInit)
|
||||
return IEEETable
|
||||
case Castagnoli:
|
||||
castagnoliOnce.Do(castagnoliInit)
|
||||
return castagnoliTable
|
||||
}
|
||||
return simpleMakeTable(poly)
|
||||
}
|
||||
|
||||
// digest represents the partial evaluation of a checksum.
|
||||
type digest struct {
|
||||
crc uint32
|
||||
tab *Table
|
||||
}
|
||||
|
||||
// New creates a new hash.Hash32 computing the CRC-32 checksum
|
||||
// using the polynomial represented by the Table.
|
||||
// Its Sum method will lay the value out in big-endian byte order.
|
||||
func New(tab *Table) hash.Hash32 {
|
||||
if tab == IEEETable {
|
||||
ieeeOnce.Do(ieeeInit)
|
||||
}
|
||||
return &digest{0, tab}
|
||||
}
|
||||
|
||||
// NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum
|
||||
// using the IEEE polynomial.
|
||||
// Its Sum method will lay the value out in big-endian byte order.
|
||||
func NewIEEE() hash.Hash32 { return New(IEEETable) }
|
||||
|
||||
func (d *digest) Size() int { return Size }
|
||||
|
||||
func (d *digest) BlockSize() int { return 1 }
|
||||
|
||||
func (d *digest) Reset() { d.crc = 0 }
|
||||
|
||||
// Update returns the result of adding the bytes in p to the crc.
|
||||
func Update(crc uint32, tab *Table, p []byte) uint32 {
|
||||
switch tab {
|
||||
case castagnoliTable:
|
||||
return updateCastagnoli(crc, p)
|
||||
case IEEETable:
|
||||
// Unfortunately, because IEEETable is exported, IEEE may be used without a
|
||||
// call to MakeTable. We have to make sure it gets initialized in that case.
|
||||
ieeeOnce.Do(ieeeInit)
|
||||
return updateIEEE(crc, p)
|
||||
default:
|
||||
return simpleUpdate(crc, tab, p)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *digest) Write(p []byte) (n int, err error) {
|
||||
switch d.tab {
|
||||
case castagnoliTable:
|
||||
d.crc = updateCastagnoli(d.crc, p)
|
||||
case IEEETable:
|
||||
// We only create digest objects through New() which takes care of
|
||||
// initialization in this case.
|
||||
d.crc = updateIEEE(d.crc, p)
|
||||
default:
|
||||
d.crc = simpleUpdate(d.crc, d.tab, p)
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (d *digest) Sum32() uint32 { return d.crc }
|
||||
|
||||
func (d *digest) Sum(in []byte) []byte {
|
||||
s := d.Sum32()
|
||||
return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
|
||||
}
|
||||
|
||||
// Checksum returns the CRC-32 checksum of data
|
||||
// using the polynomial represented by the Table.
|
||||
func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, data) }
|
||||
|
||||
// ChecksumIEEE returns the CRC-32 checksum of data
|
||||
// using the IEEE polynomial.
|
||||
func ChecksumIEEE(data []byte) uint32 {
|
||||
ieeeOnce.Do(ieeeInit)
|
||||
return updateIEEE(0, data)
|
||||
}
|
||||
230
vendor/github.com/klauspost/crc32/crc32_amd64.go
generated
vendored
230
vendor/github.com/klauspost/crc32/crc32_amd64.go
generated
vendored
@@ -1,230 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine,!gccgo
|
||||
|
||||
// AMD64-specific hardware-assisted CRC32 algorithms. See crc32.go for a
|
||||
// description of the interface that each architecture-specific file
|
||||
// implements.
|
||||
|
||||
package crc32
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// This file contains the code to call the SSE 4.2 version of the Castagnoli
|
||||
// and IEEE CRC.
|
||||
|
||||
// haveSSE41/haveSSE42/haveCLMUL are defined in crc_amd64.s and use
|
||||
// CPUID to test for SSE 4.1, 4.2 and CLMUL support.
|
||||
func haveSSE41() bool
|
||||
func haveSSE42() bool
|
||||
func haveCLMUL() bool
|
||||
|
||||
// castagnoliSSE42 is defined in crc32_amd64.s and uses the SSE4.2 CRC32
|
||||
// instruction.
|
||||
//go:noescape
|
||||
func castagnoliSSE42(crc uint32, p []byte) uint32
|
||||
|
||||
// castagnoliSSE42Triple is defined in crc32_amd64.s and uses the SSE4.2 CRC32
|
||||
// instruction.
|
||||
//go:noescape
|
||||
func castagnoliSSE42Triple(
|
||||
crcA, crcB, crcC uint32,
|
||||
a, b, c []byte,
|
||||
rounds uint32,
|
||||
) (retA uint32, retB uint32, retC uint32)
|
||||
|
||||
// ieeeCLMUL is defined in crc_amd64.s and uses the PCLMULQDQ
|
||||
// instruction as well as SSE 4.1.
|
||||
//go:noescape
|
||||
func ieeeCLMUL(crc uint32, p []byte) uint32
|
||||
|
||||
var sse42 = haveSSE42()
|
||||
var useFastIEEE = haveCLMUL() && haveSSE41()
|
||||
|
||||
const castagnoliK1 = 168
|
||||
const castagnoliK2 = 1344
|
||||
|
||||
type sse42Table [4]Table
|
||||
|
||||
var castagnoliSSE42TableK1 *sse42Table
|
||||
var castagnoliSSE42TableK2 *sse42Table
|
||||
|
||||
func archAvailableCastagnoli() bool {
|
||||
return sse42
|
||||
}
|
||||
|
||||
func archInitCastagnoli() {
|
||||
if !sse42 {
|
||||
panic("arch-specific Castagnoli not available")
|
||||
}
|
||||
castagnoliSSE42TableK1 = new(sse42Table)
|
||||
castagnoliSSE42TableK2 = new(sse42Table)
|
||||
// See description in updateCastagnoli.
|
||||
// t[0][i] = CRC(i000, O)
|
||||
// t[1][i] = CRC(0i00, O)
|
||||
// t[2][i] = CRC(00i0, O)
|
||||
// t[3][i] = CRC(000i, O)
|
||||
// where O is a sequence of K zeros.
|
||||
var tmp [castagnoliK2]byte
|
||||
for b := 0; b < 4; b++ {
|
||||
for i := 0; i < 256; i++ {
|
||||
val := uint32(i) << uint32(b*8)
|
||||
castagnoliSSE42TableK1[b][i] = castagnoliSSE42(val, tmp[:castagnoliK1])
|
||||
castagnoliSSE42TableK2[b][i] = castagnoliSSE42(val, tmp[:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// castagnoliShift computes the CRC32-C of K1 or K2 zeroes (depending on the
|
||||
// table given) with the given initial crc value. This corresponds to
|
||||
// CRC(crc, O) in the description in updateCastagnoli.
|
||||
func castagnoliShift(table *sse42Table, crc uint32) uint32 {
|
||||
return table[3][crc>>24] ^
|
||||
table[2][(crc>>16)&0xFF] ^
|
||||
table[1][(crc>>8)&0xFF] ^
|
||||
table[0][crc&0xFF]
|
||||
}
|
||||
|
||||
func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
|
||||
if !sse42 {
|
||||
panic("not available")
|
||||
}
|
||||
|
||||
// This method is inspired from the algorithm in Intel's white paper:
|
||||
// "Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction"
|
||||
// The same strategy of splitting the buffer in three is used but the
|
||||
// combining calculation is different; the complete derivation is explained
|
||||
// below.
|
||||
//
|
||||
// -- The basic idea --
|
||||
//
|
||||
// The CRC32 instruction (available in SSE4.2) can process 8 bytes at a
|
||||
// time. In recent Intel architectures the instruction takes 3 cycles;
|
||||
// however the processor can pipeline up to three instructions if they
|
||||
// don't depend on each other.
|
||||
//
|
||||
// Roughly this means that we can process three buffers in about the same
|
||||
// time we can process one buffer.
|
||||
//
|
||||
// The idea is then to split the buffer in three, CRC the three pieces
|
||||
// separately and then combine the results.
|
||||
//
|
||||
// Combining the results requires precomputed tables, so we must choose a
|
||||
// fixed buffer length to optimize. The longer the length, the faster; but
|
||||
// only buffers longer than this length will use the optimization. We choose
|
||||
// two cutoffs and compute tables for both:
|
||||
// - one around 512: 168*3=504
|
||||
// - one around 4KB: 1344*3=4032
|
||||
//
|
||||
// -- The nitty gritty --
|
||||
//
|
||||
// Let CRC(I, X) be the non-inverted CRC32-C of the sequence X (with
|
||||
// initial non-inverted CRC I). This function has the following properties:
|
||||
// (a) CRC(I, AB) = CRC(CRC(I, A), B)
|
||||
// (b) CRC(I, A xor B) = CRC(I, A) xor CRC(0, B)
|
||||
//
|
||||
// Say we want to compute CRC(I, ABC) where A, B, C are three sequences of
|
||||
// K bytes each, where K is a fixed constant. Let O be the sequence of K zero
|
||||
// bytes.
|
||||
//
|
||||
// CRC(I, ABC) = CRC(I, ABO xor C)
|
||||
// = CRC(I, ABO) xor CRC(0, C)
|
||||
// = CRC(CRC(I, AB), O) xor CRC(0, C)
|
||||
// = CRC(CRC(I, AO xor B), O) xor CRC(0, C)
|
||||
// = CRC(CRC(I, AO) xor CRC(0, B), O) xor CRC(0, C)
|
||||
// = CRC(CRC(CRC(I, A), O) xor CRC(0, B), O) xor CRC(0, C)
|
||||
//
|
||||
// The castagnoliSSE42Triple function can compute CRC(I, A), CRC(0, B),
|
||||
// and CRC(0, C) efficiently. We just need to find a way to quickly compute
|
||||
// CRC(uvwx, O) given a 4-byte initial value uvwx. We can precompute these
|
||||
// values; since we can't have a 32-bit table, we break it up into four
|
||||
// 8-bit tables:
|
||||
//
|
||||
// CRC(uvwx, O) = CRC(u000, O) xor
|
||||
// CRC(0v00, O) xor
|
||||
// CRC(00w0, O) xor
|
||||
// CRC(000x, O)
|
||||
//
|
||||
// We can compute tables corresponding to the four terms for all 8-bit
|
||||
// values.
|
||||
|
||||
crc = ^crc
|
||||
|
||||
// If a buffer is long enough to use the optimization, process the first few
|
||||
// bytes to align the buffer to an 8 byte boundary (if necessary).
|
||||
if len(p) >= castagnoliK1*3 {
|
||||
delta := int(uintptr(unsafe.Pointer(&p[0])) & 7)
|
||||
if delta != 0 {
|
||||
delta = 8 - delta
|
||||
crc = castagnoliSSE42(crc, p[:delta])
|
||||
p = p[delta:]
|
||||
}
|
||||
}
|
||||
|
||||
// Process 3*K2 at a time.
|
||||
for len(p) >= castagnoliK2*3 {
|
||||
// Compute CRC(I, A), CRC(0, B), and CRC(0, C).
|
||||
crcA, crcB, crcC := castagnoliSSE42Triple(
|
||||
crc, 0, 0,
|
||||
p, p[castagnoliK2:], p[castagnoliK2*2:],
|
||||
castagnoliK2/24)
|
||||
|
||||
// CRC(I, AB) = CRC(CRC(I, A), O) xor CRC(0, B)
|
||||
crcAB := castagnoliShift(castagnoliSSE42TableK2, crcA) ^ crcB
|
||||
// CRC(I, ABC) = CRC(CRC(I, AB), O) xor CRC(0, C)
|
||||
crc = castagnoliShift(castagnoliSSE42TableK2, crcAB) ^ crcC
|
||||
p = p[castagnoliK2*3:]
|
||||
}
|
||||
|
||||
// Process 3*K1 at a time.
|
||||
for len(p) >= castagnoliK1*3 {
|
||||
// Compute CRC(I, A), CRC(0, B), and CRC(0, C).
|
||||
crcA, crcB, crcC := castagnoliSSE42Triple(
|
||||
crc, 0, 0,
|
||||
p, p[castagnoliK1:], p[castagnoliK1*2:],
|
||||
castagnoliK1/24)
|
||||
|
||||
// CRC(I, AB) = CRC(CRC(I, A), O) xor CRC(0, B)
|
||||
crcAB := castagnoliShift(castagnoliSSE42TableK1, crcA) ^ crcB
|
||||
// CRC(I, ABC) = CRC(CRC(I, AB), O) xor CRC(0, C)
|
||||
crc = castagnoliShift(castagnoliSSE42TableK1, crcAB) ^ crcC
|
||||
p = p[castagnoliK1*3:]
|
||||
}
|
||||
|
||||
// Use the simple implementation for what's left.
|
||||
crc = castagnoliSSE42(crc, p)
|
||||
return ^crc
|
||||
}
|
||||
|
||||
func archAvailableIEEE() bool {
|
||||
return useFastIEEE
|
||||
}
|
||||
|
||||
var archIeeeTable8 *slicing8Table
|
||||
|
||||
func archInitIEEE() {
|
||||
if !useFastIEEE {
|
||||
panic("not available")
|
||||
}
|
||||
// We still use slicing-by-8 for small buffers.
|
||||
archIeeeTable8 = slicingMakeTable(IEEE)
|
||||
}
|
||||
|
||||
func archUpdateIEEE(crc uint32, p []byte) uint32 {
|
||||
if !useFastIEEE {
|
||||
panic("not available")
|
||||
}
|
||||
|
||||
if len(p) >= 64 {
|
||||
left := len(p) & 15
|
||||
do := len(p) - left
|
||||
crc = ^ieeeCLMUL(^crc, p[:do])
|
||||
p = p[do:]
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return crc
|
||||
}
|
||||
return slicingUpdate(crc, archIeeeTable8, p)
|
||||
}
|
||||
319
vendor/github.com/klauspost/crc32/crc32_amd64.s
generated
vendored
319
vendor/github.com/klauspost/crc32/crc32_amd64.s
generated
vendored
@@ -1,319 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build gc
|
||||
|
||||
#define NOSPLIT 4
|
||||
#define RODATA 8
|
||||
|
||||
// castagnoliSSE42 updates the (non-inverted) crc with the given buffer.
|
||||
//
|
||||
// func castagnoliSSE42(crc uint32, p []byte) uint32
|
||||
TEXT ·castagnoliSSE42(SB), NOSPLIT, $0
|
||||
MOVL crc+0(FP), AX // CRC value
|
||||
MOVQ p+8(FP), SI // data pointer
|
||||
MOVQ p_len+16(FP), CX // len(p)
|
||||
|
||||
// If there are fewer than 8 bytes to process, skip alignment.
|
||||
CMPQ CX, $8
|
||||
JL less_than_8
|
||||
|
||||
MOVQ SI, BX
|
||||
ANDQ $7, BX
|
||||
JZ aligned
|
||||
|
||||
// Process the first few bytes to 8-byte align the input.
|
||||
|
||||
// BX = 8 - BX. We need to process this many bytes to align.
|
||||
SUBQ $1, BX
|
||||
XORQ $7, BX
|
||||
|
||||
BTQ $0, BX
|
||||
JNC align_2
|
||||
|
||||
CRC32B (SI), AX
|
||||
DECQ CX
|
||||
INCQ SI
|
||||
|
||||
align_2:
|
||||
BTQ $1, BX
|
||||
JNC align_4
|
||||
|
||||
// CRC32W (SI), AX
|
||||
BYTE $0x66; BYTE $0xf2; BYTE $0x0f; BYTE $0x38; BYTE $0xf1; BYTE $0x06
|
||||
|
||||
SUBQ $2, CX
|
||||
ADDQ $2, SI
|
||||
|
||||
align_4:
|
||||
BTQ $2, BX
|
||||
JNC aligned
|
||||
|
||||
// CRC32L (SI), AX
|
||||
BYTE $0xf2; BYTE $0x0f; BYTE $0x38; BYTE $0xf1; BYTE $0x06
|
||||
|
||||
SUBQ $4, CX
|
||||
ADDQ $4, SI
|
||||
|
||||
aligned:
|
||||
// The input is now 8-byte aligned and we can process 8-byte chunks.
|
||||
CMPQ CX, $8
|
||||
JL less_than_8
|
||||
|
||||
CRC32Q (SI), AX
|
||||
ADDQ $8, SI
|
||||
SUBQ $8, CX
|
||||
JMP aligned
|
||||
|
||||
less_than_8:
|
||||
// We may have some bytes left over; process 4 bytes, then 2, then 1.
|
||||
BTQ $2, CX
|
||||
JNC less_than_4
|
||||
|
||||
// CRC32L (SI), AX
|
||||
BYTE $0xf2; BYTE $0x0f; BYTE $0x38; BYTE $0xf1; BYTE $0x06
|
||||
ADDQ $4, SI
|
||||
|
||||
less_than_4:
|
||||
BTQ $1, CX
|
||||
JNC less_than_2
|
||||
|
||||
// CRC32W (SI), AX
|
||||
BYTE $0x66; BYTE $0xf2; BYTE $0x0f; BYTE $0x38; BYTE $0xf1; BYTE $0x06
|
||||
ADDQ $2, SI
|
||||
|
||||
less_than_2:
|
||||
BTQ $0, CX
|
||||
JNC done
|
||||
|
||||
CRC32B (SI), AX
|
||||
|
||||
done:
|
||||
MOVL AX, ret+32(FP)
|
||||
RET
|
||||
|
||||
// castagnoliSSE42Triple updates three (non-inverted) crcs with (24*rounds)
|
||||
// bytes from each buffer.
|
||||
//
|
||||
// func castagnoliSSE42Triple(
|
||||
// crc1, crc2, crc3 uint32,
|
||||
// a, b, c []byte,
|
||||
// rounds uint32,
|
||||
// ) (retA uint32, retB uint32, retC uint32)
|
||||
TEXT ·castagnoliSSE42Triple(SB), NOSPLIT, $0
|
||||
MOVL crcA+0(FP), AX
|
||||
MOVL crcB+4(FP), CX
|
||||
MOVL crcC+8(FP), DX
|
||||
|
||||
MOVQ a+16(FP), R8 // data pointer
|
||||
MOVQ b+40(FP), R9 // data pointer
|
||||
MOVQ c+64(FP), R10 // data pointer
|
||||
|
||||
MOVL rounds+88(FP), R11
|
||||
|
||||
loop:
|
||||
CRC32Q (R8), AX
|
||||
CRC32Q (R9), CX
|
||||
CRC32Q (R10), DX
|
||||
|
||||
CRC32Q 8(R8), AX
|
||||
CRC32Q 8(R9), CX
|
||||
CRC32Q 8(R10), DX
|
||||
|
||||
CRC32Q 16(R8), AX
|
||||
CRC32Q 16(R9), CX
|
||||
CRC32Q 16(R10), DX
|
||||
|
||||
ADDQ $24, R8
|
||||
ADDQ $24, R9
|
||||
ADDQ $24, R10
|
||||
|
||||
DECQ R11
|
||||
JNZ loop
|
||||
|
||||
MOVL AX, retA+96(FP)
|
||||
MOVL CX, retB+100(FP)
|
||||
MOVL DX, retC+104(FP)
|
||||
RET
|
||||
|
||||
// func haveSSE42() bool
|
||||
TEXT ·haveSSE42(SB), NOSPLIT, $0
|
||||
XORQ AX, AX
|
||||
INCL AX
|
||||
CPUID
|
||||
SHRQ $20, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func haveCLMUL() bool
|
||||
TEXT ·haveCLMUL(SB), NOSPLIT, $0
|
||||
XORQ AX, AX
|
||||
INCL AX
|
||||
CPUID
|
||||
SHRQ $1, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func haveSSE41() bool
|
||||
TEXT ·haveSSE41(SB), NOSPLIT, $0
|
||||
XORQ AX, AX
|
||||
INCL AX
|
||||
CPUID
|
||||
SHRQ $19, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// CRC32 polynomial data
|
||||
//
|
||||
// These constants are lifted from the
|
||||
// Linux kernel, since they avoid the costly
|
||||
// PSHUFB 16 byte reversal proposed in the
|
||||
// original Intel paper.
|
||||
DATA r2r1kp<>+0(SB)/8, $0x154442bd4
|
||||
DATA r2r1kp<>+8(SB)/8, $0x1c6e41596
|
||||
DATA r4r3kp<>+0(SB)/8, $0x1751997d0
|
||||
DATA r4r3kp<>+8(SB)/8, $0x0ccaa009e
|
||||
DATA rupolykp<>+0(SB)/8, $0x1db710641
|
||||
DATA rupolykp<>+8(SB)/8, $0x1f7011641
|
||||
DATA r5kp<>+0(SB)/8, $0x163cd6124
|
||||
|
||||
GLOBL r2r1kp<>(SB), RODATA, $16
|
||||
GLOBL r4r3kp<>(SB), RODATA, $16
|
||||
GLOBL rupolykp<>(SB), RODATA, $16
|
||||
GLOBL r5kp<>(SB), RODATA, $8
|
||||
|
||||
// Based on http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
|
||||
// len(p) must be at least 64, and must be a multiple of 16.
|
||||
|
||||
// func ieeeCLMUL(crc uint32, p []byte) uint32
|
||||
TEXT ·ieeeCLMUL(SB), NOSPLIT, $0
|
||||
MOVL crc+0(FP), X0 // Initial CRC value
|
||||
MOVQ p+8(FP), SI // data pointer
|
||||
MOVQ p_len+16(FP), CX // len(p)
|
||||
|
||||
MOVOU (SI), X1
|
||||
MOVOU 16(SI), X2
|
||||
MOVOU 32(SI), X3
|
||||
MOVOU 48(SI), X4
|
||||
PXOR X0, X1
|
||||
ADDQ $64, SI // buf+=64
|
||||
SUBQ $64, CX // len-=64
|
||||
CMPQ CX, $64 // Less than 64 bytes left
|
||||
JB remain64
|
||||
|
||||
MOVOA r2r1kp<>+0(SB), X0
|
||||
|
||||
loopback64:
|
||||
MOVOA X1, X5
|
||||
MOVOA X2, X6
|
||||
MOVOA X3, X7
|
||||
MOVOA X4, X8
|
||||
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PCLMULQDQ $0, X0, X2
|
||||
PCLMULQDQ $0, X0, X3
|
||||
PCLMULQDQ $0, X0, X4
|
||||
|
||||
// Load next early
|
||||
MOVOU (SI), X11
|
||||
MOVOU 16(SI), X12
|
||||
MOVOU 32(SI), X13
|
||||
MOVOU 48(SI), X14
|
||||
|
||||
PCLMULQDQ $0x11, X0, X5
|
||||
PCLMULQDQ $0x11, X0, X6
|
||||
PCLMULQDQ $0x11, X0, X7
|
||||
PCLMULQDQ $0x11, X0, X8
|
||||
|
||||
PXOR X5, X1
|
||||
PXOR X6, X2
|
||||
PXOR X7, X3
|
||||
PXOR X8, X4
|
||||
|
||||
PXOR X11, X1
|
||||
PXOR X12, X2
|
||||
PXOR X13, X3
|
||||
PXOR X14, X4
|
||||
|
||||
ADDQ $0x40, DI
|
||||
ADDQ $64, SI // buf+=64
|
||||
SUBQ $64, CX // len-=64
|
||||
CMPQ CX, $64 // Less than 64 bytes left?
|
||||
JGE loopback64
|
||||
|
||||
// Fold result into a single register (X1)
|
||||
remain64:
|
||||
MOVOA r4r3kp<>+0(SB), X0
|
||||
|
||||
MOVOA X1, X5
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PCLMULQDQ $0x11, X0, X5
|
||||
PXOR X5, X1
|
||||
PXOR X2, X1
|
||||
|
||||
MOVOA X1, X5
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PCLMULQDQ $0x11, X0, X5
|
||||
PXOR X5, X1
|
||||
PXOR X3, X1
|
||||
|
||||
MOVOA X1, X5
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PCLMULQDQ $0x11, X0, X5
|
||||
PXOR X5, X1
|
||||
PXOR X4, X1
|
||||
|
||||
// If there is less than 16 bytes left we are done
|
||||
CMPQ CX, $16
|
||||
JB finish
|
||||
|
||||
// Encode 16 bytes
|
||||
remain16:
|
||||
MOVOU (SI), X10
|
||||
MOVOA X1, X5
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PCLMULQDQ $0x11, X0, X5
|
||||
PXOR X5, X1
|
||||
PXOR X10, X1
|
||||
SUBQ $16, CX
|
||||
ADDQ $16, SI
|
||||
CMPQ CX, $16
|
||||
JGE remain16
|
||||
|
||||
finish:
|
||||
// Fold final result into 32 bits and return it
|
||||
PCMPEQB X3, X3
|
||||
PCLMULQDQ $1, X1, X0
|
||||
PSRLDQ $8, X1
|
||||
PXOR X0, X1
|
||||
|
||||
MOVOA X1, X2
|
||||
MOVQ r5kp<>+0(SB), X0
|
||||
|
||||
// Creates 32 bit mask. Note that we don't care about upper half.
|
||||
PSRLQ $32, X3
|
||||
|
||||
PSRLDQ $4, X2
|
||||
PAND X3, X1
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PXOR X2, X1
|
||||
|
||||
MOVOA rupolykp<>+0(SB), X0
|
||||
|
||||
MOVOA X1, X2
|
||||
PAND X3, X1
|
||||
PCLMULQDQ $0x10, X0, X1
|
||||
PAND X3, X1
|
||||
PCLMULQDQ $0, X0, X1
|
||||
PXOR X2, X1
|
||||
|
||||
// PEXTRD $1, X1, AX (SSE 4.1)
|
||||
BYTE $0x66; BYTE $0x0f; BYTE $0x3a
|
||||
BYTE $0x16; BYTE $0xc8; BYTE $0x01
|
||||
MOVL AX, ret+32(FP)
|
||||
|
||||
RET
|
||||
43
vendor/github.com/klauspost/crc32/crc32_amd64p32.go
generated
vendored
43
vendor/github.com/klauspost/crc32/crc32_amd64p32.go
generated
vendored
@@ -1,43 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine,!gccgo
|
||||
|
||||
package crc32
|
||||
|
||||
// This file contains the code to call the SSE 4.2 version of the Castagnoli
|
||||
// CRC.
|
||||
|
||||
// haveSSE42 is defined in crc32_amd64p32.s and uses CPUID to test for SSE 4.2
|
||||
// support.
|
||||
func haveSSE42() bool
|
||||
|
||||
// castagnoliSSE42 is defined in crc32_amd64p32.s and uses the SSE4.2 CRC32
|
||||
// instruction.
|
||||
//go:noescape
|
||||
func castagnoliSSE42(crc uint32, p []byte) uint32
|
||||
|
||||
var sse42 = haveSSE42()
|
||||
|
||||
func archAvailableCastagnoli() bool {
|
||||
return sse42
|
||||
}
|
||||
|
||||
func archInitCastagnoli() {
|
||||
if !sse42 {
|
||||
panic("not available")
|
||||
}
|
||||
// No initialization necessary.
|
||||
}
|
||||
|
||||
func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
|
||||
if !sse42 {
|
||||
panic("not available")
|
||||
}
|
||||
return castagnoliSSE42(crc, p)
|
||||
}
|
||||
|
||||
func archAvailableIEEE() bool { return false }
|
||||
func archInitIEEE() { panic("not available") }
|
||||
func archUpdateIEEE(crc uint32, p []byte) uint32 { panic("not available") }
|
||||
67
vendor/github.com/klauspost/crc32/crc32_amd64p32.s
generated
vendored
67
vendor/github.com/klauspost/crc32/crc32_amd64p32.s
generated
vendored
@@ -1,67 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build gc
|
||||
|
||||
#define NOSPLIT 4
|
||||
#define RODATA 8
|
||||
|
||||
// func castagnoliSSE42(crc uint32, p []byte) uint32
|
||||
TEXT ·castagnoliSSE42(SB), NOSPLIT, $0
|
||||
MOVL crc+0(FP), AX // CRC value
|
||||
MOVL p+4(FP), SI // data pointer
|
||||
MOVL p_len+8(FP), CX // len(p)
|
||||
|
||||
NOTL AX
|
||||
|
||||
// If there's less than 8 bytes to process, we do it byte-by-byte.
|
||||
CMPQ CX, $8
|
||||
JL cleanup
|
||||
|
||||
// Process individual bytes until the input is 8-byte aligned.
|
||||
startup:
|
||||
MOVQ SI, BX
|
||||
ANDQ $7, BX
|
||||
JZ aligned
|
||||
|
||||
CRC32B (SI), AX
|
||||
DECQ CX
|
||||
INCQ SI
|
||||
JMP startup
|
||||
|
||||
aligned:
|
||||
// The input is now 8-byte aligned and we can process 8-byte chunks.
|
||||
CMPQ CX, $8
|
||||
JL cleanup
|
||||
|
||||
CRC32Q (SI), AX
|
||||
ADDQ $8, SI
|
||||
SUBQ $8, CX
|
||||
JMP aligned
|
||||
|
||||
cleanup:
|
||||
// We may have some bytes left over that we process one at a time.
|
||||
CMPQ CX, $0
|
||||
JE done
|
||||
|
||||
CRC32B (SI), AX
|
||||
INCQ SI
|
||||
DECQ CX
|
||||
JMP cleanup
|
||||
|
||||
done:
|
||||
NOTL AX
|
||||
MOVL AX, ret+16(FP)
|
||||
RET
|
||||
|
||||
// func haveSSE42() bool
|
||||
TEXT ·haveSSE42(SB), NOSPLIT, $0
|
||||
XORQ AX, AX
|
||||
INCL AX
|
||||
CPUID
|
||||
SHRQ $20, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
89
vendor/github.com/klauspost/crc32/crc32_generic.go
generated
vendored
89
vendor/github.com/klauspost/crc32/crc32_generic.go
generated
vendored
@@ -1,89 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file contains CRC32 algorithms that are not specific to any architecture
|
||||
// and don't use hardware acceleration.
|
||||
//
|
||||
// The simple (and slow) CRC32 implementation only uses a 256*4 bytes table.
|
||||
//
|
||||
// The slicing-by-8 algorithm is a faster implementation that uses a bigger
|
||||
// table (8*256*4 bytes).
|
||||
|
||||
package crc32
|
||||
|
||||
// simpleMakeTable allocates and constructs a Table for the specified
|
||||
// polynomial. The table is suitable for use with the simple algorithm
|
||||
// (simpleUpdate).
|
||||
func simpleMakeTable(poly uint32) *Table {
|
||||
t := new(Table)
|
||||
simplePopulateTable(poly, t)
|
||||
return t
|
||||
}
|
||||
|
||||
// simplePopulateTable constructs a Table for the specified polynomial, suitable
|
||||
// for use with simpleUpdate.
|
||||
func simplePopulateTable(poly uint32, t *Table) {
|
||||
for i := 0; i < 256; i++ {
|
||||
crc := uint32(i)
|
||||
for j := 0; j < 8; j++ {
|
||||
if crc&1 == 1 {
|
||||
crc = (crc >> 1) ^ poly
|
||||
} else {
|
||||
crc >>= 1
|
||||
}
|
||||
}
|
||||
t[i] = crc
|
||||
}
|
||||
}
|
||||
|
||||
// simpleUpdate uses the simple algorithm to update the CRC, given a table that
|
||||
// was previously computed using simpleMakeTable.
|
||||
func simpleUpdate(crc uint32, tab *Table, p []byte) uint32 {
|
||||
crc = ^crc
|
||||
for _, v := range p {
|
||||
crc = tab[byte(crc)^v] ^ (crc >> 8)
|
||||
}
|
||||
return ^crc
|
||||
}
|
||||
|
||||
// Use slicing-by-8 when payload >= this value.
|
||||
const slicing8Cutoff = 16
|
||||
|
||||
// slicing8Table is array of 8 Tables, used by the slicing-by-8 algorithm.
|
||||
type slicing8Table [8]Table
|
||||
|
||||
// slicingMakeTable constructs a slicing8Table for the specified polynomial. The
|
||||
// table is suitable for use with the slicing-by-8 algorithm (slicingUpdate).
|
||||
func slicingMakeTable(poly uint32) *slicing8Table {
|
||||
t := new(slicing8Table)
|
||||
simplePopulateTable(poly, &t[0])
|
||||
for i := 0; i < 256; i++ {
|
||||
crc := t[0][i]
|
||||
for j := 1; j < 8; j++ {
|
||||
crc = t[0][crc&0xFF] ^ (crc >> 8)
|
||||
t[j][i] = crc
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// slicingUpdate uses the slicing-by-8 algorithm to update the CRC, given a
|
||||
// table that was previously computed using slicingMakeTable.
|
||||
func slicingUpdate(crc uint32, tab *slicing8Table, p []byte) uint32 {
|
||||
if len(p) >= slicing8Cutoff {
|
||||
crc = ^crc
|
||||
for len(p) > 8 {
|
||||
crc ^= uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
|
||||
crc = tab[0][p[7]] ^ tab[1][p[6]] ^ tab[2][p[5]] ^ tab[3][p[4]] ^
|
||||
tab[4][crc>>24] ^ tab[5][(crc>>16)&0xFF] ^
|
||||
tab[6][(crc>>8)&0xFF] ^ tab[7][crc&0xFF]
|
||||
p = p[8:]
|
||||
}
|
||||
crc = ^crc
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return crc
|
||||
}
|
||||
return simpleUpdate(crc, &tab[0], p)
|
||||
}
|
||||
15
vendor/github.com/klauspost/crc32/crc32_otherarch.go
generated
vendored
15
vendor/github.com/klauspost/crc32/crc32_otherarch.go
generated
vendored
@@ -1,15 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !amd64,!amd64p32,!s390x
|
||||
|
||||
package crc32
|
||||
|
||||
func archAvailableIEEE() bool { return false }
|
||||
func archInitIEEE() { panic("not available") }
|
||||
func archUpdateIEEE(crc uint32, p []byte) uint32 { panic("not available") }
|
||||
|
||||
func archAvailableCastagnoli() bool { return false }
|
||||
func archInitCastagnoli() { panic("not available") }
|
||||
func archUpdateCastagnoli(crc uint32, p []byte) uint32 { panic("not available") }
|
||||
91
vendor/github.com/klauspost/crc32/crc32_s390x.go
generated
vendored
91
vendor/github.com/klauspost/crc32/crc32_s390x.go
generated
vendored
@@ -1,91 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build s390x
|
||||
|
||||
package crc32
|
||||
|
||||
const (
|
||||
vxMinLen = 64
|
||||
vxAlignMask = 15 // align to 16 bytes
|
||||
)
|
||||
|
||||
// hasVectorFacility reports whether the machine has the z/Architecture
|
||||
// vector facility installed and enabled.
|
||||
func hasVectorFacility() bool
|
||||
|
||||
var hasVX = hasVectorFacility()
|
||||
|
||||
// vectorizedCastagnoli implements CRC32 using vector instructions.
|
||||
// It is defined in crc32_s390x.s.
|
||||
//go:noescape
|
||||
func vectorizedCastagnoli(crc uint32, p []byte) uint32
|
||||
|
||||
// vectorizedIEEE implements CRC32 using vector instructions.
|
||||
// It is defined in crc32_s390x.s.
|
||||
//go:noescape
|
||||
func vectorizedIEEE(crc uint32, p []byte) uint32
|
||||
|
||||
func archAvailableCastagnoli() bool {
|
||||
return hasVX
|
||||
}
|
||||
|
||||
var archCastagnoliTable8 *slicing8Table
|
||||
|
||||
func archInitCastagnoli() {
|
||||
if !hasVX {
|
||||
panic("not available")
|
||||
}
|
||||
// We still use slicing-by-8 for small buffers.
|
||||
archCastagnoliTable8 = slicingMakeTable(Castagnoli)
|
||||
}
|
||||
|
||||
// archUpdateCastagnoli calculates the checksum of p using
|
||||
// vectorizedCastagnoli.
|
||||
func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
|
||||
if !hasVX {
|
||||
panic("not available")
|
||||
}
|
||||
// Use vectorized function if data length is above threshold.
|
||||
if len(p) >= vxMinLen {
|
||||
aligned := len(p) & ^vxAlignMask
|
||||
crc = vectorizedCastagnoli(crc, p[:aligned])
|
||||
p = p[aligned:]
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return crc
|
||||
}
|
||||
return slicingUpdate(crc, archCastagnoliTable8, p)
|
||||
}
|
||||
|
||||
func archAvailableIEEE() bool {
|
||||
return hasVX
|
||||
}
|
||||
|
||||
var archIeeeTable8 *slicing8Table
|
||||
|
||||
func archInitIEEE() {
|
||||
if !hasVX {
|
||||
panic("not available")
|
||||
}
|
||||
// We still use slicing-by-8 for small buffers.
|
||||
archIeeeTable8 = slicingMakeTable(IEEE)
|
||||
}
|
||||
|
||||
// archUpdateIEEE calculates the checksum of p using vectorizedIEEE.
|
||||
func archUpdateIEEE(crc uint32, p []byte) uint32 {
|
||||
if !hasVX {
|
||||
panic("not available")
|
||||
}
|
||||
// Use vectorized function if data length is above threshold.
|
||||
if len(p) >= vxMinLen {
|
||||
aligned := len(p) & ^vxAlignMask
|
||||
crc = vectorizedIEEE(crc, p[:aligned])
|
||||
p = p[aligned:]
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return crc
|
||||
}
|
||||
return slicingUpdate(crc, archIeeeTable8, p)
|
||||
}
|
||||
249
vendor/github.com/klauspost/crc32/crc32_s390x.s
generated
vendored
249
vendor/github.com/klauspost/crc32/crc32_s390x.s
generated
vendored
@@ -1,249 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build s390x
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Vector register range containing CRC-32 constants
|
||||
|
||||
#define CONST_PERM_LE2BE V9
|
||||
#define CONST_R2R1 V10
|
||||
#define CONST_R4R3 V11
|
||||
#define CONST_R5 V12
|
||||
#define CONST_RU_POLY V13
|
||||
#define CONST_CRC_POLY V14
|
||||
|
||||
// The CRC-32 constant block contains reduction constants to fold and
|
||||
// process particular chunks of the input data stream in parallel.
|
||||
//
|
||||
// Note that the constant definitions below are extended in order to compute
|
||||
// intermediate results with a single VECTOR GALOIS FIELD MULTIPLY instruction.
|
||||
// The rightmost doubleword can be 0 to prevent contribution to the result or
|
||||
// can be multiplied by 1 to perform an XOR without the need for a separate
|
||||
// VECTOR EXCLUSIVE OR instruction.
|
||||
//
|
||||
// The polynomials used are bit-reflected:
|
||||
//
|
||||
// IEEE: P'(x) = 0x0edb88320
|
||||
// Castagnoli: P'(x) = 0x082f63b78
|
||||
|
||||
// IEEE polynomial constants
|
||||
DATA ·crcleconskp+0(SB)/8, $0x0F0E0D0C0B0A0908 // LE-to-BE mask
|
||||
DATA ·crcleconskp+8(SB)/8, $0x0706050403020100
|
||||
DATA ·crcleconskp+16(SB)/8, $0x00000001c6e41596 // R2
|
||||
DATA ·crcleconskp+24(SB)/8, $0x0000000154442bd4 // R1
|
||||
DATA ·crcleconskp+32(SB)/8, $0x00000000ccaa009e // R4
|
||||
DATA ·crcleconskp+40(SB)/8, $0x00000001751997d0 // R3
|
||||
DATA ·crcleconskp+48(SB)/8, $0x0000000000000000
|
||||
DATA ·crcleconskp+56(SB)/8, $0x0000000163cd6124 // R5
|
||||
DATA ·crcleconskp+64(SB)/8, $0x0000000000000000
|
||||
DATA ·crcleconskp+72(SB)/8, $0x00000001F7011641 // u'
|
||||
DATA ·crcleconskp+80(SB)/8, $0x0000000000000000
|
||||
DATA ·crcleconskp+88(SB)/8, $0x00000001DB710641 // P'(x) << 1
|
||||
|
||||
GLOBL ·crcleconskp(SB), RODATA, $144
|
||||
|
||||
// Castagonli Polynomial constants
|
||||
DATA ·crccleconskp+0(SB)/8, $0x0F0E0D0C0B0A0908 // LE-to-BE mask
|
||||
DATA ·crccleconskp+8(SB)/8, $0x0706050403020100
|
||||
DATA ·crccleconskp+16(SB)/8, $0x000000009e4addf8 // R2
|
||||
DATA ·crccleconskp+24(SB)/8, $0x00000000740eef02 // R1
|
||||
DATA ·crccleconskp+32(SB)/8, $0x000000014cd00bd6 // R4
|
||||
DATA ·crccleconskp+40(SB)/8, $0x00000000f20c0dfe // R3
|
||||
DATA ·crccleconskp+48(SB)/8, $0x0000000000000000
|
||||
DATA ·crccleconskp+56(SB)/8, $0x00000000dd45aab8 // R5
|
||||
DATA ·crccleconskp+64(SB)/8, $0x0000000000000000
|
||||
DATA ·crccleconskp+72(SB)/8, $0x00000000dea713f1 // u'
|
||||
DATA ·crccleconskp+80(SB)/8, $0x0000000000000000
|
||||
DATA ·crccleconskp+88(SB)/8, $0x0000000105ec76f0 // P'(x) << 1
|
||||
|
||||
GLOBL ·crccleconskp(SB), RODATA, $144
|
||||
|
||||
// func hasVectorFacility() bool
|
||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
||||
MOVD $x-24(SP), R1
|
||||
XC $24, 0(R1), 0(R1) // clear the storage
|
||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
||||
WORD $0xB2B01000 // STFLE 0(R1)
|
||||
XOR R0, R0 // reset the value of R0
|
||||
MOVBZ z-8(SP), R1
|
||||
AND $0x40, R1
|
||||
BEQ novector
|
||||
|
||||
vectorinstalled:
|
||||
// check if the vector instruction has been enabled
|
||||
VLEIB $0, $0xF, V16
|
||||
VLGVB $0, V16, R1
|
||||
CMPBNE R1, $0xF, novector
|
||||
MOVB $1, ret+0(FP) // have vx
|
||||
RET
|
||||
|
||||
novector:
|
||||
MOVB $0, ret+0(FP) // no vx
|
||||
RET
|
||||
|
||||
// The CRC-32 function(s) use these calling conventions:
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// R2: Initial CRC value, typically ~0; and final CRC (return) value.
|
||||
// R3: Input buffer pointer, performance might be improved if the
|
||||
// buffer is on a doubleword boundary.
|
||||
// R4: Length of the buffer, must be 64 bytes or greater.
|
||||
//
|
||||
// Register usage:
|
||||
//
|
||||
// R5: CRC-32 constant pool base pointer.
|
||||
// V0: Initial CRC value and intermediate constants and results.
|
||||
// V1..V4: Data for CRC computation.
|
||||
// V5..V8: Next data chunks that are fetched from the input buffer.
|
||||
//
|
||||
// V9..V14: CRC-32 constants.
|
||||
|
||||
// func vectorizedIEEE(crc uint32, p []byte) uint32
|
||||
TEXT ·vectorizedIEEE(SB), NOSPLIT, $0
|
||||
MOVWZ crc+0(FP), R2 // R2 stores the CRC value
|
||||
MOVD p+8(FP), R3 // data pointer
|
||||
MOVD p_len+16(FP), R4 // len(p)
|
||||
|
||||
MOVD $·crcleconskp(SB), R5
|
||||
BR vectorizedBody<>(SB)
|
||||
|
||||
// func vectorizedCastagnoli(crc uint32, p []byte) uint32
|
||||
TEXT ·vectorizedCastagnoli(SB), NOSPLIT, $0
|
||||
MOVWZ crc+0(FP), R2 // R2 stores the CRC value
|
||||
MOVD p+8(FP), R3 // data pointer
|
||||
MOVD p_len+16(FP), R4 // len(p)
|
||||
|
||||
// R5: crc-32 constant pool base pointer, constant is used to reduce crc
|
||||
MOVD $·crccleconskp(SB), R5
|
||||
BR vectorizedBody<>(SB)
|
||||
|
||||
TEXT vectorizedBody<>(SB), NOSPLIT, $0
|
||||
XOR $0xffffffff, R2 // NOTW R2
|
||||
VLM 0(R5), CONST_PERM_LE2BE, CONST_CRC_POLY
|
||||
|
||||
// Load the initial CRC value into the rightmost word of V0
|
||||
VZERO V0
|
||||
VLVGF $3, R2, V0
|
||||
|
||||
// Crash if the input size is less than 64-bytes.
|
||||
CMP R4, $64
|
||||
BLT crash
|
||||
|
||||
// Load a 64-byte data chunk and XOR with CRC
|
||||
VLM 0(R3), V1, V4 // 64-bytes into V1..V4
|
||||
|
||||
// Reflect the data if the CRC operation is in the bit-reflected domain
|
||||
VPERM V1, V1, CONST_PERM_LE2BE, V1
|
||||
VPERM V2, V2, CONST_PERM_LE2BE, V2
|
||||
VPERM V3, V3, CONST_PERM_LE2BE, V3
|
||||
VPERM V4, V4, CONST_PERM_LE2BE, V4
|
||||
|
||||
VX V0, V1, V1 // V1 ^= CRC
|
||||
ADD $64, R3 // BUF = BUF + 64
|
||||
ADD $(-64), R4
|
||||
|
||||
// Check remaining buffer size and jump to proper folding method
|
||||
CMP R4, $64
|
||||
BLT less_than_64bytes
|
||||
|
||||
fold_64bytes_loop:
|
||||
// Load the next 64-byte data chunk into V5 to V8
|
||||
VLM 0(R3), V5, V8
|
||||
VPERM V5, V5, CONST_PERM_LE2BE, V5
|
||||
VPERM V6, V6, CONST_PERM_LE2BE, V6
|
||||
VPERM V7, V7, CONST_PERM_LE2BE, V7
|
||||
VPERM V8, V8, CONST_PERM_LE2BE, V8
|
||||
|
||||
// Perform a GF(2) multiplication of the doublewords in V1 with
|
||||
// the reduction constants in V0. The intermediate result is
|
||||
// then folded (accumulated) with the next data chunk in V5 and
|
||||
// stored in V1. Repeat this step for the register contents
|
||||
// in V2, V3, and V4 respectively.
|
||||
|
||||
VGFMAG CONST_R2R1, V1, V5, V1
|
||||
VGFMAG CONST_R2R1, V2, V6, V2
|
||||
VGFMAG CONST_R2R1, V3, V7, V3
|
||||
VGFMAG CONST_R2R1, V4, V8, V4
|
||||
|
||||
// Adjust buffer pointer and length for next loop
|
||||
ADD $64, R3 // BUF = BUF + 64
|
||||
ADD $(-64), R4 // LEN = LEN - 64
|
||||
|
||||
CMP R4, $64
|
||||
BGE fold_64bytes_loop
|
||||
|
||||
less_than_64bytes:
|
||||
// Fold V1 to V4 into a single 128-bit value in V1
|
||||
VGFMAG CONST_R4R3, V1, V2, V1
|
||||
VGFMAG CONST_R4R3, V1, V3, V1
|
||||
VGFMAG CONST_R4R3, V1, V4, V1
|
||||
|
||||
// Check whether to continue with 64-bit folding
|
||||
CMP R4, $16
|
||||
BLT final_fold
|
||||
|
||||
fold_16bytes_loop:
|
||||
VL 0(R3), V2 // Load next data chunk
|
||||
VPERM V2, V2, CONST_PERM_LE2BE, V2
|
||||
|
||||
VGFMAG CONST_R4R3, V1, V2, V1 // Fold next data chunk
|
||||
|
||||
// Adjust buffer pointer and size for folding next data chunk
|
||||
ADD $16, R3
|
||||
ADD $-16, R4
|
||||
|
||||
// Process remaining data chunks
|
||||
CMP R4, $16
|
||||
BGE fold_16bytes_loop
|
||||
|
||||
final_fold:
|
||||
VLEIB $7, $0x40, V9
|
||||
VSRLB V9, CONST_R4R3, V0
|
||||
VLEIG $0, $1, V0
|
||||
|
||||
VGFMG V0, V1, V1
|
||||
|
||||
VLEIB $7, $0x20, V9 // Shift by words
|
||||
VSRLB V9, V1, V2 // Store remaining bits in V2
|
||||
VUPLLF V1, V1 // Split rightmost doubleword
|
||||
VGFMAG CONST_R5, V1, V2, V1 // V1 = (V1 * R5) XOR V2
|
||||
|
||||
// The input values to the Barret reduction are the degree-63 polynomial
|
||||
// in V1 (R(x)), degree-32 generator polynomial, and the reduction
|
||||
// constant u. The Barret reduction result is the CRC value of R(x) mod
|
||||
// P(x).
|
||||
//
|
||||
// The Barret reduction algorithm is defined as:
|
||||
//
|
||||
// 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u
|
||||
// 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x)
|
||||
// 3. C(x) = R(x) XOR T2(x) mod x^32
|
||||
//
|
||||
// Note: To compensate the division by x^32, use the vector unpack
|
||||
// instruction to move the leftmost word into the leftmost doubleword
|
||||
// of the vector register. The rightmost doubleword is multiplied
|
||||
// with zero to not contribute to the intermedate results.
|
||||
|
||||
// T1(x) = floor( R(x) / x^32 ) GF2MUL u
|
||||
VUPLLF V1, V2
|
||||
VGFMG CONST_RU_POLY, V2, V2
|
||||
|
||||
// Compute the GF(2) product of the CRC polynomial in VO with T1(x) in
|
||||
// V2 and XOR the intermediate result, T2(x), with the value in V1.
|
||||
// The final result is in the rightmost word of V2.
|
||||
|
||||
VUPLLF V2, V2
|
||||
VGFMAG CONST_CRC_POLY, V2, V1, V2
|
||||
|
||||
done:
|
||||
VLGVF $2, V2, R2
|
||||
XOR $0xffffffff, R2 // NOTW R2
|
||||
MOVWZ R2, ret + 32(FP)
|
||||
RET
|
||||
|
||||
crash:
|
||||
MOVD $0, (R0) // input size is less than 64-bytes
|
||||
284
vendor/github.com/klauspost/crc32/crc32_test.go
generated
vendored
284
vendor/github.com/klauspost/crc32/crc32_test.go
generated
vendored
@@ -1,284 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package crc32
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"hash"
|
||||
mrand "math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type test struct {
|
||||
ieee, castagnoli uint32
|
||||
in string
|
||||
}
|
||||
|
||||
var golden = []test{
|
||||
{0x0, 0x0, ""},
|
||||
{0xe8b7be43, 0xc1d04330, "a"},
|
||||
{0x9e83486d, 0xe2a22936, "ab"},
|
||||
{0x352441c2, 0x364b3fb7, "abc"},
|
||||
{0xed82cd11, 0x92c80a31, "abcd"},
|
||||
{0x8587d865, 0xc450d697, "abcde"},
|
||||
{0x4b8e39ef, 0x53bceff1, "abcdef"},
|
||||
{0x312a6aa6, 0xe627f441, "abcdefg"},
|
||||
{0xaeef2a50, 0xa9421b7, "abcdefgh"},
|
||||
{0x8da988af, 0x2ddc99fc, "abcdefghi"},
|
||||
{0x3981703a, 0xe6599437, "abcdefghij"},
|
||||
{0x6b9cdfe7, 0xb2cc01fe, "Discard medicine more than two years old."},
|
||||
{0xc90ef73f, 0xe28207f, "He who has a shady past knows that nice guys finish last."},
|
||||
{0xb902341f, 0xbe93f964, "I wouldn't marry him with a ten foot pole."},
|
||||
{0x42080e8, 0x9e3be0c3, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
|
||||
{0x154c6d11, 0xf505ef04, "The days of the digital watch are numbered. -Tom Stoppard"},
|
||||
{0x4c418325, 0x85d3dc82, "Nepal premier won't resign."},
|
||||
{0x33955150, 0xc5142380, "For every action there is an equal and opposite government program."},
|
||||
{0x26216a4b, 0x75eb77dd, "His money is twice tainted: 'taint yours and 'taint mine."},
|
||||
{0x1abbe45e, 0x91ebe9f7, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
|
||||
{0xc89a94f7, 0xf0b1168e, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
|
||||
{0xab3abe14, 0x572b74e2, "size: a.out: bad magic"},
|
||||
{0xbab102b6, 0x8a58a6d5, "The major problem is with sendmail. -Mark Horton"},
|
||||
{0x999149d7, 0x9c426c50, "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
|
||||
{0x6d52a33c, 0x735400a4, "If the enemy is within range, then so are you."},
|
||||
{0x90631e8d, 0xbec49c95, "It's well we cannot hear the screams/That we create in others' dreams."},
|
||||
{0x78309130, 0xa95a2079, "You remind me of a TV show, but that's all right: I watch it anyway."},
|
||||
{0x7d0a377f, 0xde2e65c5, "C is as portable as Stonehedge!!"},
|
||||
{0x8c79fd79, 0x297a88ed, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
|
||||
{0xa20b7167, 0x66ed1d8b, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
|
||||
{0x8e0bb443, 0xdcded527, "How can you write a big system without C++? -Paul Glick"},
|
||||
}
|
||||
|
||||
// testGoldenIEEE verifies that the given function returns
|
||||
// correct IEEE checksums.
|
||||
func testGoldenIEEE(t *testing.T, crcFunc func(b []byte) uint32) {
|
||||
for _, g := range golden {
|
||||
if crc := crcFunc([]byte(g.in)); crc != g.ieee {
|
||||
t.Errorf("IEEE(%s) = 0x%x want 0x%x", g.in, crc, g.ieee)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testGoldenCastagnoli verifies that the given function returns
|
||||
// correct IEEE checksums.
|
||||
func testGoldenCastagnoli(t *testing.T, crcFunc func(b []byte) uint32) {
|
||||
for _, g := range golden {
|
||||
if crc := crcFunc([]byte(g.in)); crc != g.castagnoli {
|
||||
t.Errorf("Castagnoli(%s) = 0x%x want 0x%x", g.in, crc, g.castagnoli)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testCrossCheck generates random buffers of various lengths and verifies that
|
||||
// the two "update" functions return the same result.
|
||||
func testCrossCheck(t *testing.T, crcFunc1, crcFunc2 func(crc uint32, b []byte) uint32) {
|
||||
// The AMD64 implementation has some cutoffs at lengths 168*3=504 and
|
||||
// 1344*3=4032. We should make sure lengths around these values are in the
|
||||
// list.
|
||||
lengths := []int{0, 1, 2, 3, 4, 5, 10, 16, 50, 100, 128,
|
||||
500, 501, 502, 503, 504, 505, 512, 1000, 1024, 2000,
|
||||
4030, 4031, 4032, 4033, 4036, 4040, 4048, 4096, 5000, 10000}
|
||||
for _, length := range lengths {
|
||||
p := make([]byte, length)
|
||||
_, _ = crand.Read(p)
|
||||
crcInit := uint32(mrand.Int63())
|
||||
crc1 := crcFunc1(crcInit, p)
|
||||
crc2 := crcFunc2(crcInit, p)
|
||||
if crc1 != crc2 {
|
||||
t.Errorf("mismatch: 0x%x vs 0x%x (buffer length %d)", crc1, crc2, length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestSimple tests the simple generic algorithm.
|
||||
func TestSimple(t *testing.T) {
|
||||
tab := simpleMakeTable(IEEE)
|
||||
testGoldenIEEE(t, func(b []byte) uint32 {
|
||||
return simpleUpdate(0, tab, b)
|
||||
})
|
||||
|
||||
tab = simpleMakeTable(Castagnoli)
|
||||
testGoldenCastagnoli(t, func(b []byte) uint32 {
|
||||
return simpleUpdate(0, tab, b)
|
||||
})
|
||||
}
|
||||
|
||||
// TestSimple tests the slicing-by-8 algorithm.
|
||||
func TestSlicing(t *testing.T) {
|
||||
tab := slicingMakeTable(IEEE)
|
||||
testGoldenIEEE(t, func(b []byte) uint32 {
|
||||
return slicingUpdate(0, tab, b)
|
||||
})
|
||||
|
||||
tab = slicingMakeTable(Castagnoli)
|
||||
testGoldenCastagnoli(t, func(b []byte) uint32 {
|
||||
return slicingUpdate(0, tab, b)
|
||||
})
|
||||
|
||||
// Cross-check various polys against the simple algorithm.
|
||||
for _, poly := range []uint32{IEEE, Castagnoli, Koopman, 0xD5828281} {
|
||||
t1 := simpleMakeTable(poly)
|
||||
f1 := func(crc uint32, b []byte) uint32 {
|
||||
return simpleUpdate(crc, t1, b)
|
||||
}
|
||||
t2 := slicingMakeTable(poly)
|
||||
f2 := func(crc uint32, b []byte) uint32 {
|
||||
return slicingUpdate(crc, t2, b)
|
||||
}
|
||||
testCrossCheck(t, f1, f2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArchIEEE(t *testing.T) {
|
||||
if !archAvailableIEEE() {
|
||||
t.Skip("Arch-specific IEEE not available.")
|
||||
}
|
||||
archInitIEEE()
|
||||
slicingTable := slicingMakeTable(IEEE)
|
||||
testCrossCheck(t, archUpdateIEEE, func(crc uint32, b []byte) uint32 {
|
||||
return slicingUpdate(crc, slicingTable, b)
|
||||
})
|
||||
}
|
||||
|
||||
func TestArchCastagnoli(t *testing.T) {
|
||||
if !archAvailableCastagnoli() {
|
||||
t.Skip("Arch-specific Castagnoli not available.")
|
||||
}
|
||||
archInitCastagnoli()
|
||||
slicingTable := slicingMakeTable(Castagnoli)
|
||||
testCrossCheck(t, archUpdateCastagnoli, func(crc uint32, b []byte) uint32 {
|
||||
return slicingUpdate(crc, slicingTable, b)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGolden(t *testing.T) {
|
||||
testGoldenIEEE(t, ChecksumIEEE)
|
||||
|
||||
// Some implementations have special code to deal with misaligned
|
||||
// data; test that as well.
|
||||
for delta := 1; delta <= 7; delta++ {
|
||||
testGoldenIEEE(t, func(b []byte) uint32 {
|
||||
ieee := NewIEEE()
|
||||
d := delta
|
||||
if d >= len(b) {
|
||||
d = len(b)
|
||||
}
|
||||
ieee.Write(b[:d])
|
||||
ieee.Write(b[d:])
|
||||
return ieee.Sum32()
|
||||
})
|
||||
}
|
||||
|
||||
castagnoliTab := MakeTable(Castagnoli)
|
||||
if castagnoliTab == nil {
|
||||
t.Errorf("nil Castagnoli Table")
|
||||
}
|
||||
|
||||
testGoldenCastagnoli(t, func(b []byte) uint32 {
|
||||
castagnoli := New(castagnoliTab)
|
||||
castagnoli.Write(b)
|
||||
return castagnoli.Sum32()
|
||||
})
|
||||
|
||||
// Some implementations have special code to deal with misaligned
|
||||
// data; test that as well.
|
||||
for delta := 1; delta <= 7; delta++ {
|
||||
testGoldenCastagnoli(t, func(b []byte) uint32 {
|
||||
castagnoli := New(castagnoliTab)
|
||||
d := delta
|
||||
if d >= len(b) {
|
||||
d = len(b)
|
||||
}
|
||||
castagnoli.Write(b[:d])
|
||||
castagnoli.Write(b[d:])
|
||||
return castagnoli.Sum32()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIEEECrc40B(b *testing.B) {
|
||||
benchmark(b, NewIEEE(), 40, 0)
|
||||
}
|
||||
|
||||
func BenchmarkIEEECrc1KB(b *testing.B) {
|
||||
benchmark(b, NewIEEE(), 1<<10, 0)
|
||||
}
|
||||
|
||||
func BenchmarkIEEECrc4KB(b *testing.B) {
|
||||
benchmark(b, NewIEEE(), 4<<10, 0)
|
||||
}
|
||||
|
||||
func BenchmarkIEEECrc32KB(b *testing.B) {
|
||||
benchmark(b, NewIEEE(), 32<<10, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc15B(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 15, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc15BMisaligned(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 15, 1)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc40B(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 40, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc40BMisaligned(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 40, 1)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc512(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 512, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc512Misaligned(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 512, 1)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc1KB(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 1<<10, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc1KBMisaligned(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 1<<10, 1)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc4KB(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 4<<10, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc4KBMisaligned(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 4<<10, 1)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc32KB(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 32<<10, 0)
|
||||
}
|
||||
|
||||
func BenchmarkCastagnoliCrc32KBMisaligned(b *testing.B) {
|
||||
benchmark(b, New(MakeTable(Castagnoli)), 32<<10, 1)
|
||||
}
|
||||
|
||||
func benchmark(b *testing.B, h hash.Hash32, n, alignment int64) {
|
||||
b.SetBytes(n)
|
||||
data := make([]byte, n+alignment)
|
||||
data = data[alignment:]
|
||||
for i := range data {
|
||||
data[i] = byte(i)
|
||||
}
|
||||
in := make([]byte, 0, h.Size())
|
||||
|
||||
// Warm up
|
||||
h.Reset()
|
||||
h.Write(data)
|
||||
h.Sum(in)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
h.Reset()
|
||||
h.Write(data)
|
||||
h.Sum(in)
|
||||
}
|
||||
}
|
||||
28
vendor/github.com/klauspost/crc32/example_test.go
generated
vendored
28
vendor/github.com/klauspost/crc32/example_test.go
generated
vendored
@@ -1,28 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package crc32_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
func ExampleMakeTable() {
|
||||
// In this package, the CRC polynomial is represented in reversed notation,
|
||||
// or LSB-first representation.
|
||||
//
|
||||
// LSB-first representation is a hexadecimal number with n bits, in which the
|
||||
// most significant bit represents the coefficient of x⁰ and the least significant
|
||||
// bit represents the coefficient of xⁿ⁻¹ (the coefficient for xⁿ is implicit).
|
||||
//
|
||||
// For example, CRC32-Q, as defined by the following polynomial,
|
||||
// x³²+ x³¹+ x²⁴+ x²²+ x¹⁶+ x¹⁴+ x⁸+ x⁷+ x⁵+ x³+ x¹+ x⁰
|
||||
// has the reversed notation 0b11010101100000101000001010000001, so the value
|
||||
// that should be passed to MakeTable is 0xD5828281.
|
||||
crc32q := crc32.MakeTable(0xD5828281)
|
||||
fmt.Printf("%08x\n", crc32.Checksum([]byte("Hello world"), crc32q))
|
||||
// Output:
|
||||
// 2964d064
|
||||
}
|
||||
4
vendor/github.com/mailru/easyjson/jlexer/lexer.go
generated
vendored
4
vendor/github.com/mailru/easyjson/jlexer/lexer.go
generated
vendored
@@ -582,11 +582,11 @@ func (r *Lexer) Consumed() {
|
||||
|
||||
for _, c := range r.Data[r.pos:] {
|
||||
if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
|
||||
r.fatalError = &LexerError{
|
||||
r.AddError(&LexerError{
|
||||
Reason: "invalid character '" + string(c) + "' after top-level value",
|
||||
Offset: r.pos,
|
||||
Data: string(r.Data[r.pos:]),
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
14
vendor/github.com/mholt/caddy/.gitattributes
generated
vendored
14
vendor/github.com/mholt/caddy/.gitattributes
generated
vendored
@@ -1,14 +0,0 @@
|
||||
# shell scripts should not use tabs to indent!
|
||||
*.bash text eol=lf core.whitespace whitespace=tab-in-indent,trailing-space,tabwidth=2
|
||||
*.sh text eol=lf core.whitespace whitespace=tab-in-indent,trailing-space,tabwidth=2
|
||||
|
||||
# files for systemd (shell-similar)
|
||||
*.path text eol=lf core.whitespace whitespace=tab-in-indent,trailing-space,tabwidth=2
|
||||
*.service text eol=lf core.whitespace whitespace=tab-in-indent,trailing-space,tabwidth=2
|
||||
*.timer text eol=lf core.whitespace whitespace=tab-in-indent,trailing-space,tabwidth=2
|
||||
|
||||
# go fmt will enforce this, but in case a user has not called "go fmt" allow GIT to catch this:
|
||||
*.go text eol=lf core.whitespace whitespace=indent-with-non-tab,trailing-space,tabwidth=4
|
||||
|
||||
*.yml text eol=lf core.whitespace whitespace=tab-in-indent,trailing-space,tabwidth=2
|
||||
.git* text eol=auto core.whitespace whitespace=trailing-space
|
||||
19
vendor/github.com/mholt/caddy/.gitignore
generated
vendored
19
vendor/github.com/mholt/caddy/.gitignore
generated
vendored
@@ -1,19 +0,0 @@
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
_gitignore/
|
||||
Vagrantfile
|
||||
.vagrant/
|
||||
/.idea
|
||||
|
||||
dist/builds/
|
||||
dist/release/
|
||||
|
||||
error.log
|
||||
access.log
|
||||
|
||||
/*.conf
|
||||
Caddyfile
|
||||
|
||||
og_static/
|
||||
|
||||
.vscode/
|
||||
34
vendor/github.com/mholt/caddy/.travis.yml
generated
vendored
34
vendor/github.com/mholt/caddy/.travis.yml
generated
vendored
@@ -1,34 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
# Decrypts a script that installs an authenticated cookie
|
||||
# for git to use when cloning from googlesource.com.
|
||||
# Bypasses "bandwidth limit exceeded" errors.
|
||||
# See github.com/golang/go/issues/12933
|
||||
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then openssl aes-256-cbc -K $encrypted_3df18f9af81d_key -iv $encrypted_3df18f9af81d_iv -in dist/gitcookie.sh.enc -out dist/gitcookie.sh -d; fi
|
||||
|
||||
install:
|
||||
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash dist/gitcookie.sh; fi
|
||||
- go get -t ./...
|
||||
- go get github.com/golang/lint/golint
|
||||
- go get github.com/gordonklaus/ineffassign
|
||||
- go get github.com/client9/misspell/cmd/misspell
|
||||
|
||||
script:
|
||||
- diff <(echo -n) <(gofmt -s -d .)
|
||||
- ineffassign .
|
||||
- misspell -error .
|
||||
- go vet ./...
|
||||
- go test -race ./...
|
||||
|
||||
after_script:
|
||||
- golint ./...
|
||||
117
vendor/github.com/mholt/caddy/CONTRIBUTING.md
generated
vendored
117
vendor/github.com/mholt/caddy/CONTRIBUTING.md
generated
vendored
@@ -1,117 +0,0 @@
|
||||
## Contributing to Caddy
|
||||
|
||||
Welcome! Our community focuses on helping others and making Caddy the best it
|
||||
can be. We gladly accept contributions and encourage you to get involved!
|
||||
|
||||
|
||||
### Join us in the forum
|
||||
|
||||
The [Caddy forum](https://forum.caddyserver.com) is the place for all discussion
|
||||
that doesn't belong in issues or pull requests. Feel free to participate with us!
|
||||
|
||||
If you want to file a bug report or make an improvement to Caddy, however, you
|
||||
should submit an issue or pull request.
|
||||
|
||||
|
||||
### Bug reports
|
||||
|
||||
Please [search this repository](https://github.com/mholt/caddy/search?q=&type=Issues&utf8=%E2%9C%93)
|
||||
with a variety of keywords to ensure your bug is not already reported.
|
||||
|
||||
If unique, [open an issue](https://github.com/mholt/caddy/issues) and answer the
|
||||
questions so we can understand and reproduce the problematic behavior.
|
||||
|
||||
The burden is on you to convince us that it is actually a bug in Caddy. This is
|
||||
easiest to do when you write clear, concise instructions so we can reproduce
|
||||
the behavior (even if it seems obvious). The more detailed and specific you are,
|
||||
the faster we will be able to help you. Check out
|
||||
[How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
|
||||
|
||||
Please be kind. :smile: Remember that Caddy comes at no cost to you, and you're
|
||||
getting free help. If we helped you, please consider
|
||||
[donating](https://caddyserver.com/donate) - it keeps us motivated!
|
||||
|
||||
|
||||
### Minor improvements and new tests
|
||||
|
||||
Submit [pull requests](https://github.com/mholt/caddy/pulls) at any time for
|
||||
minor changes or new tests. Make sure to write tests to assert your change is
|
||||
working properly and is thoroughly covered. We'll ask most pull requests to be
|
||||
[squashed](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html),
|
||||
especially with small commits.
|
||||
|
||||
Your pull request may be thoroughly reviewed. This is because if we accept the
|
||||
PR, we also assume responsibility for it, although we would prefer you to
|
||||
help maintain your code after it gets merged.
|
||||
|
||||
|
||||
### Proposals, suggestions, ideas, new features
|
||||
|
||||
First, please [search](https://github.com/mholt/caddy/search?q=&type=Issues&utf8=%E2%9C%93)
|
||||
with a variety of keywords to ensure your suggestion/proposal is new.
|
||||
|
||||
If so, you may open either an issue or a pull request for discussion and
|
||||
feedback.
|
||||
|
||||
The advantage of issues is that you don't have to spend time implementing your
|
||||
idea, but you should still describe it thoroughly as if someone reading it would
|
||||
implement the whole thing starting from scratch.
|
||||
|
||||
The advantage of pull requests is that we can immediately see the impact the
|
||||
change will have on the project, what the code will look like, and how to
|
||||
improve it. The disadvantage of pull requests is that they are unlikely to get
|
||||
accepted without significant changes first, or it may be rejected entirely.
|
||||
Don't worry, that won't happen without an open discussion first.
|
||||
|
||||
If you are going to spend significant time writing code for a new pull request,
|
||||
best to open an issue to "claim" it and get feedback before you invest a lot of
|
||||
time. Not all pull requests are merged, and that's okay,
|
||||
[Read why.](https://github.com/turbolinks/turbolinks/pull/124#issuecomment-239826060)
|
||||
|
||||
Remember: pull requests should always be thoroughly documented both via godoc
|
||||
and with at least a rough draft of documentation that might go on the website
|
||||
for users to read.
|
||||
|
||||
|
||||
### Collaborator status
|
||||
|
||||
If your pull request is merged, congratulations! You're technically a
|
||||
collaborator. We may also grant you "Collaborator status" which means you can
|
||||
push to the repository and merge other pull requests. We hope that you will
|
||||
stay involved by reviewing pull requests, submitting more of your own, and
|
||||
resolving issues as you are able to. Thanks for making Caddy amazing!
|
||||
|
||||
We ask that collaborators will conduct thorough code reviews and be nice to
|
||||
new contributors. Before merging a PR, it's best to get the approval of
|
||||
at least one or two other collaborators and/or the project owner. We prefer
|
||||
squashed commits instead of many little, semantically-unimportant commits. Also,
|
||||
CI and other post-commit hooks must pass before being merged except in certain
|
||||
unusual circumstances.
|
||||
|
||||
Collaborator status may be removed for inactive users from time to time as
|
||||
we see fit; this is not an insult, just a basic security precaution in case
|
||||
the account becomes inactive or abandoned. Privileges can always be restored
|
||||
later.
|
||||
|
||||
**Reviewing pull requests:** Please help submit and review pull requests as
|
||||
you are able! We would ask that every pull request be reviewed by at least
|
||||
one collaborator who did not open the pull request before merging. This will
|
||||
help ensure high code quality as new collaborators are added to the project.
|
||||
|
||||
Read [CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments)
|
||||
on the Go wiki for an idea of what we look for in good, clean Go code, and
|
||||
check out [what Linus suggests](https://gist.github.com/matthewhudson/1475276)
|
||||
for good commit messages.
|
||||
|
||||
|
||||
|
||||
### Vulnerabilities
|
||||
|
||||
If you've found a vulnerability that is serious, please email me: Matthew dot
|
||||
Holt at Gmail. If it's not a big deal, a pull request will probably be faster.
|
||||
|
||||
|
||||
## Thank you
|
||||
|
||||
Thanks for your help! Caddy would not be what it is today without your
|
||||
contributions.
|
||||
30
vendor/github.com/mholt/caddy/ISSUE_TEMPLATE
generated
vendored
30
vendor/github.com/mholt/caddy/ISSUE_TEMPLATE
generated
vendored
@@ -1,30 +0,0 @@
|
||||
(Are you asking for help with using Caddy? Please use our forum instead: https://forum.caddyserver.com. If you are filing a bug report, please take a few minutes to carefully answer the following questions. If your issue is not a bug report, you do not need to use this template. Thanks!)
|
||||
|
||||
### 1. What version of Caddy are you running (`caddy -version`)?
|
||||
|
||||
|
||||
### 2. What are you trying to do?
|
||||
|
||||
|
||||
### 3. What is your entire Caddyfile?
|
||||
```text
|
||||
(Put Caddyfile here)
|
||||
```
|
||||
|
||||
### 4. How did you run Caddy (give the full command and describe the execution environment)?
|
||||
|
||||
|
||||
### 5. Please paste any relevant HTTP request(s) here.
|
||||
|
||||
(paste curl command, or full HTTP request including headers and body, here)
|
||||
|
||||
|
||||
### 6. What did you expect to see?
|
||||
|
||||
|
||||
### 7. What did you see instead (give full error messages and/or log)?
|
||||
|
||||
|
||||
### 8. How can someone who is starting from scratch reproduce the bug as minimally as possible?
|
||||
|
||||
(Please strip away any extra infrastructure such as containers, reverse proxies, upstream apps, dependencies, etc, to prove this is a bug in Caddy and not an external misconfiguration. Your chances of getting this bug fixed go way up the easier it is to replicate. Thank you!)
|
||||
201
vendor/github.com/mholt/caddy/LICENSE.txt
generated
vendored
201
vendor/github.com/mholt/caddy/LICENSE.txt
generated
vendored
@@ -1,201 +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.
|
||||
168
vendor/github.com/mholt/caddy/README.md
generated
vendored
168
vendor/github.com/mholt/caddy/README.md
generated
vendored
@@ -1,168 +0,0 @@
|
||||
<a href="https://caddyserver.com"><img src="https://caddyserver.com/resources/images/caddy-lower.png" alt="Caddy" width="350"></a>
|
||||
|
||||
[](https://forum.caddyserver.com) [](https://twitter.com/caddyserver) [](https://godoc.org/github.com/mholt/caddy) [](https://travis-ci.org/mholt/caddy) [](https://ci.appveyor.com/project/mholt/caddy)
|
||||
[](https://goreportcard.com/report/mholt/caddy)
|
||||
[](https://sourcegraph.com/github.com/mholt/caddy?badge)
|
||||
|
||||
|
||||
Caddy is a general-purpose web server for Windows, Mac, Linux, BSD, and
|
||||
[Android](https://github.com/mholt/caddy/wiki/Running-Caddy-on-Android). It is
|
||||
a capable but easier alternative to other popular web servers.
|
||||
|
||||
[Releases](https://github.com/mholt/caddy/releases) ·
|
||||
[User Guide](https://caddyserver.com/docs) ·
|
||||
[Community](https://forum.caddyserver.com)
|
||||
|
||||
**Attend the [Caddy launch event](https://www.facebook.com/events/1413078512092363/) on April 20! It's free, and we will try to get a live stream going.**
|
||||
|
||||
<a href="https://www.facebook.com/events/1413078512092363/"><img src="http://i.imgur.com/CjGICWU.png" alt="Caddy launch event" width="500"></a>
|
||||
|
||||
Try browsing [the code on Sourcegraph](https://sourcegraph.com/github.com/mholt/caddy)!
|
||||
|
||||
## Menu
|
||||
|
||||
- [Features](#features)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Running from Source](#running-from-source)
|
||||
- [Running in Production](#running-in-production)
|
||||
- [Contributing](#contributing)
|
||||
- [About the Project](#about-the-project)
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **Easy configuration** with Caddyfile
|
||||
- **Automatic HTTPS** via [Let's Encrypt](https://letsencrypt.org); Caddy
|
||||
obtains and manages all cryptographic assets for you
|
||||
- **HTTP/2** enabled by default (powered by Go standard library)
|
||||
- **Virtual hosting** for hundreds of sites per server instance, including TLS
|
||||
SNI
|
||||
- Experimental **QUIC support** for those that like speed
|
||||
- TLS session ticket **key rotation** for more secure connections
|
||||
- **Brilliant extensibility** so Caddy can be customized for your needs
|
||||
- **Runs anywhere** with **no external dependencies** (not even libc)
|
||||
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
Caddy binaries have no dependencies and are available for every platform.
|
||||
Install Caddy any one of these ways:
|
||||
|
||||
- **[Download page](https://caddyserver.com/download)** allows you to
|
||||
customize your build in the browser
|
||||
- **[Latest release](https://github.com/mholt/caddy/releases/latest)** for
|
||||
pre-built binaries
|
||||
- **curl [getcaddy.com](https://getcaddy.com)** for auto install:
|
||||
`curl https://getcaddy.com | bash`
|
||||
|
||||
Once `caddy` is in your PATH, you can `cd` to your website's folder and run
|
||||
`caddy` to serve it. By default, Caddy serves the current directory at
|
||||
[localhost:2015](http://localhost:2015).
|
||||
|
||||
To customize how your site is served, create a file named Caddyfile by your
|
||||
site and paste this into it:
|
||||
|
||||
```plain
|
||||
localhost
|
||||
|
||||
gzip
|
||||
browse
|
||||
websocket /echo cat
|
||||
ext .html
|
||||
log /var/log/access.log
|
||||
proxy /api 127.0.0.1:7005
|
||||
header /api Access-Control-Allow-Origin *
|
||||
```
|
||||
|
||||
When you run `caddy` in that directory, it will automatically find and use
|
||||
that Caddyfile to configure itself.
|
||||
|
||||
This simple file enables compression, allows directory browsing (for folders
|
||||
without an index file), hosts a WebSocket echo server at /echo, serves clean
|
||||
URLs, logs requests to access.log, proxies all API requests to a backend on
|
||||
port 7005, and adds the coveted `Access-Control-Allow-Origin: *` header for
|
||||
all responses from the API.
|
||||
|
||||
Wow! Caddy can do a lot with just a few lines.
|
||||
|
||||
To host multiple sites and do more with the Caddyfile, please see the
|
||||
[Caddyfile documentation](https://caddyserver.com/docs/caddyfile).
|
||||
|
||||
Note that production sites are served over
|
||||
[HTTPS by default](https://caddyserver.com/docs/automatic-https).
|
||||
|
||||
Caddy has a command line interface. Run `caddy -h` to view basic help or see
|
||||
the [CLI documentation](https://caddyserver.com/docs/cli) for details.
|
||||
|
||||
**Running as root:** We advise against this. You can still listen on ports
|
||||
< 1024 using setcap like so: `sudo setcap cap_net_bind_service=+ep ./caddy`
|
||||
|
||||
|
||||
|
||||
## Running from Source
|
||||
|
||||
Note: You will need **[Go 1.8](https://golang.org/dl/)** or newer.
|
||||
|
||||
1. `go get github.com/mholt/caddy/caddy`
|
||||
2. `cd` into your website's directory
|
||||
3. Run `caddy` (assuming `$GOPATH/bin` is in your `$PATH`)
|
||||
|
||||
Caddy's `main()` is in the caddy subfolder. To recompile Caddy, use
|
||||
`build.bash` found in that folder.
|
||||
|
||||
|
||||
|
||||
## Running in Production
|
||||
|
||||
The Caddy project does not officially maintain any system-specific
|
||||
integrations, but your download file includes
|
||||
[unofficial resources](https://github.com/mholt/caddy/tree/master/dist/init)
|
||||
contributed by the community that you may find helpful for running Caddy in
|
||||
production.
|
||||
|
||||
How you choose to run Caddy is up to you. Many users are satisfied with
|
||||
`nohup caddy &`. Others use `screen`. Users who need Caddy to come back up
|
||||
after reboots either do so in the script that caused the reboot, add a command
|
||||
to an init script, or configure a service with their OS.
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
**[Join our community](https://forum.caddyserver.com) where you can chat with
|
||||
other Caddy users and developers!**
|
||||
|
||||
Please see our [contributing guidelines](https://github.com/mholt/caddy/blob/master/CONTRIBUTING.md)
|
||||
and check out the [developer wiki](https://github.com/mholt/caddy/wiki).
|
||||
|
||||
We use GitHub issues and pull requests only for discussing bug reports and
|
||||
the development of specific changes. We welcome all other topics on the
|
||||
[forum](https://forum.caddyserver.com)!
|
||||
|
||||
If you want to contribute to the documentation, please submit pull requests to [caddyserver/caddyserver.com](https://github.com/caddyserver/caddyserver.com).
|
||||
|
||||
Thanks for making Caddy -- and the Web -- better!
|
||||
|
||||
Special thanks to
|
||||
[](https://www.digitalocean.com)
|
||||
for hosting the Caddy project.
|
||||
|
||||
|
||||
|
||||
## About the Project
|
||||
|
||||
Caddy was born out of the need for a "batteries-included" web server that runs
|
||||
anywhere and doesn't have to take its configuration with it. Caddy took
|
||||
inspiration from [spark](https://github.com/rif/spark),
|
||||
[nginx](https://github.com/nginx/nginx), lighttpd,
|
||||
[Websocketd](https://github.com/joewalnes/websocketd)
|
||||
and [Vagrant](https://www.vagrantup.com/),
|
||||
which provides a pleasant mixture of features from each of them.
|
||||
|
||||
**The name "Caddy":** The name of the software is "Caddy", not "Caddy Server"
|
||||
or "CaddyServer". Please call it "Caddy" or, if you wish to clarify, "the
|
||||
Caddy web server". See [brand guidelines](https://caddyserver.com/brand).
|
||||
|
||||
*Author on Twitter: [@mholt6](https://twitter.com/mholt6)*
|
||||
31
vendor/github.com/mholt/caddy/appveyor.yml
generated
vendored
31
vendor/github.com/mholt/caddy/appveyor.yml
generated
vendored
@@ -1,31 +0,0 @@
|
||||
version: "{build}"
|
||||
|
||||
os: Windows Server 2012 R2
|
||||
|
||||
clone_folder: c:\gopath\src\github.com\mholt\caddy
|
||||
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
|
||||
install:
|
||||
- rmdir c:\go /s /q
|
||||
- appveyor DownloadFile https://storage.googleapis.com/golang/go1.8.windows-amd64.zip
|
||||
- 7z x go1.8.windows-amd64.zip -y -oC:\ > NUL
|
||||
- go version
|
||||
- go env
|
||||
- go get -t ./...
|
||||
- go get github.com/golang/lint/golint
|
||||
- go get github.com/gordonklaus/ineffassign
|
||||
- set PATH=%GOPATH%\bin;%PATH%
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- go vet ./...
|
||||
- go test -race ./...
|
||||
- ineffassign .
|
||||
|
||||
after_test:
|
||||
- golint ./...
|
||||
|
||||
deploy: off
|
||||
34
vendor/github.com/mholt/caddy/assets.go
generated
vendored
34
vendor/github.com/mholt/caddy/assets.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
package caddy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// AssetsPath returns the path to the folder
|
||||
// where the application may store data. If
|
||||
// CADDYPATH env variable is set, that value
|
||||
// is used. Otherwise, the path is the result
|
||||
// of evaluating "$HOME/.caddy".
|
||||
func AssetsPath() string {
|
||||
if caddyPath := os.Getenv("CADDYPATH"); caddyPath != "" {
|
||||
return caddyPath
|
||||
}
|
||||
return filepath.Join(userHomeDir(), ".caddy")
|
||||
}
|
||||
|
||||
// userHomeDir returns the user's home directory according to
|
||||
// environment variables.
|
||||
//
|
||||
// Credit: http://stackoverflow.com/a/7922977/1048862
|
||||
func userHomeDir() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
||||
if home == "" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
return home
|
||||
}
|
||||
return os.Getenv("HOME")
|
||||
}
|
||||
19
vendor/github.com/mholt/caddy/assets_test.go
generated
vendored
19
vendor/github.com/mholt/caddy/assets_test.go
generated
vendored
@@ -1,19 +0,0 @@
|
||||
package caddy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAssetsPath(t *testing.T) {
|
||||
if actual := AssetsPath(); !strings.HasSuffix(actual, ".caddy") {
|
||||
t.Errorf("Expected path to be a .caddy folder, got: %v", actual)
|
||||
}
|
||||
|
||||
os.Setenv("CADDYPATH", "testpath")
|
||||
if actual, expected := AssetsPath(), "testpath"; actual != expected {
|
||||
t.Errorf("Expected path to be %v, got: %v", expected, actual)
|
||||
}
|
||||
os.Setenv("CADDYPATH", "")
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user