diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 3a265b7e87..81ce939b48 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -135,10 +135,6 @@ "Comment": "v1.1.0-65-gee4a088", "Rev": "ee4a0888a9abe7eefe5a0992ca4cb06864839873" }, - { - "ImportPath": "github.com/bradfitz/http2", - "Rev": "3e36af6d3af0e56fa3da71099f864933dea3d9fb" - }, { "ImportPath": "github.com/camlistore/go4/errorutil", "Rev": "3b6feb5cf32f573fb124905de36a54c24ee14ac1" @@ -150,123 +146,123 @@ }, { "ImportPath": "github.com/coreos/etcd/client", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/error", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/timeutil", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/storage", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/store", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/version", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Comment": "v2.2.2-4-ge0c7768", - "Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" + "Comment": "v2.2.5", + "Rev": "bc9ddf260115d2680191c46977ae72b837785472" }, { "ImportPath": "github.com/coreos/go-etcd/etcd", @@ -340,8 +336,8 @@ }, { "ImportPath": "github.com/coreos/rkt/api/v1alpha", - "Comment": "v0.15.0-22-g8ac03ac", - "Rev": "8ac03ace42034b4d6b31af9e3ef574b9e71ccc1a" + "Comment": "v1.0.0", + "Rev": "1ddc36601c8688ff207210bc9ecbf973d09573fa" }, { "ImportPath": "github.com/cpuguy83/go-md2man/md2man", @@ -425,7 +421,6 @@ }, { "ImportPath": "github.com/fsouza/go-dockerclient", - "Comment": "0.2.1-860-g25bc220", "Rev": "25bc220b299845ae5489fd19bf89c5278864b050" }, { @@ -452,118 +447,118 @@ }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/description", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/embedcheck", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/enumstringer", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/equal", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/face", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/gostring", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/grpc", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/marshalto", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/populate", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/size", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/stringer", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/testgen", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/union", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/plugin/unmarshal", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/proto", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/sortkeys", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/gogo/protobuf/vanity", - "Comment": "v0.1-108-g9dc5109", - "Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" + "Comment": "v0.1-125-g82d16f7", + "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" }, { "ImportPath": "github.com/golang/glog", @@ -575,7 +570,7 @@ }, { "ImportPath": "github.com/golang/protobuf/proto", - "Rev": "7f07925444bb51fa4cf9dfe6f7661876f8852275" + "Rev": "b982704f8bb716bb608144408cff30e15fbde841" }, { "ImportPath": "github.com/google/btree", @@ -970,6 +965,10 @@ "ImportPath": "golang.org/x/net/html", "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" }, + { + "ImportPath": "golang.org/x/net/http2", + "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" + }, { "ImportPath": "golang.org/x/net/internal/timeseries", "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" @@ -1028,7 +1027,7 @@ }, { "ImportPath": "google.golang.org/grpc", - "Rev": "4bd040ce23a624ff9a1d07b0e729ee189bddd51c" + "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" }, { "ImportPath": "gopkg.in/natefinch/lumberjack.v2", @@ -1041,7 +1040,7 @@ }, { "ImportPath": "k8s.io/heapster/api/v1/types", - "Comment": "v0.19.1", + "Comment": "v0.19.1-44-g0991ac5", "Rev": "0991ac528ea24aae194e45d6dcf01896cb42cbea" }, { diff --git a/Godeps/LICENSES.md b/Godeps/LICENSES.md index ce6220319e..448927f8de 100644 --- a/Godeps/LICENSES.md +++ b/Godeps/LICENSES.md @@ -13,7 +13,6 @@ github.com/aws/aws-sdk-go | Apache-2 github.com/beorn7/perks/quantile | MIT? github.com/blang/semver | MITname github.com/boltdb/bolt | MITname -github.com/bradfitz/http2 | BSDlikeRef github.com/camlistore/go4 | Apache-2 github.com/ClusterHQ/flocker-go | UNKNOWN github.com/codegangsta/negroni | MITname @@ -23,7 +22,7 @@ github.com/coreos/go-oidc | Apache-2 github.com/coreos/go-semver | Apache-2 github.com/coreos/go-systemd | Apache-2 github.com/coreos/pkg | Apache-2 -github.com/coreos/rkt | Apache-2 +github.com/coreos/rkt | MITname github.com/cpuguy83/go-md2man | MITname github.com/davecgh/go-spew | MIToldwithoutSellandNoDocumentationRequi github.com/daviddengcn/go-colortext | BSD? diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/.gitignore b/Godeps/_workspace/src/github.com/bradfitz/http2/.gitignore deleted file mode 100644 index b25c15b81f..0000000000 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*~ diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/AUTHORS b/Godeps/_workspace/src/github.com/bradfitz/http2/AUTHORS deleted file mode 100644 index dab9dbe751..0000000000 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -# This file is like Go's AUTHORS file: it lists Copyright holders. -# The list of humans who have contributd is in the CONTRIBUTORS file. -# -# To contribute to this project, because it will eventually be folded -# back in to Go itself, you need to submit a CLA: -# -# http://golang.org/doc/contribute.html#copyright -# -# Then you get added to CONTRIBUTORS and you or your company get added -# to the AUTHORS file. - -Blake Mizerany github=bmizerany -Daniel Morsing github=DanielMorsing -Gabriel Aszalos github=gbbr -Google, Inc. -Keith Rarick github=kr -Matthew Keenan github=mattkeenan -Matt Layher github=mdlayher -Tatsuhiro Tsujikawa github=tatsuhiro-t diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/CONTRIBUTORS b/Godeps/_workspace/src/github.com/bradfitz/http2/CONTRIBUTORS deleted file mode 100644 index 22e8c8c544..0000000000 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/CONTRIBUTORS +++ /dev/null @@ -1,19 +0,0 @@ -# This file is like Go's CONTRIBUTORS file: it lists humans. -# The list of copyright holders (which may be companies) are in the AUTHORS file. -# -# To contribute to this project, because it will eventually be folded -# back in to Go itself, you need to submit a CLA: -# -# http://golang.org/doc/contribute.html#copyright -# -# Then you get added to CONTRIBUTORS and you or your company get added -# to the AUTHORS file. - -Blake Mizerany github=bmizerany -Brad Fitzpatrick github=bradfitz -Daniel Morsing github=DanielMorsing -Gabriel Aszalos github=gbbr -Keith Rarick github=kr -Matthew Keenan github=mattkeenan -Matt Layher github=mdlayher -Tatsuhiro Tsujikawa github=tatsuhiro-t diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/HACKING b/Godeps/_workspace/src/github.com/bradfitz/http2/HACKING deleted file mode 100644 index 69aafe4d17..0000000000 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/HACKING +++ /dev/null @@ -1,5 +0,0 @@ -We only accept contributions from users who have gone through Go's -contribution process (signed a CLA). - -Please acknowledge whether you have (and use the same email) if -sending a pull request. diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/LICENSE b/Godeps/_workspace/src/github.com/bradfitz/http2/LICENSE deleted file mode 100644 index 2dc6853cae..0000000000 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2014 Google & the Go AUTHORS - -Go AUTHORS are: -See https://code.google.com/p/go/source/browse/AUTHORS - -Licensed under the terms of Go itself: -https://code.google.com/p/go/source/browse/LICENSE diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go index e484032c1a..cf8aea8775 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go @@ -24,6 +24,7 @@ import ( "net/url" "reflect" "sort" + "strconv" "sync" "time" @@ -99,6 +100,8 @@ type Config struct { // watch start. But if server is behind some kind of proxy, the response // header may be cached at proxy, and Client cannot rely on this behavior. // + // Especially, wait request will ignore this timeout. + // // One API call may send multiple requests to different etcd servers until it // succeeds. Use context of the API to specify the overall timeout. // @@ -162,6 +165,11 @@ type Client interface { // this may differ from the initial Endpoints provided in the Config. Endpoints() []string + // SetEndpoints sets the set of API endpoints used by Client to resolve + // HTTP requests. If the given endpoints are not valid, an error will be + // returned + SetEndpoints(eps []string) error + httpClient } @@ -176,7 +184,7 @@ func New(cfg Config) (Client, error) { password: cfg.Password, } } - if err := c.reset(cfg.Endpoints); err != nil { + if err := c.SetEndpoints(cfg.Endpoints); err != nil { return nil, err } return c, nil @@ -219,7 +227,7 @@ type httpClusterClient struct { rand *rand.Rand } -func (c *httpClusterClient) reset(eps []string) error { +func (c *httpClusterClient) SetEndpoints(eps []string) error { if len(eps) == 0 { return ErrNoEndpoints } @@ -341,7 +349,7 @@ func (c *httpClusterClient) Sync(ctx context.Context) error { return nil } - return c.reset(eps) + return c.SetEndpoints(eps) } func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error { @@ -378,9 +386,21 @@ func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Respon return nil, nil, err } + isWait := false + if req != nil && req.URL != nil { + ws := req.URL.Query().Get("wait") + if len(ws) != 0 { + var err error + isWait, err = strconv.ParseBool(ws) + if err != nil { + return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req) + } + } + } + var hctx context.Context var hcancel context.CancelFunc - if c.headerTimeout > 0 { + if !isWait && c.headerTimeout > 0 { hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout) } else { hctx, hcancel = context.WithCancel(ctx) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth.go index 9e7dd4e79f..2a6b17333f 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth.go @@ -95,8 +95,7 @@ type store struct { timeout time.Duration ensuredOnce bool - mu sync.Mutex // protect enabled - enabled *bool + mu sync.Mutex } type User struct { @@ -409,8 +408,6 @@ func (s *store) EnableAuth() error { } err = s.enableAuth() if err == nil { - b := true - s.enabled = &b plog.Noticef("auth: enabled auth") } else { plog.Errorf("error enabling auth (%v)", err) @@ -428,8 +425,6 @@ func (s *store) DisableAuth() error { err := s.disableAuth() if err == nil { - b := false - s.enabled = &b plog.Noticef("auth: disabled auth") } else { plog.Errorf("error disabling auth (%v)", err) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth_requests.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth_requests.go index ca30060ce6..0761121d74 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth_requests.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/auth/auth_requests.go @@ -85,15 +85,10 @@ func (s *store) detectAuth() bool { if s.server == nil { return false } - if s.enabled != nil { - return *s.enabled - } value, err := s.requestResource("/enabled", false) if err != nil { if e, ok := err.(*etcderr.Error); ok { if e.ErrorCode == etcderr.EcodeKeyNotFound { - b := false - s.enabled = &b return false } } @@ -107,7 +102,6 @@ func (s *store) detectAuth() bool { plog.Errorf("internal bookkeeping value for enabled isn't valid JSON (%v)", err) return false } - s.enabled = &u return u } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go index 447fda41cb..6f46c2fe9c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go @@ -13,38 +13,56 @@ It has these top-level messages: Request Metadata + InternalRaftRequest + ResponseHeader + RangeRequest + RangeResponse + PutRequest + PutResponse + DeleteRangeRequest + DeleteRangeResponse + RequestUnion + ResponseUnion + Compare + TxnRequest + TxnResponse + CompactionRequest + CompactionResponse */ package etcdserverpb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" + + proto "github.com/gogo/protobuf/proto" +) + import math "math" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" - import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type Request struct { - ID uint64 `protobuf:"varint,1,opt" json:"ID"` - Method string `protobuf:"bytes,2,opt" json:"Method"` - Path string `protobuf:"bytes,3,opt" json:"Path"` - Val string `protobuf:"bytes,4,opt" json:"Val"` - Dir bool `protobuf:"varint,5,opt" json:"Dir"` - PrevValue string `protobuf:"bytes,6,opt" json:"PrevValue"` - PrevIndex uint64 `protobuf:"varint,7,opt" json:"PrevIndex"` - PrevExist *bool `protobuf:"varint,8,opt" json:"PrevExist,omitempty"` - Expiration int64 `protobuf:"varint,9,opt" json:"Expiration"` - Wait bool `protobuf:"varint,10,opt" json:"Wait"` - Since uint64 `protobuf:"varint,11,opt" json:"Since"` - Recursive bool `protobuf:"varint,12,opt" json:"Recursive"` - Sorted bool `protobuf:"varint,13,opt" json:"Sorted"` - Quorum bool `protobuf:"varint,14,opt" json:"Quorum"` - Time int64 `protobuf:"varint,15,opt" json:"Time"` - Stream bool `protobuf:"varint,16,opt" json:"Stream"` + ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"` + Method string `protobuf:"bytes,2,opt,name=Method" json:"Method"` + Path string `protobuf:"bytes,3,opt,name=Path" json:"Path"` + Val string `protobuf:"bytes,4,opt,name=Val" json:"Val"` + Dir bool `protobuf:"varint,5,opt,name=Dir" json:"Dir"` + PrevValue string `protobuf:"bytes,6,opt,name=PrevValue" json:"PrevValue"` + PrevIndex uint64 `protobuf:"varint,7,opt,name=PrevIndex" json:"PrevIndex"` + PrevExist *bool `protobuf:"varint,8,opt,name=PrevExist" json:"PrevExist,omitempty"` + Expiration int64 `protobuf:"varint,9,opt,name=Expiration" json:"Expiration"` + Wait bool `protobuf:"varint,10,opt,name=Wait" json:"Wait"` + Since uint64 `protobuf:"varint,11,opt,name=Since" json:"Since"` + Recursive bool `protobuf:"varint,12,opt,name=Recursive" json:"Recursive"` + Sorted bool `protobuf:"varint,13,opt,name=Sorted" json:"Sorted"` + Quorum bool `protobuf:"varint,14,opt,name=Quorum" json:"Quorum"` + Time int64 `protobuf:"varint,15,opt,name=Time" json:"Time"` + Stream bool `protobuf:"varint,16,opt,name=Stream" json:"Stream"` XXX_unrecognized []byte `json:"-"` } @@ -53,8 +71,8 @@ func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} type Metadata struct { - NodeID uint64 `protobuf:"varint,1,opt" json:"NodeID"` - ClusterID uint64 `protobuf:"varint,2,opt" json:"ClusterID"` + NodeID uint64 `protobuf:"varint,1,opt,name=NodeID" json:"NodeID"` + ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID" json:"ClusterID"` XXX_unrecognized []byte `json:"-"` } @@ -62,6 +80,10 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} +func init() { + proto.RegisterType((*Request)(nil), "etcdserverpb.Request") + proto.RegisterType((*Metadata)(nil), "etcdserverpb.Metadata") +} func (m *Request) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -287,8 +309,12 @@ func (m *Request) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -301,6 +327,12 @@ func (m *Request) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Request: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -308,6 +340,9 @@ func (m *Request) Unmarshal(data []byte) error { } m.ID = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -324,6 +359,9 @@ func (m *Request) Unmarshal(data []byte) error { } var stringLen uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -350,6 +388,9 @@ func (m *Request) Unmarshal(data []byte) error { } var stringLen uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -376,6 +417,9 @@ func (m *Request) Unmarshal(data []byte) error { } var stringLen uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -402,6 +446,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -419,6 +466,9 @@ func (m *Request) Unmarshal(data []byte) error { } var stringLen uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -445,6 +495,9 @@ func (m *Request) Unmarshal(data []byte) error { } m.PrevIndex = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -461,6 +514,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -479,6 +535,9 @@ func (m *Request) Unmarshal(data []byte) error { } m.Expiration = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -495,6 +554,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -512,6 +574,9 @@ func (m *Request) Unmarshal(data []byte) error { } m.Since = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -528,6 +593,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -545,6 +613,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -562,6 +633,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -579,6 +653,9 @@ func (m *Request) Unmarshal(data []byte) error { } m.Time = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -595,6 +672,9 @@ func (m *Request) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -607,15 +687,7 @@ func (m *Request) Unmarshal(data []byte) error { } m.Stream = bool(v != 0) default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipEtcdserver(data[iNdEx:]) if err != nil { return err @@ -631,14 +703,21 @@ func (m *Request) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *Metadata) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -651,6 +730,12 @@ func (m *Metadata) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -658,6 +743,9 @@ func (m *Metadata) Unmarshal(data []byte) error { } m.NodeID = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -674,6 +762,9 @@ func (m *Metadata) Unmarshal(data []byte) error { } m.ClusterID = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEtcdserver + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -685,15 +776,7 @@ func (m *Metadata) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipEtcdserver(data[iNdEx:]) if err != nil { return err @@ -709,6 +792,9 @@ func (m *Metadata) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipEtcdserver(data []byte) (n int, err error) { @@ -717,6 +803,9 @@ func skipEtcdserver(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEtcdserver + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -730,7 +819,10 @@ func skipEtcdserver(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEtcdserver + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -746,6 +838,9 @@ func skipEtcdserver(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEtcdserver + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -766,6 +861,9 @@ func skipEtcdserver(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEtcdserver + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -801,4 +899,5 @@ func skipEtcdserver(data []byte) (n int, err error) { var ( ErrInvalidLengthEtcdserver = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEtcdserver = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go index 8d6fb22cd3..47402aebf7 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go @@ -4,15 +4,20 @@ package etcdserverpb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +import math "math" import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf // An InternalRaftRequest is the union of all requests which can be // sent via raft. @@ -28,6 +33,9 @@ func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} } func (m *InternalRaftRequest) String() string { return proto.CompactTextString(m) } func (*InternalRaftRequest) ProtoMessage() {} +func init() { + proto.RegisterType((*InternalRaftRequest)(nil), "etcdserverpb.InternalRaftRequest") +} func (m *InternalRaftRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -162,48 +170,16 @@ func sovRaftInternal(x uint64) (n int) { func sozRaftInternal(x uint64) (n int) { return sovRaftInternal(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (this *InternalRaftRequest) GetValue() interface{} { - if this.V2 != nil { - return this.V2 - } - if this.Range != nil { - return this.Range - } - if this.Put != nil { - return this.Put - } - if this.DeleteRange != nil { - return this.DeleteRange - } - if this.Txn != nil { - return this.Txn - } - return nil -} - -func (this *InternalRaftRequest) SetValue(value interface{}) bool { - switch vt := value.(type) { - case *Request: - this.V2 = vt - case *RangeRequest: - this.Range = vt - case *PutRequest: - this.Put = vt - case *DeleteRangeRequest: - this.DeleteRange = vt - case *TxnRequest: - this.Txn = vt - default: - return false - } - return true -} func (m *InternalRaftRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -216,6 +192,12 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: InternalRaftRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: InternalRaftRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -223,6 +205,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -253,6 +238,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -283,6 +271,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -313,6 +304,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -343,6 +337,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -368,15 +365,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaftInternal(data[iNdEx:]) if err != nil { return err @@ -391,6 +380,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipRaftInternal(data []byte) (n int, err error) { @@ -399,6 +391,9 @@ func skipRaftInternal(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaftInternal + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -412,7 +407,10 @@ func skipRaftInternal(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaftInternal + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -428,6 +426,9 @@ func skipRaftInternal(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaftInternal + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -448,6 +449,9 @@ func skipRaftInternal(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaftInternal + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -483,4 +487,5 @@ func skipRaftInternal(data []byte) (n int, err error) { var ( ErrInvalidLengthRaftInternal = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRaftInternal = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto index 7cf7b67d03..32efcdafc9 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto @@ -13,12 +13,9 @@ option (gogoproto.goproto_getters_all) = false; // An InternalRaftRequest is the union of all requests which can be // sent via raft. message InternalRaftRequest { - option (gogoproto.onlyone) = true; - oneof value { Request v2 = 1; RangeRequest range = 2; PutRequest put = 3; DeleteRangeRequest delete_range = 4; TxnRequest txn = 5; - } } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go index 462b0610b9..9dd30fb02f 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -4,9 +4,14 @@ package etcdserverpb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" + + proto "github.com/gogo/protobuf/proto" +) + +import math "math" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" import storagepb "github.com/coreos/etcd/storage/storagepb" import ( @@ -15,10 +20,11 @@ import ( ) import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf type Compare_CompareResult int32 @@ -178,86 +184,404 @@ func (m *DeleteRangeResponse) GetHeader() *ResponseHeader { } type RequestUnion struct { - RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range" json:"request_range,omitempty"` - RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put" json:"request_put,omitempty"` - RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range" json:"request_delete_range,omitempty"` + // Types that are valid to be assigned to Request: + // *RequestUnion_RequestRange + // *RequestUnion_RequestPut + // *RequestUnion_RequestDeleteRange + Request isRequestUnion_Request `protobuf_oneof:"request"` } func (m *RequestUnion) Reset() { *m = RequestUnion{} } func (m *RequestUnion) String() string { return proto.CompactTextString(m) } func (*RequestUnion) ProtoMessage() {} -func (m *RequestUnion) GetRequestRange() *RangeRequest { +type isRequestUnion_Request interface { + isRequestUnion_Request() + MarshalTo([]byte) (int, error) + Size() int +} + +type RequestUnion_RequestRange struct { + RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range,oneof"` +} +type RequestUnion_RequestPut struct { + RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put,oneof"` +} +type RequestUnion_RequestDeleteRange struct { + RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,oneof"` +} + +func (*RequestUnion_RequestRange) isRequestUnion_Request() {} +func (*RequestUnion_RequestPut) isRequestUnion_Request() {} +func (*RequestUnion_RequestDeleteRange) isRequestUnion_Request() {} + +func (m *RequestUnion) GetRequest() isRequestUnion_Request { if m != nil { - return m.RequestRange + return m.Request + } + return nil +} + +func (m *RequestUnion) GetRequestRange() *RangeRequest { + if x, ok := m.GetRequest().(*RequestUnion_RequestRange); ok { + return x.RequestRange } return nil } func (m *RequestUnion) GetRequestPut() *PutRequest { - if m != nil { - return m.RequestPut + if x, ok := m.GetRequest().(*RequestUnion_RequestPut); ok { + return x.RequestPut } return nil } func (m *RequestUnion) GetRequestDeleteRange() *DeleteRangeRequest { - if m != nil { - return m.RequestDeleteRange + if x, ok := m.GetRequest().(*RequestUnion_RequestDeleteRange); ok { + return x.RequestDeleteRange } return nil } +// XXX_OneofFuncs is for the internal use of the proto package. +func (*RequestUnion) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { + return _RequestUnion_OneofMarshaler, _RequestUnion_OneofUnmarshaler, []interface{}{ + (*RequestUnion_RequestRange)(nil), + (*RequestUnion_RequestPut)(nil), + (*RequestUnion_RequestDeleteRange)(nil), + } +} + +func _RequestUnion_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*RequestUnion) + // request + switch x := m.Request.(type) { + case *RequestUnion_RequestRange: + _ = b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.RequestRange); err != nil { + return err + } + case *RequestUnion_RequestPut: + _ = b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.RequestPut); err != nil { + return err + } + case *RequestUnion_RequestDeleteRange: + _ = b.EncodeVarint(3<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.RequestDeleteRange); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("RequestUnion.Request has unexpected type %T", x) + } + return nil +} + +func _RequestUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*RequestUnion) + switch tag { + case 1: // request.request_range + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(RangeRequest) + err := b.DecodeMessage(msg) + m.Request = &RequestUnion_RequestRange{msg} + return true, err + case 2: // request.request_put + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(PutRequest) + err := b.DecodeMessage(msg) + m.Request = &RequestUnion_RequestPut{msg} + return true, err + case 3: // request.request_delete_range + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(DeleteRangeRequest) + err := b.DecodeMessage(msg) + m.Request = &RequestUnion_RequestDeleteRange{msg} + return true, err + default: + return false, nil + } +} + type ResponseUnion struct { - ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range" json:"response_range,omitempty"` - ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put" json:"response_put,omitempty"` - ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range" json:"response_delete_range,omitempty"` + // Types that are valid to be assigned to Response: + // *ResponseUnion_ResponseRange + // *ResponseUnion_ResponsePut + // *ResponseUnion_ResponseDeleteRange + Response isResponseUnion_Response `protobuf_oneof:"response"` } func (m *ResponseUnion) Reset() { *m = ResponseUnion{} } func (m *ResponseUnion) String() string { return proto.CompactTextString(m) } func (*ResponseUnion) ProtoMessage() {} -func (m *ResponseUnion) GetResponseRange() *RangeResponse { +type isResponseUnion_Response interface { + isResponseUnion_Response() + MarshalTo([]byte) (int, error) + Size() int +} + +type ResponseUnion_ResponseRange struct { + ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range,oneof"` +} +type ResponseUnion_ResponsePut struct { + ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put,oneof"` +} +type ResponseUnion_ResponseDeleteRange struct { + ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,oneof"` +} + +func (*ResponseUnion_ResponseRange) isResponseUnion_Response() {} +func (*ResponseUnion_ResponsePut) isResponseUnion_Response() {} +func (*ResponseUnion_ResponseDeleteRange) isResponseUnion_Response() {} + +func (m *ResponseUnion) GetResponse() isResponseUnion_Response { if m != nil { - return m.ResponseRange + return m.Response + } + return nil +} + +func (m *ResponseUnion) GetResponseRange() *RangeResponse { + if x, ok := m.GetResponse().(*ResponseUnion_ResponseRange); ok { + return x.ResponseRange } return nil } func (m *ResponseUnion) GetResponsePut() *PutResponse { - if m != nil { - return m.ResponsePut + if x, ok := m.GetResponse().(*ResponseUnion_ResponsePut); ok { + return x.ResponsePut } return nil } func (m *ResponseUnion) GetResponseDeleteRange() *DeleteRangeResponse { - if m != nil { - return m.ResponseDeleteRange + if x, ok := m.GetResponse().(*ResponseUnion_ResponseDeleteRange); ok { + return x.ResponseDeleteRange } return nil } +// XXX_OneofFuncs is for the internal use of the proto package. +func (*ResponseUnion) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { + return _ResponseUnion_OneofMarshaler, _ResponseUnion_OneofUnmarshaler, []interface{}{ + (*ResponseUnion_ResponseRange)(nil), + (*ResponseUnion_ResponsePut)(nil), + (*ResponseUnion_ResponseDeleteRange)(nil), + } +} + +func _ResponseUnion_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*ResponseUnion) + // response + switch x := m.Response.(type) { + case *ResponseUnion_ResponseRange: + _ = b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ResponseRange); err != nil { + return err + } + case *ResponseUnion_ResponsePut: + _ = b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ResponsePut); err != nil { + return err + } + case *ResponseUnion_ResponseDeleteRange: + _ = b.EncodeVarint(3<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ResponseDeleteRange); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("ResponseUnion.Response has unexpected type %T", x) + } + return nil +} + +func _ResponseUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*ResponseUnion) + switch tag { + case 1: // response.response_range + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(RangeResponse) + err := b.DecodeMessage(msg) + m.Response = &ResponseUnion_ResponseRange{msg} + return true, err + case 2: // response.response_put + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(PutResponse) + err := b.DecodeMessage(msg) + m.Response = &ResponseUnion_ResponsePut{msg} + return true, err + case 3: // response.response_delete_range + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(DeleteRangeResponse) + err := b.DecodeMessage(msg) + m.Response = &ResponseUnion_ResponseDeleteRange{msg} + return true, err + default: + return false, nil + } +} + type Compare struct { Result Compare_CompareResult `protobuf:"varint,1,opt,name=result,proto3,enum=etcdserverpb.Compare_CompareResult" json:"result,omitempty"` Target Compare_CompareTarget `protobuf:"varint,2,opt,name=target,proto3,enum=etcdserverpb.Compare_CompareTarget" json:"target,omitempty"` // key path Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - // version of the given key - Version int64 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` - // create revision of the given key - CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,proto3" json:"create_revision,omitempty"` - // last modified revision of the given key - ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,proto3" json:"mod_revision,omitempty"` - // value of the given key - Value []byte `protobuf:"bytes,7,opt,name=value,proto3" json:"value,omitempty"` + // Types that are valid to be assigned to TargetUnion: + // *Compare_Version + // *Compare_CreateRevision + // *Compare_ModRevision + // *Compare_Value + TargetUnion isCompare_TargetUnion `protobuf_oneof:"target_union"` } func (m *Compare) Reset() { *m = Compare{} } func (m *Compare) String() string { return proto.CompactTextString(m) } func (*Compare) ProtoMessage() {} +type isCompare_TargetUnion interface { + isCompare_TargetUnion() + MarshalTo([]byte) (int, error) + Size() int +} + +type Compare_Version struct { + Version int64 `protobuf:"varint,4,opt,name=version,proto3,oneof"` +} +type Compare_CreateRevision struct { + CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,proto3,oneof"` +} +type Compare_ModRevision struct { + ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,proto3,oneof"` +} +type Compare_Value struct { + Value []byte `protobuf:"bytes,7,opt,name=value,proto3,oneof"` +} + +func (*Compare_Version) isCompare_TargetUnion() {} +func (*Compare_CreateRevision) isCompare_TargetUnion() {} +func (*Compare_ModRevision) isCompare_TargetUnion() {} +func (*Compare_Value) isCompare_TargetUnion() {} + +func (m *Compare) GetTargetUnion() isCompare_TargetUnion { + if m != nil { + return m.TargetUnion + } + return nil +} + +func (m *Compare) GetVersion() int64 { + if x, ok := m.GetTargetUnion().(*Compare_Version); ok { + return x.Version + } + return 0 +} + +func (m *Compare) GetCreateRevision() int64 { + if x, ok := m.GetTargetUnion().(*Compare_CreateRevision); ok { + return x.CreateRevision + } + return 0 +} + +func (m *Compare) GetModRevision() int64 { + if x, ok := m.GetTargetUnion().(*Compare_ModRevision); ok { + return x.ModRevision + } + return 0 +} + +func (m *Compare) GetValue() []byte { + if x, ok := m.GetTargetUnion().(*Compare_Value); ok { + return x.Value + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Compare) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { + return _Compare_OneofMarshaler, _Compare_OneofUnmarshaler, []interface{}{ + (*Compare_Version)(nil), + (*Compare_CreateRevision)(nil), + (*Compare_ModRevision)(nil), + (*Compare_Value)(nil), + } +} + +func _Compare_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Compare) + // target_union + switch x := m.TargetUnion.(type) { + case *Compare_Version: + _ = b.EncodeVarint(4<<3 | proto.WireVarint) + _ = b.EncodeVarint(uint64(x.Version)) + case *Compare_CreateRevision: + _ = b.EncodeVarint(5<<3 | proto.WireVarint) + _ = b.EncodeVarint(uint64(x.CreateRevision)) + case *Compare_ModRevision: + _ = b.EncodeVarint(6<<3 | proto.WireVarint) + _ = b.EncodeVarint(uint64(x.ModRevision)) + case *Compare_Value: + _ = b.EncodeVarint(7<<3 | proto.WireBytes) + _ = b.EncodeRawBytes(x.Value) + case nil: + default: + return fmt.Errorf("Compare.TargetUnion has unexpected type %T", x) + } + return nil +} + +func _Compare_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Compare) + switch tag { + case 4: // target_union.version + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TargetUnion = &Compare_Version{int64(x)} + return true, err + case 5: // target_union.create_revision + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TargetUnion = &Compare_CreateRevision{int64(x)} + return true, err + case 6: // target_union.mod_revision + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TargetUnion = &Compare_ModRevision{int64(x)} + return true, err + case 7: // target_union.value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.TargetUnion = &Compare_Value{x} + return true, err + default: + return false, nil + } +} + // From google paxosdb paper: // Our implementation hinges around a powerful primitive which we call MultiOp. All other database // operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically @@ -356,6 +680,20 @@ func (m *CompactionResponse) GetHeader() *ResponseHeader { } func init() { + proto.RegisterType((*ResponseHeader)(nil), "etcdserverpb.ResponseHeader") + proto.RegisterType((*RangeRequest)(nil), "etcdserverpb.RangeRequest") + proto.RegisterType((*RangeResponse)(nil), "etcdserverpb.RangeResponse") + proto.RegisterType((*PutRequest)(nil), "etcdserverpb.PutRequest") + proto.RegisterType((*PutResponse)(nil), "etcdserverpb.PutResponse") + proto.RegisterType((*DeleteRangeRequest)(nil), "etcdserverpb.DeleteRangeRequest") + proto.RegisterType((*DeleteRangeResponse)(nil), "etcdserverpb.DeleteRangeResponse") + proto.RegisterType((*RequestUnion)(nil), "etcdserverpb.RequestUnion") + proto.RegisterType((*ResponseUnion)(nil), "etcdserverpb.ResponseUnion") + proto.RegisterType((*Compare)(nil), "etcdserverpb.Compare") + proto.RegisterType((*TxnRequest)(nil), "etcdserverpb.TxnRequest") + proto.RegisterType((*TxnResponse)(nil), "etcdserverpb.TxnResponse") + proto.RegisterType((*CompactionRequest)(nil), "etcdserverpb.CompactionRequest") + proto.RegisterType((*CompactionResponse)(nil), "etcdserverpb.CompactionResponse") proto.RegisterEnum("etcdserverpb.Compare_CompareResult", Compare_CompareResult_name, Compare_CompareResult_value) proto.RegisterEnum("etcdserverpb.Compare_CompareTarget", Compare_CompareTarget_name, Compare_CompareTarget_value) } @@ -465,9 +803,9 @@ func RegisterEtcdServer(s *grpc.Server, srv EtcdServer) { s.RegisterService(&_Etcd_serviceDesc, srv) } -func _Etcd_Range_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Etcd_Range_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(RangeRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(EtcdServer).Range(ctx, in) @@ -477,9 +815,9 @@ func _Etcd_Range_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, return out, nil } -func _Etcd_Put_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Etcd_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(PutRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(EtcdServer).Put(ctx, in) @@ -489,9 +827,9 @@ func _Etcd_Put_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, b return out, nil } -func _Etcd_DeleteRange_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Etcd_DeleteRange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(DeleteRangeRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(EtcdServer).DeleteRange(ctx, in) @@ -501,9 +839,9 @@ func _Etcd_DeleteRange_Handler(srv interface{}, ctx context.Context, codec grpc. return out, nil } -func _Etcd_Txn_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Etcd_Txn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(TxnRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(EtcdServer).Txn(ctx, in) @@ -513,9 +851,9 @@ func _Etcd_Txn_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, b return out, nil } -func _Etcd_Compact_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Etcd_Compact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(CompactionRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(EtcdServer).Compact(ctx, in) @@ -830,31 +1168,37 @@ func (m *RequestUnion) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l + if m.Request != nil { + nn4, err := m.Request.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += nn4 + } + return i, nil +} + +func (m *RequestUnion_RequestRange) MarshalTo(data []byte) (int, error) { + i := 0 if m.RequestRange != nil { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.RequestRange.Size())) - n4, err := m.RequestRange.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n4 - } - if m.RequestPut != nil { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(m.RequestPut.Size())) - n5, err := m.RequestPut.MarshalTo(data[i:]) + n5, err := m.RequestRange.MarshalTo(data[i:]) if err != nil { return 0, err } i += n5 } - if m.RequestDeleteRange != nil { - data[i] = 0x1a + return i, nil +} +func (m *RequestUnion_RequestPut) MarshalTo(data []byte) (int, error) { + i := 0 + if m.RequestPut != nil { + data[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(m.RequestDeleteRange.Size())) - n6, err := m.RequestDeleteRange.MarshalTo(data[i:]) + i = encodeVarintRpc(data, i, uint64(m.RequestPut.Size())) + n6, err := m.RequestPut.MarshalTo(data[i:]) if err != nil { return 0, err } @@ -862,7 +1206,20 @@ func (m *RequestUnion) MarshalTo(data []byte) (int, error) { } return i, nil } - +func (m *RequestUnion_RequestDeleteRange) MarshalTo(data []byte) (int, error) { + i := 0 + if m.RequestDeleteRange != nil { + data[i] = 0x1a + i++ + i = encodeVarintRpc(data, i, uint64(m.RequestDeleteRange.Size())) + n7, err := m.RequestDeleteRange.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n7 + } + return i, nil +} func (m *ResponseUnion) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -878,31 +1235,23 @@ func (m *ResponseUnion) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l + if m.Response != nil { + nn8, err := m.Response.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += nn8 + } + return i, nil +} + +func (m *ResponseUnion_ResponseRange) MarshalTo(data []byte) (int, error) { + i := 0 if m.ResponseRange != nil { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.ResponseRange.Size())) - n7, err := m.ResponseRange.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n7 - } - if m.ResponsePut != nil { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(m.ResponsePut.Size())) - n8, err := m.ResponsePut.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n8 - } - if m.ResponseDeleteRange != nil { - data[i] = 0x1a - i++ - i = encodeVarintRpc(data, i, uint64(m.ResponseDeleteRange.Size())) - n9, err := m.ResponseDeleteRange.MarshalTo(data[i:]) + n9, err := m.ResponseRange.MarshalTo(data[i:]) if err != nil { return 0, err } @@ -910,7 +1259,34 @@ func (m *ResponseUnion) MarshalTo(data []byte) (int, error) { } return i, nil } - +func (m *ResponseUnion_ResponsePut) MarshalTo(data []byte) (int, error) { + i := 0 + if m.ResponsePut != nil { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(m.ResponsePut.Size())) + n10, err := m.ResponsePut.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n10 + } + return i, nil +} +func (m *ResponseUnion_ResponseDeleteRange) MarshalTo(data []byte) (int, error) { + i := 0 + if m.ResponseDeleteRange != nil { + data[i] = 0x1a + i++ + i = encodeVarintRpc(data, i, uint64(m.ResponseDeleteRange.Size())) + n11, err := m.ResponseDeleteRange.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n11 + } + return i, nil +} func (m *Compare) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -944,32 +1320,47 @@ func (m *Compare) MarshalTo(data []byte) (int, error) { i += copy(data[i:], m.Key) } } - if m.Version != 0 { - data[i] = 0x20 - i++ - i = encodeVarintRpc(data, i, uint64(m.Version)) - } - if m.CreateRevision != 0 { - data[i] = 0x28 - i++ - i = encodeVarintRpc(data, i, uint64(m.CreateRevision)) - } - if m.ModRevision != 0 { - data[i] = 0x30 - i++ - i = encodeVarintRpc(data, i, uint64(m.ModRevision)) - } - if m.Value != nil { - if len(m.Value) > 0 { - data[i] = 0x3a - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) + if m.TargetUnion != nil { + nn12, err := m.TargetUnion.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += nn12 } return i, nil } +func (m *Compare_Version) MarshalTo(data []byte) (int, error) { + i := 0 + data[i] = 0x20 + i++ + i = encodeVarintRpc(data, i, uint64(m.Version)) + return i, nil +} +func (m *Compare_CreateRevision) MarshalTo(data []byte) (int, error) { + i := 0 + data[i] = 0x28 + i++ + i = encodeVarintRpc(data, i, uint64(m.CreateRevision)) + return i, nil +} +func (m *Compare_ModRevision) MarshalTo(data []byte) (int, error) { + i := 0 + data[i] = 0x30 + i++ + i = encodeVarintRpc(data, i, uint64(m.ModRevision)) + return i, nil +} +func (m *Compare_Value) MarshalTo(data []byte) (int, error) { + i := 0 + if m.Value != nil { + data[i] = 0x3a + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Value))) + i += copy(data[i:], m.Value) + } + return i, nil +} func (m *TxnRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -1043,11 +1434,11 @@ func (m *TxnResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n10, err := m.Header.MarshalTo(data[i:]) + n13, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n10 + i += n13 } if m.Succeeded { data[i] = 0x10 @@ -1116,11 +1507,11 @@ func (m *CompactionResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n11, err := m.Header.MarshalTo(data[i:]) + n14, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n11 + i += n14 } return i, nil } @@ -1274,41 +1665,77 @@ func (m *DeleteRangeResponse) Size() (n int) { } func (m *RequestUnion) Size() (n int) { + var l int + _ = l + if m.Request != nil { + n += m.Request.Size() + } + return n +} + +func (m *RequestUnion_RequestRange) Size() (n int) { var l int _ = l if m.RequestRange != nil { l = m.RequestRange.Size() n += 1 + l + sovRpc(uint64(l)) } + return n +} +func (m *RequestUnion_RequestPut) Size() (n int) { + var l int + _ = l if m.RequestPut != nil { l = m.RequestPut.Size() n += 1 + l + sovRpc(uint64(l)) } + return n +} +func (m *RequestUnion_RequestDeleteRange) Size() (n int) { + var l int + _ = l if m.RequestDeleteRange != nil { l = m.RequestDeleteRange.Size() n += 1 + l + sovRpc(uint64(l)) } return n } - func (m *ResponseUnion) Size() (n int) { + var l int + _ = l + if m.Response != nil { + n += m.Response.Size() + } + return n +} + +func (m *ResponseUnion_ResponseRange) Size() (n int) { var l int _ = l if m.ResponseRange != nil { l = m.ResponseRange.Size() n += 1 + l + sovRpc(uint64(l)) } + return n +} +func (m *ResponseUnion_ResponsePut) Size() (n int) { + var l int + _ = l if m.ResponsePut != nil { l = m.ResponsePut.Size() n += 1 + l + sovRpc(uint64(l)) } + return n +} +func (m *ResponseUnion_ResponseDeleteRange) Size() (n int) { + var l int + _ = l if m.ResponseDeleteRange != nil { l = m.ResponseDeleteRange.Size() n += 1 + l + sovRpc(uint64(l)) } return n } - func (m *Compare) Size() (n int) { var l int _ = l @@ -1324,24 +1751,39 @@ func (m *Compare) Size() (n int) { n += 1 + l + sovRpc(uint64(l)) } } - if m.Version != 0 { - n += 1 + sovRpc(uint64(m.Version)) - } - if m.CreateRevision != 0 { - n += 1 + sovRpc(uint64(m.CreateRevision)) - } - if m.ModRevision != 0 { - n += 1 + sovRpc(uint64(m.ModRevision)) - } - if m.Value != nil { - l = len(m.Value) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + if m.TargetUnion != nil { + n += m.TargetUnion.Size() } return n } +func (m *Compare_Version) Size() (n int) { + var l int + _ = l + n += 1 + sovRpc(uint64(m.Version)) + return n +} +func (m *Compare_CreateRevision) Size() (n int) { + var l int + _ = l + n += 1 + sovRpc(uint64(m.CreateRevision)) + return n +} +func (m *Compare_ModRevision) Size() (n int) { + var l int + _ = l + n += 1 + sovRpc(uint64(m.ModRevision)) + return n +} +func (m *Compare_Value) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(m.Value) + n += 1 + l + sovRpc(uint64(l)) + } + return n +} func (m *TxnRequest) Size() (n int) { var l int _ = l @@ -1421,8 +1863,12 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1435,6 +1881,12 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResponseHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseHeader: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -1442,6 +1894,9 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } var stringLen uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1468,6 +1923,9 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } m.ClusterId = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1484,6 +1942,9 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } m.MemberId = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1500,6 +1961,9 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } m.Revision = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1516,6 +1980,9 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } m.RaftTerm = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1527,15 +1994,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -1550,14 +2009,21 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *RangeRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1570,6 +2036,12 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RangeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RangeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -1577,6 +2049,9 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1594,7 +2069,10 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append([]byte{}, data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } iNdEx = postIndex case 2: if wireType != 2 { @@ -1602,6 +2080,9 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1619,7 +2100,10 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = append([]byte{}, data[iNdEx:postIndex]...) + m.RangeEnd = append(m.RangeEnd[:0], data[iNdEx:postIndex]...) + if m.RangeEnd == nil { + m.RangeEnd = []byte{} + } iNdEx = postIndex case 3: if wireType != 0 { @@ -1627,6 +2111,9 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } m.Limit = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1643,6 +2130,9 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } m.Revision = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1654,15 +2144,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -1677,14 +2159,21 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *RangeResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1697,6 +2186,12 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RangeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RangeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -1704,6 +2199,9 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1734,6 +2232,9 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1762,6 +2263,9 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1774,15 +2278,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } m.More = bool(v != 0) default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -1797,14 +2293,21 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *PutRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1817,6 +2320,12 @@ func (m *PutRequest) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PutRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PutRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -1824,6 +2333,9 @@ func (m *PutRequest) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1841,7 +2353,10 @@ func (m *PutRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append([]byte{}, data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } iNdEx = postIndex case 2: if wireType != 2 { @@ -1849,6 +2364,9 @@ func (m *PutRequest) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1866,18 +2384,13 @@ func (m *PutRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = append([]byte{}, data[iNdEx:postIndex]...) + m.Value = append(m.Value[:0], data[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -1892,14 +2405,21 @@ func (m *PutRequest) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *PutResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1912,6 +2432,12 @@ func (m *PutResponse) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PutResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PutResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -1919,6 +2445,9 @@ func (m *PutResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1944,15 +2473,7 @@ func (m *PutResponse) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -1967,14 +2488,21 @@ func (m *PutResponse) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *DeleteRangeRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1987,6 +2515,12 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteRangeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteRangeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -1994,6 +2528,9 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2011,7 +2548,10 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append([]byte{}, data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } iNdEx = postIndex case 2: if wireType != 2 { @@ -2019,6 +2559,9 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2036,18 +2579,13 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = append([]byte{}, data[iNdEx:postIndex]...) + m.RangeEnd = append(m.RangeEnd[:0], data[iNdEx:postIndex]...) + if m.RangeEnd == nil { + m.RangeEnd = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2062,14 +2600,21 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *DeleteRangeResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2082,6 +2627,12 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteRangeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteRangeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -2089,6 +2640,9 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2114,15 +2668,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2137,14 +2683,21 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *RequestUnion) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2157,6 +2710,12 @@ func (m *RequestUnion) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RequestUnion: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestUnion: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -2164,6 +2723,9 @@ func (m *RequestUnion) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2181,12 +2743,11 @@ func (m *RequestUnion) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RequestRange == nil { - m.RequestRange = &RangeRequest{} - } - if err := m.RequestRange.Unmarshal(data[iNdEx:postIndex]); err != nil { + v := &RangeRequest{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } + m.Request = &RequestUnion_RequestRange{v} iNdEx = postIndex case 2: if wireType != 2 { @@ -2194,6 +2755,9 @@ func (m *RequestUnion) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2211,12 +2775,11 @@ func (m *RequestUnion) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RequestPut == nil { - m.RequestPut = &PutRequest{} - } - if err := m.RequestPut.Unmarshal(data[iNdEx:postIndex]); err != nil { + v := &PutRequest{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } + m.Request = &RequestUnion_RequestPut{v} iNdEx = postIndex case 3: if wireType != 2 { @@ -2224,6 +2787,9 @@ func (m *RequestUnion) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2241,23 +2807,14 @@ func (m *RequestUnion) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RequestDeleteRange == nil { - m.RequestDeleteRange = &DeleteRangeRequest{} - } - if err := m.RequestDeleteRange.Unmarshal(data[iNdEx:postIndex]); err != nil { + v := &DeleteRangeRequest{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } + m.Request = &RequestUnion_RequestDeleteRange{v} iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2272,14 +2829,21 @@ func (m *RequestUnion) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *ResponseUnion) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2292,6 +2856,12 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResponseUnion: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseUnion: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -2299,6 +2869,9 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2316,12 +2889,11 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ResponseRange == nil { - m.ResponseRange = &RangeResponse{} - } - if err := m.ResponseRange.Unmarshal(data[iNdEx:postIndex]); err != nil { + v := &RangeResponse{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } + m.Response = &ResponseUnion_ResponseRange{v} iNdEx = postIndex case 2: if wireType != 2 { @@ -2329,6 +2901,9 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2346,12 +2921,11 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ResponsePut == nil { - m.ResponsePut = &PutResponse{} - } - if err := m.ResponsePut.Unmarshal(data[iNdEx:postIndex]); err != nil { + v := &PutResponse{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } + m.Response = &ResponseUnion_ResponsePut{v} iNdEx = postIndex case 3: if wireType != 2 { @@ -2359,6 +2933,9 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2376,23 +2953,14 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ResponseDeleteRange == nil { - m.ResponseDeleteRange = &DeleteRangeResponse{} - } - if err := m.ResponseDeleteRange.Unmarshal(data[iNdEx:postIndex]); err != nil { + v := &DeleteRangeResponse{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } + m.Response = &ResponseUnion_ResponseDeleteRange{v} iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2407,14 +2975,21 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *Compare) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2427,6 +3002,12 @@ func (m *Compare) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Compare: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Compare: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -2434,6 +3015,9 @@ func (m *Compare) Unmarshal(data []byte) error { } m.Result = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2450,6 +3034,9 @@ func (m *Compare) Unmarshal(data []byte) error { } m.Target = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2466,6 +3053,9 @@ func (m *Compare) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2483,62 +3073,80 @@ func (m *Compare) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append([]byte{}, data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } iNdEx = postIndex case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } - m.Version = 0 + var v int64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ - m.Version |= (int64(b) & 0x7F) << shift + v |= (int64(b) & 0x7F) << shift if b < 0x80 { break } } + m.TargetUnion = &Compare_Version{v} case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field CreateRevision", wireType) } - m.CreateRevision = 0 + var v int64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ - m.CreateRevision |= (int64(b) & 0x7F) << shift + v |= (int64(b) & 0x7F) << shift if b < 0x80 { break } } + m.TargetUnion = &Compare_CreateRevision{v} case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ModRevision", wireType) } - m.ModRevision = 0 + var v int64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ - m.ModRevision |= (int64(b) & 0x7F) << shift + v |= (int64(b) & 0x7F) << shift if b < 0x80 { break } } + m.TargetUnion = &Compare_ModRevision{v} case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2556,18 +3164,12 @@ func (m *Compare) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = append([]byte{}, data[iNdEx:postIndex]...) + v := make([]byte, postIndex-iNdEx) + copy(v, data[iNdEx:postIndex]) + m.TargetUnion = &Compare_Value{v} iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2582,14 +3184,21 @@ func (m *Compare) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *TxnRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2602,6 +3211,12 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxnRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxnRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -2609,6 +3224,9 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2637,6 +3255,9 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2665,6 +3286,9 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2688,15 +3312,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2711,14 +3327,21 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *TxnResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2731,6 +3354,12 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxnResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxnResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -2738,6 +3367,9 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2768,6 +3400,9 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2785,6 +3420,9 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2808,15 +3446,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2831,14 +3461,21 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *CompactionRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2851,6 +3488,12 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CompactionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CompactionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -2858,6 +3501,9 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { } m.Revision = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2869,15 +3515,7 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2892,14 +3530,21 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *CompactionResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2912,6 +3557,12 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CompactionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CompactionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -2919,6 +3570,9 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -2944,15 +3598,7 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) if err != nil { return err @@ -2967,6 +3613,9 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipRpc(data []byte) (n int, err error) { @@ -2975,6 +3624,9 @@ func skipRpc(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -2988,7 +3640,10 @@ func skipRpc(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -3004,6 +3659,9 @@ func skipRpc(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -3024,6 +3682,9 @@ func skipRpc(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -3059,4 +3720,5 @@ func skipRpc(data []byte) (n int, err error) { var ( ErrInvalidLengthRpc = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRpc = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go index 42282bea3d..170c61cd4b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go @@ -174,12 +174,17 @@ type EtcdServer struct { // configuration is considered static for the lifetime of the EtcdServer. func NewServer(cfg *ServerConfig) (*EtcdServer, error) { st := store.New(StoreClusterPrefix, StoreKeysPrefix) + var w *wal.WAL var n raft.Node var s *raft.MemoryStorage var id types.ID var cl *cluster + if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil { + return nil, fmt.Errorf("cannot access data directory: %v", terr) + } + // Run the migrations. dataVer, err := version.DetectDataDir(cfg.DataDir) if err != nil { @@ -189,11 +194,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { return nil, err } - err = os.MkdirAll(cfg.MemberDir(), privateDirMode) - if err != nil && err != os.ErrExist { - return nil, err - } - haveWAL := wal.Exist(cfg.WALDir()) ss := snap.New(cfg.SnapDir()) @@ -255,10 +255,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { cfg.PrintWithInitial() id, n, s, w = startNode(cfg, cl, cl.MemberIDs()) case haveWAL: - if err := fileutil.IsDirWriteable(cfg.DataDir); err != nil { - return nil, fmt.Errorf("cannot write to data directory: %v", err) - } - if err := fileutil.IsDirWriteable(cfg.MemberDir()); err != nil { return nil, fmt.Errorf("cannot write to member directory: %v", err) } @@ -295,6 +291,10 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { return nil, fmt.Errorf("unsupported bootstrap config") } + if terr := fileutil.TouchDirAll(cfg.MemberDir()); terr != nil { + return nil, fmt.Errorf("cannot access member directory: %v", terr) + } + sstats := &stats.ServerStats{ Name: cfg.Name, ID: id.String(), diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go index 06cb68140a..9d2972518b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go @@ -19,6 +19,7 @@ import ( pb "github.com/coreos/etcd/etcdserver/etcdserverpb" dstorage "github.com/coreos/etcd/storage" + "github.com/coreos/etcd/storage/storagepb" "github.com/gogo/protobuf/proto" "golang.org/x/net/context" ) @@ -106,17 +107,24 @@ func doTxn(kv dstorage.KV, rt *pb.TxnRequest) *pb.TxnResponse { } func doUnion(kv dstorage.KV, union *pb.RequestUnion) *pb.ResponseUnion { - switch { - case union.RequestRange != nil: - return &pb.ResponseUnion{ResponseRange: doRange(kv, union.RequestRange)} - case union.RequestPut != nil: - return &pb.ResponseUnion{ResponsePut: doPut(kv, union.RequestPut)} - case union.RequestDeleteRange != nil: - return &pb.ResponseUnion{ResponseDeleteRange: doDeleteRange(kv, union.RequestDeleteRange)} + switch tv := union.Request.(type) { + case *pb.RequestUnion_RequestRange: + if tv.RequestRange != nil { + return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseRange{ResponseRange: doRange(kv, tv.RequestRange)}} + } + case *pb.RequestUnion_RequestPut: + if tv.RequestPut != nil { + return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponsePut{ResponsePut: doPut(kv, tv.RequestPut)}} + } + case *pb.RequestUnion_RequestDeleteRange: + if tv.RequestDeleteRange != nil { + return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseDeleteRange{ResponseDeleteRange: doDeleteRange(kv, tv.RequestDeleteRange)}} + } default: // empty union return nil } + return nil } func doCompare(kv dstorage.KV, c *pb.Compare) (int64, bool) { @@ -124,20 +132,35 @@ func doCompare(kv dstorage.KV, c *pb.Compare) (int64, bool) { if err != nil { return rev, false } - - ckv := ckvs[0] + var ckv storagepb.KeyValue + if len(ckvs) != 0 { + ckv = ckvs[0] + } // -1 is less, 0 is equal, 1 is greater var result int switch c.Target { case pb.Compare_VALUE: - result = bytes.Compare(ckv.Value, c.Value) + tv, _ := c.TargetUnion.(*pb.Compare_Value) + if tv != nil { + result = bytes.Compare(ckv.Value, tv.Value) + } case pb.Compare_CREATE: - result = compareInt64(ckv.CreateRevision, c.CreateRevision) + tv, _ := c.TargetUnion.(*pb.Compare_CreateRevision) + if tv != nil { + result = compareInt64(ckv.CreateRevision, tv.CreateRevision) + } + case pb.Compare_MOD: - result = compareInt64(ckv.ModRevision, c.ModRevision) + tv, _ := c.TargetUnion.(*pb.Compare_ModRevision) + if tv != nil { + result = compareInt64(ckv.ModRevision, tv.ModRevision) + } case pb.Compare_VERSION: - result = compareInt64(ckv.Version, c.Version) + tv, _ := c.TargetUnion.(*pb.Compare_Version) + if tv != nil { + result = compareInt64(ckv.Version, tv.Version) + } } switch c.Result { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go index b052553c11..60552a7703 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go @@ -25,6 +25,8 @@ import ( const ( privateFileMode = 0600 + // owner can make/remove files inside the directory + privateDirMode = 0700 ) var ( @@ -55,3 +57,13 @@ func ReadDir(dirpath string) ([]string, error) { sort.Strings(names) return names, nil } + +// TouchDirAll is simliar to os.MkdirAll. It creates directories with 0700 permission if any directory +// does not exists. TouchDirAll also ensures the given directory is writable. +func TouchDirAll(dir string) error { + err := os.MkdirAll(dir, privateDirMode) + if err != nil && err != os.ErrExist { + return err + } + return IsDirWriteable(dir) +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/ioutil/util.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/ioutil/util.go new file mode 100644 index 0000000000..d7ed18b454 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/ioutil/util.go @@ -0,0 +1,41 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ioutil + +import ( + "io" + "os" +) + +// WriteAndSyncFile behaviors just like ioutil.WriteFile in standard library +// but calls Sync before closing the file. WriteAndSyncFile guarantees the data +// is synced if there is no error returned. +func WriteAndSyncFile(filename string, data []byte, perm os.FileMode) error { + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) + if err != nil { + return err + } + n, err := f.Write(data) + if err == nil && n < len(data) { + err = io.ErrShortWrite + } + if err == nil { + err = f.Sync() + } + if err1 := f.Close(); err == nil { + err = err1 + } + return err +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go index 6f580619ab..1fe1ba80dd 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go @@ -21,17 +21,19 @@ import ( "time" ) -// NewKeepAliveListener returns a listener that listens on the given address. -// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html -func NewKeepAliveListener(addr string, scheme string, info TLSInfo) (net.Listener, error) { - l, err := net.Listen("tcp", addr) - if err != nil { - return nil, err - } +type keepAliveConn interface { + SetKeepAlive(bool) error + SetKeepAlivePeriod(d time.Duration) error +} +// NewKeepAliveListener returns a listener that listens on the given address. +// Be careful when wrap around KeepAliveListener with another Listener if TLSInfo is not nil. +// Some pkgs (like go/http) might expect Listener to return TLSConn type to start TLS handshake. +// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html +func NewKeepAliveListener(l net.Listener, scheme string, info TLSInfo) (net.Listener, error) { if scheme == "https" { if info.Empty() { - return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", scheme+"://"+addr) + return nil, fmt.Errorf("cannot listen on TLS for given listener: KeyFile and CertFile are not presented") } cfg, err := info.ServerConfig() if err != nil { @@ -53,13 +55,13 @@ func (kln *keepaliveListener) Accept() (net.Conn, error) { if err != nil { return nil, err } - tcpc := c.(*net.TCPConn) + kac := c.(keepAliveConn) // detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl // default on linux: 30 + 8 * 30 // default on osx: 30 + 8 * 75 - tcpc.SetKeepAlive(true) - tcpc.SetKeepAlivePeriod(30 * time.Second) - return tcpc, nil + kac.SetKeepAlive(true) + kac.SetKeepAlivePeriod(30 * time.Second) + return c, nil } // A tlsKeepaliveListener implements a network listener (net.Listener) for TLS connections. @@ -75,12 +77,12 @@ func (l *tlsKeepaliveListener) Accept() (c net.Conn, err error) { if err != nil { return } - tcpc := c.(*net.TCPConn) + kac := c.(keepAliveConn) // detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl // default on linux: 30 + 8 * 30 // default on osx: 30 + 8 * 75 - tcpc.SetKeepAlive(true) - tcpc.SetKeepAlivePeriod(30 * time.Second) + kac.SetKeepAlive(true) + kac.SetKeepAlivePeriod(30 * time.Second) c = tls.Server(c, l.config) return } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go new file mode 100644 index 0000000000..8a81a6b93f --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go @@ -0,0 +1,70 @@ +// Copyright 2013 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 netutil provides network utility functions, complementing the more +// common ones in the net package. +package transport + +import ( + "errors" + "net" + "sync" + "time" +) + +var ( + ErrNotTCP = errors.New("only tcp connections have keepalive") +) + +// LimitListener returns a Listener that accepts at most n simultaneous +// connections from the provided Listener. +func LimitListener(l net.Listener, n int) net.Listener { + return &limitListener{l, make(chan struct{}, n)} +} + +type limitListener struct { + net.Listener + sem chan struct{} +} + +func (l *limitListener) acquire() { l.sem <- struct{}{} } +func (l *limitListener) release() { <-l.sem } + +func (l *limitListener) Accept() (net.Conn, error) { + l.acquire() + c, err := l.Listener.Accept() + if err != nil { + l.release() + return nil, err + } + return &limitListenerConn{Conn: c, release: l.release}, nil +} + +type limitListenerConn struct { + net.Conn + releaseOnce sync.Once + release func() +} + +func (l *limitListenerConn) Close() error { + err := l.Conn.Close() + l.releaseOnce.Do(l.release) + return err +} + +func (l *limitListenerConn) SetKeepAlive(doKeepAlive bool) error { + tcpc, ok := l.Conn.(*net.TCPConn) + if !ok { + return ErrNotTCP + } + return tcpc.SetKeepAlive(doKeepAlive) +} + +func (l *limitListenerConn) SetKeepAlivePeriod(d time.Duration) error { + tcpc, ok := l.Conn.(*net.TCPConn) + if !ok { + return ErrNotTCP + } + return tcpc.SetKeepAlivePeriod(d) +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go index 60cb517ad8..6c3bd48017 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go @@ -19,16 +19,19 @@ */ package raftpb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" + + proto "github.com/gogo/protobuf/proto" +) + import math "math" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" - import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type EntryType int32 @@ -164,10 +167,10 @@ func (x *ConfChangeType) UnmarshalJSON(data []byte) error { } type Entry struct { - Type EntryType `protobuf:"varint,1,opt,enum=raftpb.EntryType" json:"Type"` - Term uint64 `protobuf:"varint,2,opt" json:"Term"` - Index uint64 `protobuf:"varint,3,opt" json:"Index"` - Data []byte `protobuf:"bytes,4,opt" json:"Data,omitempty"` + Type EntryType `protobuf:"varint,1,opt,name=Type,enum=raftpb.EntryType" json:"Type"` + Term uint64 `protobuf:"varint,2,opt,name=Term" json:"Term"` + Index uint64 `protobuf:"varint,3,opt,name=Index" json:"Index"` + Data []byte `protobuf:"bytes,4,opt,name=Data" json:"Data,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -236,10 +239,10 @@ func (m *ConfState) String() string { return proto.CompactTextString(m) } func (*ConfState) ProtoMessage() {} type ConfChange struct { - ID uint64 `protobuf:"varint,1,opt" json:"ID"` - Type ConfChangeType `protobuf:"varint,2,opt,enum=raftpb.ConfChangeType" json:"Type"` - NodeID uint64 `protobuf:"varint,3,opt" json:"NodeID"` - Context []byte `protobuf:"bytes,4,opt" json:"Context,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"` + Type ConfChangeType `protobuf:"varint,2,opt,name=Type,enum=raftpb.ConfChangeType" json:"Type"` + NodeID uint64 `protobuf:"varint,3,opt,name=NodeID" json:"NodeID"` + Context []byte `protobuf:"bytes,4,opt,name=Context" json:"Context,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -248,6 +251,13 @@ func (m *ConfChange) String() string { return proto.CompactTextString(m) } func (*ConfChange) ProtoMessage() {} func init() { + proto.RegisterType((*Entry)(nil), "raftpb.Entry") + proto.RegisterType((*SnapshotMetadata)(nil), "raftpb.SnapshotMetadata") + proto.RegisterType((*Snapshot)(nil), "raftpb.Snapshot") + proto.RegisterType((*Message)(nil), "raftpb.Message") + proto.RegisterType((*HardState)(nil), "raftpb.HardState") + proto.RegisterType((*ConfState)(nil), "raftpb.ConfState") + proto.RegisterType((*ConfChange)(nil), "raftpb.ConfChange") proto.RegisterEnum("raftpb.EntryType", EntryType_name, EntryType_value) proto.RegisterEnum("raftpb.MessageType", MessageType_name, MessageType_value) proto.RegisterEnum("raftpb.ConfChangeType", ConfChangeType_name, ConfChangeType_value) @@ -681,8 +691,12 @@ func (m *Entry) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -695,6 +709,12 @@ func (m *Entry) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Entry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -702,6 +722,9 @@ func (m *Entry) Unmarshal(data []byte) error { } m.Type = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -718,6 +741,9 @@ func (m *Entry) Unmarshal(data []byte) error { } m.Term = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -734,6 +760,9 @@ func (m *Entry) Unmarshal(data []byte) error { } m.Index = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -750,6 +779,9 @@ func (m *Entry) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -767,18 +799,13 @@ func (m *Entry) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append([]byte{}, data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -794,14 +821,21 @@ func (m *Entry) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *SnapshotMetadata) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -814,6 +848,12 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SnapshotMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -821,6 +861,9 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -848,6 +891,9 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } m.Index = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -864,6 +910,9 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } m.Term = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -875,15 +924,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -899,14 +940,21 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *Snapshot) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -919,6 +967,12 @@ func (m *Snapshot) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Snapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -926,6 +980,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -943,7 +1000,10 @@ func (m *Snapshot) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append([]byte{}, data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } iNdEx = postIndex case 2: if wireType != 2 { @@ -951,6 +1011,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -973,15 +1036,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -997,14 +1052,21 @@ func (m *Snapshot) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *Message) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1017,6 +1079,12 @@ func (m *Message) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Message: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -1024,6 +1092,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.Type = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1040,6 +1111,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.To = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1056,6 +1130,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.From = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1072,6 +1149,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.Term = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1088,6 +1168,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.LogTerm = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1104,6 +1187,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.Index = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1120,6 +1206,9 @@ func (m *Message) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1148,6 +1237,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.Commit = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1164,6 +1256,9 @@ func (m *Message) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1191,6 +1286,9 @@ func (m *Message) Unmarshal(data []byte) error { } var v int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1208,6 +1306,9 @@ func (m *Message) Unmarshal(data []byte) error { } m.RejectHint = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1219,15 +1320,7 @@ func (m *Message) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -1243,14 +1336,21 @@ func (m *Message) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *HardState) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1263,6 +1363,12 @@ func (m *HardState) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HardState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HardState: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -1270,6 +1376,9 @@ func (m *HardState) Unmarshal(data []byte) error { } m.Term = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1286,6 +1395,9 @@ func (m *HardState) Unmarshal(data []byte) error { } m.Vote = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1302,6 +1414,9 @@ func (m *HardState) Unmarshal(data []byte) error { } m.Commit = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1313,15 +1428,7 @@ func (m *HardState) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -1337,14 +1444,21 @@ func (m *HardState) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *ConfState) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1357,6 +1471,12 @@ func (m *ConfState) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConfState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConfState: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -1364,6 +1484,9 @@ func (m *ConfState) Unmarshal(data []byte) error { } var v uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1376,15 +1499,7 @@ func (m *ConfState) Unmarshal(data []byte) error { } m.Nodes = append(m.Nodes, v) default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -1400,14 +1515,21 @@ func (m *ConfState) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *ConfChange) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1420,6 +1542,12 @@ func (m *ConfChange) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConfChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConfChange: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -1427,6 +1555,9 @@ func (m *ConfChange) Unmarshal(data []byte) error { } m.ID = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1443,6 +1574,9 @@ func (m *ConfChange) Unmarshal(data []byte) error { } m.Type = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1459,6 +1593,9 @@ func (m *ConfChange) Unmarshal(data []byte) error { } m.NodeID = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1475,6 +1612,9 @@ func (m *ConfChange) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -1492,18 +1632,13 @@ func (m *ConfChange) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Context = append([]byte{}, data[iNdEx:postIndex]...) + m.Context = append(m.Context[:0], data[iNdEx:postIndex]...) + if m.Context == nil { + m.Context = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRaft(data[iNdEx:]) if err != nil { return err @@ -1519,6 +1654,9 @@ func (m *ConfChange) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipRaft(data []byte) (n int, err error) { @@ -1527,6 +1665,9 @@ func skipRaft(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaft + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -1540,7 +1681,10 @@ func skipRaft(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaft + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -1556,6 +1700,9 @@ func skipRaft(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaft + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -1576,6 +1723,9 @@ func skipRaft(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRaft + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -1611,4 +1761,5 @@ func skipRaft(data []byte) (n int, err error) { var ( ErrInvalidLengthRaft = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRaft = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go index 1013dbbfc8..5d1d21ab31 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go @@ -13,16 +13,19 @@ */ package snappb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" + + proto "github.com/gogo/protobuf/proto" +) + import math "math" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" - import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type Snapshot struct { @@ -35,6 +38,9 @@ func (m *Snapshot) Reset() { *m = Snapshot{} } func (m *Snapshot) String() string { return proto.CompactTextString(m) } func (*Snapshot) ProtoMessage() {} +func init() { + proto.RegisterType((*Snapshot)(nil), "snappb.snapshot") +} func (m *Snapshot) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -123,8 +129,12 @@ func (m *Snapshot) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnap + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -137,6 +147,12 @@ func (m *Snapshot) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: snapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: snapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -144,6 +160,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } m.Crc = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnap + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -160,6 +179,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnap + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -177,18 +199,13 @@ func (m *Snapshot) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append([]byte{}, data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipSnap(data[iNdEx:]) if err != nil { return err @@ -204,6 +221,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipSnap(data []byte) (n int, err error) { @@ -212,6 +232,9 @@ func skipSnap(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSnap + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -225,7 +248,10 @@ func skipSnap(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSnap + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -241,6 +267,9 @@ func skipSnap(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSnap + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -261,6 +290,9 @@ func skipSnap(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSnap + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -296,4 +328,5 @@ func skipSnap(data []byte) (n int, err error) { var ( ErrInvalidLengthSnap = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSnap = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go index 03f6fe98ed..2ac835a1ae 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go @@ -14,15 +14,20 @@ */ package storagepb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +import math "math" import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf type Event_EventType int32 @@ -76,6 +81,8 @@ func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} func init() { + proto.RegisterType((*KeyValue)(nil), "storagepb.KeyValue") + proto.RegisterType((*Event)(nil), "storagepb.Event") proto.RegisterEnum("storagepb.Event_EventType", Event_EventType_name, Event_EventType_value) } func (m *KeyValue) Marshal() (data []byte, err error) { @@ -244,8 +251,12 @@ func (m *KeyValue) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -258,6 +269,12 @@ func (m *KeyValue) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KeyValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KeyValue: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 2 { @@ -265,6 +282,9 @@ func (m *KeyValue) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -282,7 +302,10 @@ func (m *KeyValue) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append([]byte{}, data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } iNdEx = postIndex case 2: if wireType != 0 { @@ -290,6 +313,9 @@ func (m *KeyValue) Unmarshal(data []byte) error { } m.CreateRevision = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -306,6 +332,9 @@ func (m *KeyValue) Unmarshal(data []byte) error { } m.ModRevision = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -322,6 +351,9 @@ func (m *KeyValue) Unmarshal(data []byte) error { } m.Version = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -338,6 +370,9 @@ func (m *KeyValue) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -355,18 +390,13 @@ func (m *KeyValue) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = append([]byte{}, data[iNdEx:postIndex]...) + m.Value = append(m.Value[:0], data[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipKv(data[iNdEx:]) if err != nil { return err @@ -381,14 +411,21 @@ func (m *KeyValue) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *Event) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -401,6 +438,12 @@ func (m *Event) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Event: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -408,6 +451,9 @@ func (m *Event) Unmarshal(data []byte) error { } m.Type = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -424,6 +470,9 @@ func (m *Event) Unmarshal(data []byte) error { } var msglen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -449,15 +498,7 @@ func (m *Event) Unmarshal(data []byte) error { } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipKv(data[iNdEx:]) if err != nil { return err @@ -472,6 +513,9 @@ func (m *Event) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipKv(data []byte) (n int, err error) { @@ -480,6 +524,9 @@ func skipKv(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKv + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -493,7 +540,10 @@ func skipKv(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKv + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -509,6 +559,9 @@ func skipKv(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKv + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -529,6 +582,9 @@ func skipKv(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKv + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -564,4 +620,5 @@ func skipKv(data []byte) (n int, err error) { var ( ErrInvalidLengthKv = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowKv = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go b/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go index a2436553e6..5e2b778547 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go @@ -27,7 +27,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "2.1.0" - Version = "2.2.2+git" + Version = "2.2.5" // Git SHA Value will be set during build GitSHA = "Not provided (use ./build instead of go build)" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go index a9b38a47ef..638bdc3b69 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go @@ -14,16 +14,19 @@ */ package walpb -import proto "github.com/gogo/protobuf/proto" +import ( + "fmt" + + proto "github.com/gogo/protobuf/proto" +) + import math "math" -// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" - import io "io" -import fmt "fmt" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type Record struct { @@ -47,6 +50,10 @@ func (m *Snapshot) Reset() { *m = Snapshot{} } func (m *Snapshot) String() string { return proto.CompactTextString(m) } func (*Snapshot) ProtoMessage() {} +func init() { + proto.RegisterType((*Record)(nil), "walpb.Record") + proto.RegisterType((*Snapshot)(nil), "walpb.Snapshot") +} func (m *Record) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -177,8 +184,12 @@ func (m *Record) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -191,6 +202,12 @@ func (m *Record) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Record: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -198,6 +215,9 @@ func (m *Record) Unmarshal(data []byte) error { } m.Type = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -214,6 +234,9 @@ func (m *Record) Unmarshal(data []byte) error { } m.Crc = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -230,6 +253,9 @@ func (m *Record) Unmarshal(data []byte) error { } var byteLen int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -247,18 +273,13 @@ func (m *Record) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append([]byte{}, data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } iNdEx = postIndex default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRecord(data[iNdEx:]) if err != nil { return err @@ -274,14 +295,21 @@ func (m *Record) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func (m *Snapshot) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { + preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -294,6 +322,12 @@ func (m *Snapshot) Unmarshal(data []byte) error { } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Snapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } switch fieldNum { case 1: if wireType != 0 { @@ -301,6 +335,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } m.Index = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -317,6 +354,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } m.Term = 0 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } if iNdEx >= l { return io.ErrUnexpectedEOF } @@ -328,15 +368,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { } } default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - iNdEx -= sizeOfWire + iNdEx = preIndex skippy, err := skipRecord(data[iNdEx:]) if err != nil { return err @@ -352,6 +384,9 @@ func (m *Snapshot) Unmarshal(data []byte) error { } } + if iNdEx > l { + return io.ErrUnexpectedEOF + } return nil } func skipRecord(data []byte) (n int, err error) { @@ -360,6 +395,9 @@ func skipRecord(data []byte) (n int, err error) { for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -373,7 +411,10 @@ func skipRecord(data []byte) (n int, err error) { wireType := int(wire & 0x7) switch wireType { case 0: - for { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -389,6 +430,9 @@ func skipRecord(data []byte) (n int, err error) { case 2: var length int for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -409,6 +453,9 @@ func skipRecord(data []byte) (n int, err error) { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } @@ -444,4 +491,5 @@ func skipRecord(data []byte) (n int, err error) { var ( ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRecord = fmt.Errorf("proto: integer overflow") ) diff --git a/Godeps/_workspace/src/github.com/coreos/rkt/LICENSE b/Godeps/_workspace/src/github.com/coreos/rkt/LICENSE index e06d208186..f152ee101e 100644 --- a/Godeps/_workspace/src/github.com/coreos/rkt/LICENSE +++ b/Godeps/_workspace/src/github.com/coreos/rkt/LICENSE @@ -200,3 +200,28 @@ Apache License See the License for the specific language governing permissions and limitations under the License. + +Third Party Sources Bundled + +This project includes code derived from the MIT licensed naegelejd/go-acl +project. Here's a copy of its license: + + Copyright (c) 2015 Joseph Naegele + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/README.md b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/README.md index d4428e1df3..738ae2e761 100644 --- a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/README.md +++ b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/README.md @@ -2,8 +2,6 @@ The API defined here is proposed, experimental, and (for now) subject to change at any time. -**Do not use it.** - If you think you want to use it, or for any other queries, contact or file an [issue](https://github.com/coreos/rkt/issues/new) For more information, see: diff --git a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.pb.go b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.pb.go index 4195b02429..1b64bb03a3 100644 --- a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.pb.go @@ -51,6 +51,10 @@ 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. +const _ = proto.ProtoPackageIsVersion1 + // ImageType defines the supported image type. type ImageType int32 @@ -77,6 +81,7 @@ var ImageType_value = map[string]int32{ func (x ImageType) String() string { return proto.EnumName(ImageType_name, int32(x)) } +func (ImageType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } // AppState defines the possible states of the app. type AppState int32 @@ -101,6 +106,7 @@ var AppState_value = map[string]int32{ func (x AppState) String() string { return proto.EnumName(AppState_name, int32(x)) } +func (AppState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } // PodState defines the possible states of the pod. // See https://github.com/coreos/rkt/blob/master/Documentation/devel/pod-lifecycle.md for a detailed @@ -148,6 +154,7 @@ var PodState_value = map[string]int32{ func (x PodState) String() string { return proto.EnumName(PodState_name, int32(x)) } +func (PodState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } // EventType defines the type of the events that will be received via ListenEvents(). type EventType int32 @@ -196,6 +203,7 @@ var EventType_value = map[string]int32{ func (x EventType) String() string { return proto.EnumName(EventType_name, int32(x)) } +func (EventType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } // ImageFormat defines the format of the image. type ImageFormat struct { @@ -205,9 +213,10 @@ type ImageFormat struct { Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` } -func (m *ImageFormat) Reset() { *m = ImageFormat{} } -func (m *ImageFormat) String() string { return proto.CompactTextString(m) } -func (*ImageFormat) ProtoMessage() {} +func (m *ImageFormat) Reset() { *m = ImageFormat{} } +func (m *ImageFormat) String() string { return proto.CompactTextString(m) } +func (*ImageFormat) ProtoMessage() {} +func (*ImageFormat) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } // Image describes the image's information. type Image struct { @@ -232,9 +241,10 @@ type Image struct { Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"` } -func (m *Image) Reset() { *m = Image{} } -func (m *Image) String() string { return proto.CompactTextString(m) } -func (*Image) ProtoMessage() {} +func (m *Image) Reset() { *m = Image{} } +func (m *Image) String() string { return proto.CompactTextString(m) } +func (*Image) ProtoMessage() {} +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *Image) GetBaseFormat() *ImageFormat { if m != nil { @@ -260,9 +270,10 @@ type Network struct { Ipv6 string `protobuf:"bytes,3,opt,name=ipv6" json:"ipv6,omitempty"` } -func (m *Network) Reset() { *m = Network{} } -func (m *Network) String() string { return proto.CompactTextString(m) } -func (*Network) ProtoMessage() {} +func (m *Network) Reset() { *m = Network{} } +func (m *Network) String() string { return proto.CompactTextString(m) } +func (*Network) ProtoMessage() {} +func (*Network) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } // App describes the information of an app that's running in a pod. type App struct { @@ -280,9 +291,10 @@ type App struct { Annotations []*KeyValue `protobuf:"bytes,5,rep,name=annotations" json:"annotations,omitempty"` } -func (m *App) Reset() { *m = App{} } -func (m *App) String() string { return proto.CompactTextString(m) } -func (*App) ProtoMessage() {} +func (m *App) Reset() { *m = App{} } +func (m *App) String() string { return proto.CompactTextString(m) } +func (*App) ProtoMessage() {} +func (*App) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (m *App) GetImage() *Image { if m != nil { @@ -327,9 +339,10 @@ type Pod struct { Annotations []*KeyValue `protobuf:"bytes,7,rep,name=annotations" json:"annotations,omitempty"` } -func (m *Pod) Reset() { *m = Pod{} } -func (m *Pod) String() string { return proto.CompactTextString(m) } -func (*Pod) ProtoMessage() {} +func (m *Pod) Reset() { *m = Pod{} } +func (m *Pod) String() string { return proto.CompactTextString(m) } +func (*Pod) ProtoMessage() {} +func (*Pod) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (m *Pod) GetApps() []*App { if m != nil { @@ -354,14 +367,15 @@ func (m *Pod) GetAnnotations() []*KeyValue { type KeyValue struct { // Key part of the key-value pair. - Key string `protobuf:"bytes,1,opt" json:"Key,omitempty"` + Key string `protobuf:"bytes,1,opt,name=Key" json:"Key,omitempty"` // Value part of the key-value pair. Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` } -func (m *KeyValue) Reset() { *m = KeyValue{} } -func (m *KeyValue) String() string { return proto.CompactTextString(m) } -func (*KeyValue) ProtoMessage() {} +func (m *KeyValue) Reset() { *m = KeyValue{} } +func (m *KeyValue) String() string { return proto.CompactTextString(m) } +func (*KeyValue) ProtoMessage() {} +func (*KeyValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } // PodFilter defines the condition that the returned pods need to satisfy in ListPods(). // The conditions are combined by 'AND', and different filters are combined by 'OR'. @@ -380,9 +394,10 @@ type PodFilter struct { Annotations []*KeyValue `protobuf:"bytes,6,rep,name=annotations" json:"annotations,omitempty"` } -func (m *PodFilter) Reset() { *m = PodFilter{} } -func (m *PodFilter) String() string { return proto.CompactTextString(m) } -func (*PodFilter) ProtoMessage() {} +func (m *PodFilter) Reset() { *m = PodFilter{} } +func (m *PodFilter) String() string { return proto.CompactTextString(m) } +func (*PodFilter) ProtoMessage() {} +func (*PodFilter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (m *PodFilter) GetAnnotations() []*KeyValue { if m != nil { @@ -413,11 +428,14 @@ type ImageFilter struct { ImportedBefore int64 `protobuf:"varint,7,opt,name=imported_before" json:"imported_before,omitempty"` // If not empty, the images that have all of the annotations will be returned. Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"` + // If not empty, the images that have any of the exact full names will be returned. + FullNames []string `protobuf:"bytes,9,rep,name=full_names" json:"full_names,omitempty"` } -func (m *ImageFilter) Reset() { *m = ImageFilter{} } -func (m *ImageFilter) String() string { return proto.CompactTextString(m) } -func (*ImageFilter) ProtoMessage() {} +func (m *ImageFilter) Reset() { *m = ImageFilter{} } +func (m *ImageFilter) String() string { return proto.CompactTextString(m) } +func (*ImageFilter) ProtoMessage() {} +func (*ImageFilter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (m *ImageFilter) GetLabels() []*KeyValue { if m != nil { @@ -443,9 +461,10 @@ type Info struct { ApiVersion string `protobuf:"bytes,3,opt,name=api_version" json:"api_version,omitempty"` } -func (m *Info) Reset() { *m = Info{} } -func (m *Info) String() string { return proto.CompactTextString(m) } -func (*Info) ProtoMessage() {} +func (m *Info) Reset() { *m = Info{} } +func (m *Info) String() string { return proto.CompactTextString(m) } +func (*Info) ProtoMessage() {} +func (*Info) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } // Event describes the events that will be received via ListenEvents(). type Event struct { @@ -466,9 +485,10 @@ type Event struct { Data []*KeyValue `protobuf:"bytes,5,rep,name=data" json:"data,omitempty"` } -func (m *Event) Reset() { *m = Event{} } -func (m *Event) String() string { return proto.CompactTextString(m) } -func (*Event) ProtoMessage() {} +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } func (m *Event) GetData() []*KeyValue { if m != nil { @@ -495,26 +515,29 @@ type EventFilter struct { UntilTime int64 `protobuf:"varint,5,opt,name=until_time" json:"until_time,omitempty"` } -func (m *EventFilter) Reset() { *m = EventFilter{} } -func (m *EventFilter) String() string { return proto.CompactTextString(m) } -func (*EventFilter) ProtoMessage() {} +func (m *EventFilter) Reset() { *m = EventFilter{} } +func (m *EventFilter) String() string { return proto.CompactTextString(m) } +func (*EventFilter) ProtoMessage() {} +func (*EventFilter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } // Request for GetInfo(). type GetInfoRequest struct { } -func (m *GetInfoRequest) Reset() { *m = GetInfoRequest{} } -func (m *GetInfoRequest) String() string { return proto.CompactTextString(m) } -func (*GetInfoRequest) ProtoMessage() {} +func (m *GetInfoRequest) Reset() { *m = GetInfoRequest{} } +func (m *GetInfoRequest) String() string { return proto.CompactTextString(m) } +func (*GetInfoRequest) ProtoMessage() {} +func (*GetInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } // Response for GetInfo(). type GetInfoResponse struct { Info *Info `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"` } -func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} } -func (m *GetInfoResponse) String() string { return proto.CompactTextString(m) } -func (*GetInfoResponse) ProtoMessage() {} +func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} } +func (m *GetInfoResponse) String() string { return proto.CompactTextString(m) } +func (*GetInfoResponse) ProtoMessage() {} +func (*GetInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } func (m *GetInfoResponse) GetInfo() *Info { if m != nil { @@ -529,9 +552,10 @@ type ListPodsRequest struct { Detail bool `protobuf:"varint,2,opt,name=detail" json:"detail,omitempty"` } -func (m *ListPodsRequest) Reset() { *m = ListPodsRequest{} } -func (m *ListPodsRequest) String() string { return proto.CompactTextString(m) } -func (*ListPodsRequest) ProtoMessage() {} +func (m *ListPodsRequest) Reset() { *m = ListPodsRequest{} } +func (m *ListPodsRequest) String() string { return proto.CompactTextString(m) } +func (*ListPodsRequest) ProtoMessage() {} +func (*ListPodsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } func (m *ListPodsRequest) GetFilters() []*PodFilter { if m != nil { @@ -545,9 +569,10 @@ type ListPodsResponse struct { Pods []*Pod `protobuf:"bytes,1,rep,name=pods" json:"pods,omitempty"` } -func (m *ListPodsResponse) Reset() { *m = ListPodsResponse{} } -func (m *ListPodsResponse) String() string { return proto.CompactTextString(m) } -func (*ListPodsResponse) ProtoMessage() {} +func (m *ListPodsResponse) Reset() { *m = ListPodsResponse{} } +func (m *ListPodsResponse) String() string { return proto.CompactTextString(m) } +func (*ListPodsResponse) ProtoMessage() {} +func (*ListPodsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } func (m *ListPodsResponse) GetPods() []*Pod { if m != nil { @@ -562,18 +587,20 @@ type InspectPodRequest struct { Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` } -func (m *InspectPodRequest) Reset() { *m = InspectPodRequest{} } -func (m *InspectPodRequest) String() string { return proto.CompactTextString(m) } -func (*InspectPodRequest) ProtoMessage() {} +func (m *InspectPodRequest) Reset() { *m = InspectPodRequest{} } +func (m *InspectPodRequest) String() string { return proto.CompactTextString(m) } +func (*InspectPodRequest) ProtoMessage() {} +func (*InspectPodRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } // Response for InspectPod(). type InspectPodResponse struct { Pod *Pod `protobuf:"bytes,1,opt,name=pod" json:"pod,omitempty"` } -func (m *InspectPodResponse) Reset() { *m = InspectPodResponse{} } -func (m *InspectPodResponse) String() string { return proto.CompactTextString(m) } -func (*InspectPodResponse) ProtoMessage() {} +func (m *InspectPodResponse) Reset() { *m = InspectPodResponse{} } +func (m *InspectPodResponse) String() string { return proto.CompactTextString(m) } +func (*InspectPodResponse) ProtoMessage() {} +func (*InspectPodResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } func (m *InspectPodResponse) GetPod() *Pod { if m != nil { @@ -588,9 +615,10 @@ type ListImagesRequest struct { Detail bool `protobuf:"varint,2,opt,name=detail" json:"detail,omitempty"` } -func (m *ListImagesRequest) Reset() { *m = ListImagesRequest{} } -func (m *ListImagesRequest) String() string { return proto.CompactTextString(m) } -func (*ListImagesRequest) ProtoMessage() {} +func (m *ListImagesRequest) Reset() { *m = ListImagesRequest{} } +func (m *ListImagesRequest) String() string { return proto.CompactTextString(m) } +func (*ListImagesRequest) ProtoMessage() {} +func (*ListImagesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } func (m *ListImagesRequest) GetFilters() []*ImageFilter { if m != nil { @@ -604,9 +632,10 @@ type ListImagesResponse struct { Images []*Image `protobuf:"bytes,1,rep,name=images" json:"images,omitempty"` } -func (m *ListImagesResponse) Reset() { *m = ListImagesResponse{} } -func (m *ListImagesResponse) String() string { return proto.CompactTextString(m) } -func (*ListImagesResponse) ProtoMessage() {} +func (m *ListImagesResponse) Reset() { *m = ListImagesResponse{} } +func (m *ListImagesResponse) String() string { return proto.CompactTextString(m) } +func (*ListImagesResponse) ProtoMessage() {} +func (*ListImagesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } func (m *ListImagesResponse) GetImages() []*Image { if m != nil { @@ -620,18 +649,20 @@ type InspectImageRequest struct { Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` } -func (m *InspectImageRequest) Reset() { *m = InspectImageRequest{} } -func (m *InspectImageRequest) String() string { return proto.CompactTextString(m) } -func (*InspectImageRequest) ProtoMessage() {} +func (m *InspectImageRequest) Reset() { *m = InspectImageRequest{} } +func (m *InspectImageRequest) String() string { return proto.CompactTextString(m) } +func (*InspectImageRequest) ProtoMessage() {} +func (*InspectImageRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } // Response for InspectImage(). type InspectImageResponse struct { Image *Image `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"` } -func (m *InspectImageResponse) Reset() { *m = InspectImageResponse{} } -func (m *InspectImageResponse) String() string { return proto.CompactTextString(m) } -func (*InspectImageResponse) ProtoMessage() {} +func (m *InspectImageResponse) Reset() { *m = InspectImageResponse{} } +func (m *InspectImageResponse) String() string { return proto.CompactTextString(m) } +func (*InspectImageResponse) ProtoMessage() {} +func (*InspectImageResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } func (m *InspectImageResponse) GetImage() *Image { if m != nil { @@ -645,9 +676,10 @@ type ListenEventsRequest struct { Filter *EventFilter `protobuf:"bytes,1,opt,name=filter" json:"filter,omitempty"` } -func (m *ListenEventsRequest) Reset() { *m = ListenEventsRequest{} } -func (m *ListenEventsRequest) String() string { return proto.CompactTextString(m) } -func (*ListenEventsRequest) ProtoMessage() {} +func (m *ListenEventsRequest) Reset() { *m = ListenEventsRequest{} } +func (m *ListenEventsRequest) String() string { return proto.CompactTextString(m) } +func (*ListenEventsRequest) ProtoMessage() {} +func (*ListenEventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } func (m *ListenEventsRequest) GetFilter() *EventFilter { if m != nil { @@ -662,9 +694,10 @@ type ListenEventsResponse struct { Events []*Event `protobuf:"bytes,1,rep,name=events" json:"events,omitempty"` } -func (m *ListenEventsResponse) Reset() { *m = ListenEventsResponse{} } -func (m *ListenEventsResponse) String() string { return proto.CompactTextString(m) } -func (*ListenEventsResponse) ProtoMessage() {} +func (m *ListenEventsResponse) Reset() { *m = ListenEventsResponse{} } +func (m *ListenEventsResponse) String() string { return proto.CompactTextString(m) } +func (*ListenEventsResponse) ProtoMessage() {} +func (*ListenEventsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } func (m *ListenEventsResponse) GetEvents() []*Event { if m != nil { @@ -694,9 +727,10 @@ type GetLogsRequest struct { UntilTime int64 `protobuf:"varint,6,opt,name=until_time" json:"until_time,omitempty"` } -func (m *GetLogsRequest) Reset() { *m = GetLogsRequest{} } -func (m *GetLogsRequest) String() string { return proto.CompactTextString(m) } -func (*GetLogsRequest) ProtoMessage() {} +func (m *GetLogsRequest) Reset() { *m = GetLogsRequest{} } +func (m *GetLogsRequest) String() string { return proto.CompactTextString(m) } +func (*GetLogsRequest) ProtoMessage() {} +func (*GetLogsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } // Response for GetLogs(). type GetLogsResponse struct { @@ -704,11 +738,37 @@ type GetLogsResponse struct { Lines []string `protobuf:"bytes,1,rep,name=lines" json:"lines,omitempty"` } -func (m *GetLogsResponse) Reset() { *m = GetLogsResponse{} } -func (m *GetLogsResponse) String() string { return proto.CompactTextString(m) } -func (*GetLogsResponse) ProtoMessage() {} +func (m *GetLogsResponse) Reset() { *m = GetLogsResponse{} } +func (m *GetLogsResponse) String() string { return proto.CompactTextString(m) } +func (*GetLogsResponse) ProtoMessage() {} +func (*GetLogsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } func init() { + proto.RegisterType((*ImageFormat)(nil), "v1alpha.ImageFormat") + proto.RegisterType((*Image)(nil), "v1alpha.Image") + proto.RegisterType((*Network)(nil), "v1alpha.Network") + proto.RegisterType((*App)(nil), "v1alpha.App") + proto.RegisterType((*Pod)(nil), "v1alpha.Pod") + proto.RegisterType((*KeyValue)(nil), "v1alpha.KeyValue") + proto.RegisterType((*PodFilter)(nil), "v1alpha.PodFilter") + proto.RegisterType((*ImageFilter)(nil), "v1alpha.ImageFilter") + proto.RegisterType((*Info)(nil), "v1alpha.Info") + proto.RegisterType((*Event)(nil), "v1alpha.Event") + proto.RegisterType((*EventFilter)(nil), "v1alpha.EventFilter") + proto.RegisterType((*GetInfoRequest)(nil), "v1alpha.GetInfoRequest") + proto.RegisterType((*GetInfoResponse)(nil), "v1alpha.GetInfoResponse") + proto.RegisterType((*ListPodsRequest)(nil), "v1alpha.ListPodsRequest") + proto.RegisterType((*ListPodsResponse)(nil), "v1alpha.ListPodsResponse") + proto.RegisterType((*InspectPodRequest)(nil), "v1alpha.InspectPodRequest") + proto.RegisterType((*InspectPodResponse)(nil), "v1alpha.InspectPodResponse") + proto.RegisterType((*ListImagesRequest)(nil), "v1alpha.ListImagesRequest") + proto.RegisterType((*ListImagesResponse)(nil), "v1alpha.ListImagesResponse") + proto.RegisterType((*InspectImageRequest)(nil), "v1alpha.InspectImageRequest") + proto.RegisterType((*InspectImageResponse)(nil), "v1alpha.InspectImageResponse") + proto.RegisterType((*ListenEventsRequest)(nil), "v1alpha.ListenEventsRequest") + proto.RegisterType((*ListenEventsResponse)(nil), "v1alpha.ListenEventsResponse") + proto.RegisterType((*GetLogsRequest)(nil), "v1alpha.GetLogsRequest") + proto.RegisterType((*GetLogsResponse)(nil), "v1alpha.GetLogsResponse") proto.RegisterEnum("v1alpha.ImageType", ImageType_name, ImageType_value) proto.RegisterEnum("v1alpha.AppState", AppState_name, AppState_value) proto.RegisterEnum("v1alpha.PodState", PodState_name, PodState_value) @@ -890,9 +950,9 @@ func RegisterPublicAPIServer(s *grpc.Server, srv PublicAPIServer) { s.RegisterService(&_PublicAPI_serviceDesc, srv) } -func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(GetInfoRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(PublicAPIServer).GetInfo(ctx, in) @@ -902,9 +962,9 @@ func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, codec grpc return out, nil } -func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(ListPodsRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(PublicAPIServer).ListPods(ctx, in) @@ -914,9 +974,9 @@ func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, codec grp return out, nil } -func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(InspectPodRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(PublicAPIServer).InspectPod(ctx, in) @@ -926,9 +986,9 @@ func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, codec g return out, nil } -func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(ListImagesRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(PublicAPIServer).ListImages(ctx, in) @@ -938,9 +998,9 @@ func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, codec g return out, nil } -func _PublicAPI_InspectImage_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _PublicAPI_InspectImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(InspectImageRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(PublicAPIServer).InspectImage(ctx, in) @@ -1030,3 +1090,90 @@ var _PublicAPI_serviceDesc = grpc.ServiceDesc{ }, }, } + +var fileDescriptor0 = []byte{ + // 1318 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x57, 0x4d, 0x72, 0xdb, 0x46, + 0x13, 0x35, 0x08, 0x82, 0x3f, 0x4d, 0x9a, 0x02, 0x47, 0xb2, 0x45, 0xd3, 0x7f, 0x32, 0xbe, 0x2f, + 0x2e, 0x47, 0x0b, 0x25, 0x91, 0x1d, 0x6f, 0x52, 0x95, 0x32, 0x25, 0x41, 0x2a, 0xc6, 0x12, 0xc9, + 0xa2, 0x69, 0x55, 0xbc, 0x42, 0x41, 0xe2, 0xd0, 0x41, 0x89, 0x04, 0x10, 0x02, 0x92, 0xad, 0x2c, + 0x73, 0x81, 0x5c, 0x21, 0xb7, 0x48, 0x55, 0x36, 0xb9, 0x41, 0x6e, 0x91, 0x7b, 0xa4, 0x67, 0x30, + 0x00, 0x06, 0x20, 0xb8, 0xc8, 0x8e, 0xe8, 0xee, 0x79, 0xfd, 0xba, 0x7b, 0xfa, 0x01, 0x84, 0xba, + 0xed, 0x3b, 0x7b, 0xfe, 0xd2, 0x0b, 0x3d, 0x52, 0xbd, 0xf9, 0xc6, 0x9e, 0xfb, 0x3f, 0xd9, 0xc6, + 0x1b, 0x68, 0xf4, 0x17, 0xf6, 0x47, 0x7a, 0xec, 0x2d, 0x17, 0x76, 0x48, 0x76, 0xa0, 0x1c, 0xde, + 0xfa, 0xb4, 0xa3, 0xec, 0x28, 0x2f, 0x5a, 0xfb, 0x64, 0x4f, 0x84, 0xed, 0xf1, 0x98, 0x09, 0x7a, + 0xc8, 0x06, 0x54, 0x6f, 0xe8, 0x32, 0x70, 0x3c, 0xb7, 0x53, 0xc2, 0xa0, 0xba, 0xf1, 0x97, 0x02, + 0x1a, 0x77, 0x93, 0x2f, 0xa1, 0x71, 0x61, 0x07, 0xd4, 0x9a, 0x71, 0x2c, 0x8e, 0xd1, 0xd8, 0xdf, + 0xca, 0x62, 0x88, 0x3c, 0x00, 0x25, 0x67, 0x1a, 0x01, 0x90, 0x26, 0x94, 0x5d, 0x7b, 0x41, 0x3b, + 0x2a, 0x7f, 0x92, 0xf0, 0xcb, 0xdc, 0xd0, 0x01, 0xdd, 0x59, 0xf8, 0xde, 0x32, 0xb4, 0x42, 0x67, + 0x41, 0x83, 0xd0, 0x5e, 0xf8, 0x1d, 0x0d, 0x3d, 0x2a, 0xd1, 0xa1, 0xb6, 0xb0, 0x5d, 0x67, 0x86, + 0xc6, 0x4e, 0x05, 0x2d, 0x4d, 0x06, 0x15, 0x38, 0xbf, 0xd0, 0x4e, 0x95, 0xfb, 0x9f, 0x43, 0xc3, + 0x76, 0x5d, 0x2f, 0xb4, 0x43, 0x44, 0x0b, 0x3a, 0xb5, 0x1d, 0x15, 0xf9, 0xb4, 0x13, 0x3e, 0x6f, + 0xe9, 0xed, 0xb9, 0x3d, 0xbf, 0xa6, 0xc6, 0x4b, 0xa8, 0x0e, 0x68, 0xf8, 0xc9, 0x5b, 0x5e, 0x25, + 0x5c, 0x94, 0x98, 0x99, 0xe3, 0xdf, 0xbc, 0x4a, 0x79, 0xe2, 0xd3, 0xeb, 0x88, 0xa7, 0xf1, 0x9b, + 0x02, 0x6a, 0xcf, 0xf7, 0x73, 0x27, 0x1e, 0x83, 0xe6, 0xb0, 0x32, 0xf9, 0x91, 0xc6, 0x7e, 0x2b, + 0x5b, 0x3c, 0xb6, 0x57, 0xc3, 0x02, 0xc2, 0xa8, 0xd6, 0x96, 0xc4, 0x05, 0x91, 0xde, 0x31, 0x07, + 0x69, 0x43, 0x9d, 0x7e, 0x76, 0x42, 0xeb, 0xd2, 0x9b, 0x52, 0xde, 0x80, 0x76, 0xbe, 0x0c, 0x6d, + 0x5d, 0x19, 0x7f, 0x22, 0xa3, 0x91, 0x37, 0x15, 0xbd, 0x8d, 0xf8, 0x34, 0x40, 0xf5, 0x45, 0xa3, + 0xdb, 0xeb, 0xb3, 0xe3, 0xa9, 0x28, 0x7b, 0x17, 0xca, 0xb6, 0xef, 0x07, 0x98, 0x98, 0xe5, 0x68, + 0xca, 0xf4, 0x88, 0x01, 0x35, 0x37, 0xea, 0x52, 0xcc, 0x41, 0x4f, 0xfc, 0x71, 0xfb, 0x56, 0x27, + 0x92, 0x23, 0x5f, 0x5d, 0x47, 0xfe, 0x39, 0xd4, 0xe2, 0xdf, 0x8c, 0x34, 0xfe, 0x16, 0x15, 0xdc, + 0x05, 0xed, 0x86, 0x59, 0xc5, 0x6d, 0xfb, 0x5d, 0x81, 0x3a, 0xd2, 0x3d, 0x76, 0xe6, 0x21, 0x5d, + 0xb2, 0x48, 0x67, 0x1a, 0x60, 0xa4, 0x8a, 0x91, 0xcf, 0xa0, 0xc2, 0xcb, 0x0b, 0x30, 0x54, 0x2d, + 0xae, 0xaf, 0xcd, 0x76, 0xc0, 0xb7, 0xd8, 0xc0, 0x02, 0xec, 0x02, 0x3b, 0x85, 0x26, 0x3e, 0x31, + 0x8b, 0x01, 0x95, 0xb9, 0xe9, 0x1e, 0xdc, 0x15, 0x95, 0x8a, 0x48, 0x8d, 0x9b, 0x73, 0xa5, 0x54, + 0xd6, 0x95, 0xf2, 0xb7, 0x12, 0xef, 0x54, 0x01, 0x49, 0xec, 0x90, 0xbf, 0xa4, 0x33, 0xe7, 0xb3, + 0xa0, 0x59, 0x27, 0x38, 0x2f, 0xbe, 0x35, 0x32, 0x29, 0x8c, 0xba, 0xa2, 0xb7, 0xc8, 0x20, 0xe1, + 0x84, 0xc5, 0xcd, 0xed, 0x0b, 0x3a, 0x5f, 0x3f, 0x7f, 0x72, 0x1f, 0x5a, 0xd1, 0xa2, 0xd0, 0xa9, + 0x65, 0xcf, 0x30, 0x33, 0x1f, 0x81, 0x4a, 0xb6, 0x61, 0x23, 0xb1, 0x5f, 0x50, 0x5c, 0xce, 0xff, + 0xba, 0x1f, 0xc7, 0x50, 0xee, 0xbb, 0x33, 0x8f, 0x6c, 0x42, 0x63, 0x79, 0x15, 0x5a, 0xf1, 0x7a, + 0x46, 0xf3, 0xd9, 0x82, 0x26, 0xb6, 0xf4, 0xd2, 0xca, 0x88, 0x02, 0x0b, 0x45, 0xb1, 0x49, 0x8c, + 0xd1, 0xca, 0x2c, 0x41, 0x33, 0x6f, 0xa8, 0xbb, 0x5e, 0x65, 0xb8, 0x97, 0xab, 0x4c, 0x4e, 0x1f, + 0x66, 0x4b, 0x6f, 0x21, 0xf4, 0x01, 0x9f, 0x98, 0x0e, 0xf0, 0xdd, 0x50, 0xc9, 0x53, 0x28, 0x4f, + 0xed, 0xd0, 0x5e, 0xbf, 0x14, 0x21, 0x34, 0x38, 0xaa, 0x98, 0xc5, 0x33, 0xd0, 0x58, 0xe6, 0x68, + 0x1a, 0xc5, 0xa9, 0xc5, 0xb8, 0xa2, 0xe1, 0xe0, 0xed, 0x93, 0xe7, 0x82, 0xbc, 0x02, 0xc7, 0xbd, + 0xa4, 0x96, 0x44, 0x01, 0x6d, 0xd7, 0x6e, 0xe8, 0xcc, 0x23, 0x1b, 0x57, 0x26, 0x43, 0x87, 0xd6, + 0x09, 0x0d, 0x59, 0xd3, 0xc6, 0xf4, 0xe7, 0x6b, 0xdc, 0x06, 0x63, 0x0f, 0x36, 0x12, 0x4b, 0xe0, + 0x63, 0xbb, 0x29, 0x79, 0x88, 0x7a, 0x82, 0xcf, 0x42, 0x27, 0xef, 0xa6, 0x52, 0x81, 0x46, 0xec, + 0xf9, 0xc6, 0xa9, 0x13, 0x84, 0x78, 0x73, 0x03, 0x01, 0x41, 0xfe, 0x07, 0xd5, 0x19, 0xaf, 0x22, + 0x62, 0xdf, 0x90, 0xd8, 0xa7, 0x1b, 0xd1, 0x82, 0xca, 0x94, 0x86, 0xb6, 0x33, 0xe7, 0xcd, 0xab, + 0x61, 0x5e, 0x3d, 0xc5, 0x11, 0x89, 0x71, 0xcb, 0x7d, 0x6f, 0x1a, 0xa3, 0x34, 0x65, 0x14, 0xe3, + 0x29, 0xb4, 0xfb, 0x6e, 0xe0, 0xd3, 0x4b, 0x76, 0x24, 0xce, 0x2c, 0x29, 0x8a, 0xf1, 0x15, 0x10, + 0x39, 0x40, 0x40, 0x3e, 0x40, 0x9d, 0xf1, 0xa6, 0xa2, 0x94, 0x2c, 0xe2, 0x0f, 0xd0, 0x66, 0x0c, + 0xf8, 0x46, 0x24, 0xb5, 0x7c, 0x91, 0xaf, 0x25, 0xff, 0x9a, 0x28, 0xae, 0xe6, 0x15, 0x10, 0x19, + 0x4b, 0x24, 0x7f, 0x02, 0x15, 0xbe, 0xc2, 0x31, 0x56, 0x4e, 0x75, 0x8d, 0x67, 0xb0, 0x29, 0x28, + 0xf3, 0xe7, 0xa2, 0xaa, 0xbe, 0x85, 0xad, 0x6c, 0x88, 0x80, 0x4e, 0xf4, 0x5c, 0x29, 0xd2, 0x73, + 0xe3, 0x3b, 0xd8, 0x64, 0x7c, 0xa8, 0xcb, 0xaf, 0x4f, 0x52, 0xdd, 0xff, 0xa1, 0x12, 0x55, 0xb7, + 0xf2, 0x0e, 0x94, 0xee, 0xa2, 0xf1, 0x1a, 0xb6, 0xb2, 0x87, 0xd3, 0x72, 0x28, 0xb7, 0xac, 0x94, + 0xc3, 0x03, 0x8d, 0x5b, 0x7e, 0xb9, 0x4e, 0xbd, 0x8f, 0x49, 0x3e, 0x6c, 0x13, 0x76, 0xdf, 0x4a, + 0x54, 0x1f, 0xe5, 0x23, 0x96, 0x39, 0xb1, 0x43, 0x78, 0x8f, 0xe7, 0x8e, 0xcb, 0xef, 0xb1, 0xf2, + 0x42, 0x63, 0x07, 0x66, 0xde, 0x7c, 0xee, 0x7d, 0xe2, 0x77, 0xb8, 0x96, 0xbb, 0xd7, 0x5a, 0xc1, + 0xbd, 0xe6, 0x52, 0x62, 0xec, 0xf0, 0x5b, 0x1c, 0xa5, 0x16, 0x6c, 0x13, 0x64, 0xae, 0x6f, 0xbb, + 0x14, 0xea, 0xe9, 0xb7, 0x42, 0x07, 0xbb, 0x7a, 0xd6, 0x3b, 0x31, 0xad, 0xc9, 0x87, 0x91, 0x69, + 0xbd, 0x1f, 0x1c, 0x99, 0xc7, 0xfd, 0x81, 0x79, 0xa4, 0xdf, 0x41, 0x7d, 0xd8, 0x90, 0x3c, 0xbd, + 0xd1, 0xe8, 0x50, 0x57, 0x50, 0x77, 0xdb, 0x92, 0xf1, 0x68, 0x78, 0xf8, 0xd6, 0x1c, 0xeb, 0x25, + 0x24, 0xd2, 0x92, 0xcc, 0xc3, 0xc3, 0xbe, 0xae, 0xee, 0x8e, 0xa0, 0x96, 0xbc, 0x32, 0xb7, 0x61, + 0x13, 0x01, 0xac, 0x77, 0x93, 0xde, 0x24, 0x9b, 0x04, 0xf1, 0x52, 0xc7, 0xf8, 0xfd, 0x60, 0xd0, + 0x1f, 0x9c, 0x60, 0x9a, 0x2d, 0xd0, 0x53, 0xb3, 0xf9, 0x63, 0x7f, 0x82, 0xc1, 0xa5, 0xdd, 0x7f, + 0x14, 0xa8, 0x25, 0xef, 0x09, 0x84, 0x1c, 0x0d, 0x8f, 0x0a, 0x20, 0xf1, 0x6c, 0xea, 0x30, 0xcf, + 0x0e, 0xc6, 0x1f, 0x86, 0x88, 0x98, 0x09, 0x1f, 0x8d, 0xcd, 0x51, 0x6f, 0xcc, 0x52, 0x95, 0x50, + 0x92, 0x49, 0xde, 0x81, 0x30, 0x2a, 0x63, 0x96, 0xda, 0x63, 0x66, 0x65, 0xbc, 0x6d, 0x0f, 0x52, + 0x73, 0xef, 0x60, 0x38, 0x46, 0x6a, 0xf1, 0x31, 0x5d, 0xcb, 0x25, 0x8f, 0x88, 0x57, 0xb2, 0x39, + 0x8e, 0xcc, 0x53, 0x73, 0xc2, 0xc0, 0xaa, 0xd9, 0x1c, 0x27, 0xbd, 0xf1, 0x01, 0xb6, 0x50, 0xaf, + 0xed, 0xfe, 0x51, 0x82, 0x7a, 0x2a, 0x76, 0x38, 0x21, 0xf3, 0xdc, 0x1c, 0x4c, 0x56, 0x27, 0xf4, + 0x10, 0xb6, 0x25, 0x0f, 0x43, 0x4a, 0xf8, 0x2b, 0xf8, 0x2d, 0xf0, 0xa4, 0xd8, 0x19, 0xb3, 0xc6, + 0xda, 0xbb, 0x70, 0x3f, 0x17, 0x83, 0x54, 0xb8, 0x4f, 0x45, 0xb9, 0xb8, 0x97, 0xf3, 0x89, 0x72, + 0xca, 0xb8, 0x3b, 0x3b, 0x39, 0x97, 0xe0, 0x6e, 0x1d, 0x0e, 0x4f, 0x4f, 0xcd, 0x43, 0x16, 0xa5, + 0xe5, 0xc0, 0xc5, 0x38, 0xc7, 0x51, 0x43, 0xb2, 0xe0, 0xcc, 0x27, 0xc0, 0xab, 0xac, 0xc1, 0x92, + 0x2b, 0xba, 0x55, 0xfd, 0xb3, 0x51, 0x44, 0xb9, 0x46, 0x1e, 0x41, 0x67, 0xc5, 0x3d, 0x36, 0xcf, + 0x86, 0xe7, 0xe8, 0xad, 0xef, 0xff, 0x5a, 0xc6, 0x4f, 0x8f, 0xeb, 0x8b, 0xb9, 0x73, 0xd9, 0x1b, + 0xf5, 0xc9, 0xf7, 0x50, 0x15, 0x82, 0x4e, 0xb6, 0x93, 0x05, 0xcd, 0x8a, 0x7e, 0xb7, 0xb3, 0xea, + 0x88, 0xb6, 0xc6, 0xb8, 0x43, 0x7a, 0x50, 0x8b, 0x85, 0x99, 0xa4, 0x71, 0x39, 0xcd, 0xef, 0x3e, + 0x28, 0xf0, 0x24, 0x10, 0x27, 0x00, 0xa9, 0x14, 0x93, 0xae, 0xf4, 0x02, 0xc9, 0x09, 0x78, 0xf7, + 0x61, 0xa1, 0x4f, 0x06, 0x4a, 0x65, 0x55, 0x02, 0x5a, 0xd1, 0x6d, 0x09, 0x68, 0x55, 0x87, 0x11, + 0xe8, 0x0c, 0x9a, 0xb2, 0x8c, 0x92, 0x47, 0xf9, 0xbc, 0xb2, 0x00, 0x77, 0x1f, 0xaf, 0xf1, 0x26, + 0x70, 0x43, 0x68, 0xca, 0x0a, 0x29, 0xc1, 0x15, 0xa8, 0xae, 0x04, 0x57, 0x24, 0xab, 0xc6, 0x9d, + 0xaf, 0x15, 0xf2, 0x86, 0x0f, 0x8d, 0xe9, 0x57, 0x76, 0x68, 0x92, 0x98, 0x66, 0x87, 0x26, 0x4b, + 0x1d, 0x43, 0xb8, 0xa8, 0xf0, 0xff, 0x4f, 0x2f, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x84, 0xa0, + 0x2b, 0xe3, 0x4c, 0x0d, 0x00, 0x00, +} diff --git a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.proto b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.proto index 8112c42f5f..73b453d47a 100644 --- a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.proto +++ b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.proto @@ -21,8 +21,6 @@ // The API defined here is proposed, experimental, // // and (for now) subject to change at any time. // // // -// Do not use it. // -// // // If you think you want to use it, or for any other // // queries, contact // // or file an issue on github.com/coreos/rkt // @@ -234,6 +232,9 @@ message ImageFilter { // If not empty, the images that have all of the annotations will be returned. repeated KeyValue annotations = 8; + + // If not empty, the images that have any of the exact full names will be returned. + repeated string full_names = 9; } // Info describes the information of rkt on the machine. diff --git a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/client_example.go b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/client_example.go index 7c71540896..ec807d9ee3 100644 --- a/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/client_example.go +++ b/Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/client_example.go @@ -20,8 +20,6 @@ import ( "fmt" "os" - // Note that if your project uses Godep to manage dependencies, then - // you need to change following the import paths. "github.com/coreos/rkt/api/v1alpha" "golang.org/x/net/context" "google.golang.org/grpc" diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.pb.go b/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.pb.go index 9f1f5312cc..760e4e61d8 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.pb.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.pb.go @@ -230,6 +230,14 @@ var E_GogoprotoImport = &proto.ExtensionDesc{ Tag: "varint,63027,opt,name=gogoproto_import", } +var E_ProtosizerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63028, + Name: "gogoproto.protosizer_all", + Tag: "varint,63028,opt,name=protosizer_all", +} + var E_GoprotoGetters = &proto.ExtensionDesc{ ExtendedType: (*google_protobuf.MessageOptions)(nil), ExtensionType: (*bool)(nil), @@ -382,6 +390,14 @@ var E_GoprotoUnrecognized = &proto.ExtensionDesc{ Tag: "varint,64026,opt,name=goproto_unrecognized", } +var E_Protosizer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64028, + Name: "gogoproto.protosizer", + Tag: "varint,64028,opt,name=protosizer", +} + var E_Nullable = &proto.ExtensionDesc{ ExtendedType: (*google_protobuf.FieldOptions)(nil), ExtensionType: (*bool)(nil), @@ -481,6 +497,7 @@ func init() { proto.RegisterExtension(E_GoprotoExtensionsMapAll) proto.RegisterExtension(E_GoprotoUnrecognizedAll) proto.RegisterExtension(E_GogoprotoImport) + proto.RegisterExtension(E_ProtosizerAll) proto.RegisterExtension(E_GoprotoGetters) proto.RegisterExtension(E_GoprotoStringer) proto.RegisterExtension(E_VerboseEqual) @@ -500,6 +517,7 @@ func init() { proto.RegisterExtension(E_UnsafeUnmarshaler) proto.RegisterExtension(E_GoprotoExtensionsMap) proto.RegisterExtension(E_GoprotoUnrecognized) + proto.RegisterExtension(E_Protosizer) proto.RegisterExtension(E_Nullable) proto.RegisterExtension(E_Embed) proto.RegisterExtension(E_Customtype) diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.proto b/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.proto index 84310e8fdb..3373faf319 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.proto +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/gogo.proto @@ -67,6 +67,8 @@ extend google.protobuf.FileOptions { optional bool goproto_extensions_map_all = 63025; optional bool goproto_unrecognized_all = 63026; optional bool gogoproto_import = 63027; + + optional bool protosizer_all = 63028; } extend google.protobuf.MessageOptions { @@ -93,6 +95,8 @@ extend google.protobuf.MessageOptions { optional bool goproto_extensions_map = 64025; optional bool goproto_unrecognized = 64026; + + optional bool protosizer = 64028; } extend google.protobuf.FieldOptions { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/helper.go b/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/helper.go index b1889f258c..b5a1853844 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/helper.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/gogoproto/helper.go @@ -213,6 +213,10 @@ func IsSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf return proto.GetBoolExtension(message.Options, E_Sizer, proto.GetBoolExtension(file.Options, E_SizerAll, false)) } +func IsProtoSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Protosizer, proto.GetBoolExtension(file.Options, E_ProtosizerAll, false)) +} + func IsGoEnumStringer(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { return proto.GetBoolExtension(enum.Options, E_GoprotoEnumStringer, proto.GetBoolExtension(file.Options, E_GoprotoEnumStringerAll, true)) } diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go index 460dc77523..af8fd96811 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go @@ -80,7 +80,8 @@ var overwriters []map[string]gogoproto.EnableFunc = []map[string]gogoproto.Enabl "verboseequal": gogoproto.HasVerboseEqual, }, { - "size": gogoproto.IsSizer, + "size": gogoproto.IsSizer, + "protosizer": gogoproto.IsProtoSizer, }, { "unmarshaler": gogoproto.IsUnmarshaler, diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/marshalto/marshalto.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/marshalto/marshalto.go index 60362c5eeb..52d36098fe 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/marshalto/marshalto.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/marshalto/marshalto.go @@ -303,12 +303,12 @@ func wireToType(wire string) int { panic("unreachable") } -func (p *marshalto) mapField(numGen NumGen, fieldTyp descriptor.FieldDescriptorProto_Type, varName string) { +func (p *marshalto) mapField(numGen NumGen, fieldTyp descriptor.FieldDescriptorProto_Type, varName string, protoSizer bool) { switch fieldTyp { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: - p.callFixed64(p.mathPkg.Use(), `.Float64bits(`, varName, `)`) + p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(`, varName, `))`) case descriptor.FieldDescriptorProto_TYPE_FLOAT: - p.callFixed32(p.mathPkg.Use(), `.Float32bits(`, varName, `)`) + p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(`, varName, `))`) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, @@ -341,7 +341,11 @@ func (p *marshalto) mapField(numGen NumGen, fieldTyp descriptor.FieldDescriptorP case descriptor.FieldDescriptorProto_TYPE_SINT64: p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: - p.callVarint(varName, `.Size()`) + if protoSizer { + p.callVarint(varName, `.ProtoSize()`) + } else { + p.callVarint(varName, `.Size()`) + } p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() @@ -371,6 +375,8 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() required := field.IsRequired() + + protoSizer := gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) if required && nullable { p.P(`if m.`, fieldname, `== nil {`) p.In() @@ -397,13 +403,13 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi } switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: - if !p.unsafe { + if !p.unsafe || gogoproto.IsCastType(field) { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() - p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(num)`) + p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`) p.encodeFixed64("f" + numGen.Current()) p.Out() p.P(`}`) @@ -411,7 +417,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) - p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(num)`) + p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`) p.encodeFixed64("f" + numGen.Current()) p.Out() p.P(`}`) @@ -419,15 +425,15 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) - p.callFixed64(p.mathPkg.Use(), `.Float64bits(m.`+fieldname, `)`) + p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) - p.callFixed64(p.mathPkg.Use(), `.Float64bits(m.`+fieldname, `)`) + p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`) } else { p.encodeKey(fieldNumber, wireType) - p.callFixed64(p.mathPkg.Use(), `.Float64bits(*m.`+fieldname, `)`) + p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(*m.`+fieldname, `))`) } } else { if packed { @@ -461,13 +467,13 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi } } case descriptor.FieldDescriptorProto_TYPE_FLOAT: - if !p.unsafe { + if !p.unsafe || gogoproto.IsCastType(field) { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() - p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(num)`) + p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`) p.encodeFixed32("f" + numGen.Current()) p.Out() p.P(`}`) @@ -475,7 +481,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) - p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(num)`) + p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`) p.encodeFixed32("f" + numGen.Current()) p.Out() p.P(`}`) @@ -483,15 +489,15 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) - p.callFixed32(p.mathPkg.Use(), `.Float32bits(m.`+fieldname, `)`) + p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) - p.callFixed32(p.mathPkg.Use(), `.Float32bits(m.`+fieldname, `)`) + p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`) } else { p.encodeKey(fieldNumber, wireType) - p.callFixed32(p.mathPkg.Use(), `.Float32bits(*m.`+fieldname, `)`) + p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(*m.`+fieldname, `))`) } } else { if packed { @@ -896,22 +902,30 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi } else if !nullable { accessor = `(&v)` } - p.P(`msgSize := `, accessor, `.Size()`) + if protoSizer { + p.P(`msgSize := `, accessor, `.ProtoSize()`) + } else { + p.P(`msgSize := `, accessor, `.Size()`) + } sum = append(sum, `msgSize + sov`+p.localName+`(uint64(msgSize))`) } p.P(`mapSize := `, strings.Join(sum, " + ")) p.callVarint("mapSize") p.encodeKey(1, wireToType(keywire)) - p.mapField(numGen, m.KeyField.GetType(), "k") + p.mapField(numGen, m.KeyField.GetType(), "k", protoSizer) p.encodeKey(2, wireToType(valuewire)) - p.mapField(numGen, m.ValueField.GetType(), accessor) + p.mapField(numGen, m.ValueField.GetType(), accessor, protoSizer) p.Out() p.P(`}`) } else if repeated { p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) - p.callVarint("msg.Size()") + if protoSizer { + p.callVarint("msg.ProtoSize()") + } else { + p.callVarint("msg.Size()") + } p.P(`n, err := msg.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() @@ -923,7 +937,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) - p.callVarint(`m.`, fieldname, `.Size()`) + if protoSizer { + p.callVarint(`m.`, fieldname, `.ProtoSize()`) + } else { + p.callVarint(`m.`, fieldname, `.Size()`) + } p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() @@ -960,7 +978,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) - p.callVarint(`msg.Size()`) + if protoSizer { + p.callVarint(`msg.ProtoSize()`) + } else { + p.callVarint(`msg.Size()`) + } p.P(`n, err := msg.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() @@ -972,7 +994,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) - p.callVarint(`m.`, fieldname, `.Size()`) + if protoSizer { + p.callVarint(`m.`, fieldname, `.ProtoSize()`) + } else { + p.callVarint(`m.`, fieldname, `.Size()`) + } p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() @@ -1126,7 +1152,11 @@ func (p *marshalto) Generate(file *generator.FileDescriptor) { p.P(`func (m *`, ccTypeName, `) Marshal() (data []byte, err error) {`) p.In() - p.P(`size := m.Size()`) + if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) { + p.P(`size := m.ProtoSize()`) + } else { + p.P(`size := m.Size()`) + } p.P(`data = make([]byte, size)`) p.P(`n, err := m.MarshalTo(data)`) p.P(`if err != nil {`) diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/populate/populate.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/populate/populate.go index 70597db3aa..6594096f7f 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/populate/populate.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/populate/populate.go @@ -290,7 +290,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato } else if field.IsMessage() || p.IsGroup(field) { funcCall := getFuncCall(goTypName) if field.IsRepeated() { - p.P(p.varGen.Next(), ` := r.Intn(10)`) + p.P(p.varGen.Next(), ` := r.Intn(5)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() @@ -346,7 +346,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato } } else if field.IsBytes() { if field.IsRepeated() { - p.P(p.varGen.Next(), ` := r.Intn(100)`) + p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() @@ -387,7 +387,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato } else { typName := generator.GoTypeToName(goTyp) if field.IsRepeated() { - p.P(p.varGen.Next(), ` := r.Intn(100)`) + p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/size.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/size.go index b657611b3d..49b1f962cd 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/size.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/size.go @@ -25,7 +25,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* -The size plugin generates a Size method for each message. +The size plugin generates a Size or ProtoSize method for each message. This is useful with the MarshalTo method generated by the marshalto plugin and the gogoproto.marshaler and gogoproto.marshaler_all extensions. @@ -33,6 +33,8 @@ It is enabled by the following extensions: - sizer - sizer_all + - protosizer + - protosizer_all The size plugin also generates a test given it is enabled using one of the following extensions: @@ -195,7 +197,7 @@ func (p *size) sizeZigZag() { }`) } -func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { +func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, sizeName string) { fieldname := p.GetOneOfFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() @@ -393,17 +395,17 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag p.P(`if v != nil {`) p.In() if valuegoTyp != valuegoAliasTyp { - p.P(`l = ((`, valuegoTyp, `)(v)).Size()`) + p.P(`l = ((`, valuegoTyp, `)(v)).`, sizeName, `()`) } else { - p.P(`l = v.Size()`) + p.P(`l = v.`, sizeName, `()`) } p.Out() p.P(`}`) } else { if valuegoTyp != valuegoAliasTyp { - p.P(`l = ((*`, valuegoTyp, `)(&v)).Size()`) + p.P(`l = ((*`, valuegoTyp, `)(&v)).`, sizeName, `()`) } else { - p.P(`l = v.Size()`) + p.P(`l = v.`, sizeName, `()`) } } sum = append(sum, `l+sov`+p.localName+`(uint64(l))`) @@ -415,12 +417,12 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag } else if repeated { p.P(`for _, e := range m.`, fieldname, ` { `) p.In() - p.P(`l=e.Size()`) + p.P(`l=e.`, sizeName, `()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { - p.P(`l=m.`, fieldname, `.Size()`) + p.P(`l=m.`, fieldname, `.`, sizeName, `()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } case descriptor.FieldDescriptorProto_TYPE_BYTES: @@ -447,12 +449,12 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag if repeated { p.P(`for _, e := range m.`, fieldname, ` { `) p.In() - p.P(`l=e.Size()`) + p.P(`l=e.`, sizeName, `()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { - p.P(`l=m.`, fieldname, `.Size()`) + p.P(`l=m.`, fieldname, `.`, sizeName, `()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } } @@ -501,7 +503,12 @@ func (p *size) Generate(file *generator.FileDescriptor) { protoPkg = p.NewImport("github.com/golang/protobuf/proto") } for _, message := range file.Messages() { - if !gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { + sizeName := "" + if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { + sizeName = "Size" + } else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) { + sizeName = "ProtoSize" + } else { continue } if message.DescriptorProto.GetOptions().GetMapEntry() { @@ -509,7 +516,7 @@ func (p *size) Generate(file *generator.FileDescriptor) { } p.atleastOne = true ccTypeName := generator.CamelCaseSlice(message.TypeName()) - p.P(`func (m *`, ccTypeName, `) Size() (n int) {`) + p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`) p.In() p.P(`var l int`) p.P(`_ = l`) @@ -518,7 +525,7 @@ func (p *size) Generate(file *generator.FileDescriptor) { oneof := field.OneofIndex != nil if !oneof { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) - p.generateField(proto3, file, message, field) + p.generateField(proto3, file, message, field, sizeName) } else { fieldname := p.GetFieldName(message, field) if _, ok := oneofs[fieldname]; ok { @@ -528,7 +535,7 @@ func (p *size) Generate(file *generator.FileDescriptor) { } p.P(`if m.`, fieldname, ` != nil {`) p.In() - p.P(`n+=m.`, fieldname, `.Size()`) + p.P(`n+=m.`, fieldname, `.`, sizeName, `()`) p.Out() p.P(`}`) } @@ -564,12 +571,12 @@ func (p *size) Generate(file *generator.FileDescriptor) { continue } ccTypeName := p.OneOfTypeName(message, f) - p.P(`func (m *`, ccTypeName, `) Size() (n int) {`) + p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`) p.In() p.P(`var l int`) p.P(`_ = l`) vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly(f) - p.generateField(false, file, message, f) + p.generateField(false, file, message, f, sizeName) p.P(`return n`) p.Out() p.P(`}`) diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/sizetest.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/sizetest.go index 0851a29a47..4fa946e57e 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/sizetest.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/size/sizetest.go @@ -51,7 +51,12 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes } for _, message := range file.Messages() { ccTypeName := generator.CamelCaseSlice(message.TypeName()) - if !gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { + sizeName := "" + if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { + sizeName = "Size" + } else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) { + sizeName = "ProtoSize" + } else { continue } if message.DescriptorProto.GetOptions().GetMapEntry() { @@ -60,7 +65,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) { used = true - p.P(`func Test`, ccTypeName, `Size(t *`, testingPkg.Use(), `.T) {`) + p.P(`func Test`, ccTypeName, sizeName, `(t *`, testingPkg.Use(), `.T) {`) p.In() p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`) p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`) @@ -72,7 +77,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`) p.Out() p.P(`}`) - p.P(`size := p.Size()`) + p.P(`size := p.`, sizeName, `()`) p.P(`if len(data) != size {`) p.In() p.P(`t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data))`) @@ -96,7 +101,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) { used = true - p.P(`func Benchmark`, ccTypeName, `Size(b *`, testingPkg.Use(), `.B) {`) + p.P(`func Benchmark`, ccTypeName, sizeName, `(b *`, testingPkg.Use(), `.B) {`) p.In() p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`) p.P(`total := 0`) @@ -109,7 +114,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes p.P(`b.ResetTimer()`) p.P(`for i := 0; i < b.N; i++ {`) p.In() - p.P(`total += pops[i%1000].Size()`) + p.P(`total += pops[i%1000].`, sizeName, `()`) p.Out() p.P(`}`) p.P(`b.SetBytes(int64(total / b.N))`) diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/testgen/testgen.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/testgen/testgen.go index de6c7217db..a48a1c2ccb 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/testgen/testgen.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/testgen/testgen.go @@ -341,7 +341,11 @@ func (p *testProto) Generate(imports generator.PluginImports, file *generator.Fi p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`) p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`) p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`) - p.P(`size := p.Size()`) + if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) { + p.P(`size := p.ProtoSize()`) + } else { + p.P(`size := p.Size()`) + } p.P(`data := make([]byte, size)`) p.P(`for i := range data {`) p.In() diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go index acb32d9db0..1328596098 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go @@ -419,7 +419,7 @@ func (p *unmarshal) noStarOrSliceType(msg *generator.Descriptor, field *descript return typ } -func (p *unmarshal) field(file *descriptor.FileDescriptorProto, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) { +func (p *unmarshal) field(file *generator.FileDescriptor, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) { repeated := field.IsRepeated() nullable := gogoproto.IsNullable(field) typ := p.noStarOrSliceType(msg, field) @@ -676,7 +676,7 @@ func (p *unmarshal) field(file *descriptor.FileDescriptorProto, msg *generator.D p.Out() p.P(`}`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) - } else if generator.IsMap(file, field) { + } else if generator.IsMap(file.FileDescriptorProto, field) { m := p.GoMapType(nil, field) keygoTyp, _ := p.GoType(nil, m.KeyField) @@ -773,7 +773,12 @@ func (p *unmarshal) field(file *descriptor.FileDescriptorProto, msg *generator.D p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`) p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], data[iNdEx:postIndex])`) } else { - p.P(`m.`, fieldname, ` = append([]byte{}`, `, data[iNdEx:postIndex]...)`) + p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , data[iNdEx:postIndex]...)`) + p.P(`if m.`, fieldname, ` == nil {`) + p.In() + p.P(`m.`, fieldname, ` = []byte{}`) + p.Out() + p.P(`}`) } } else { _, ctyp, err := generator.GetCustomType(field) @@ -1061,13 +1066,13 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) { p.P(`}`) p.P(`for iNdEx < postIndex {`) p.In() - p.field(file.FileDescriptorProto, message, field, fieldname, false) + p.field(file, message, field, fieldname, false) p.Out() p.P(`}`) p.Out() p.P(`} else if wireType == `, strconv.Itoa(wireType), `{`) p.In() - p.field(file.FileDescriptorProto, message, field, fieldname, false) + p.field(file, message, field, fieldname, false) p.Out() p.P(`} else {`) p.In() @@ -1080,7 +1085,7 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) { p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`) p.Out() p.P(`}`) - p.field(file.FileDescriptorProto, message, field, fieldname, proto3) + p.field(file, message, field, fieldname, proto3) } if field.IsRequired() { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go b/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go index f3a690a6b6..33c501b3e4 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go @@ -601,7 +601,7 @@ func (g *Generator) CommandLineParameters(parameter string) { if pluginList == "none" { pluginList = "" } - gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck"} + gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "protosizer", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck"} pluginList = strings.Join(append(gogoPluginNames, pluginList), "+") if pluginList != "" { // Amend the set of plugins. @@ -1857,11 +1857,11 @@ var methodNames = [...]string{ "ExtensionRangeArray", "ExtensionMap", "Descriptor", - "Size", "MarshalTo", "Equal", "VerboseEqual", "GoString", + "ProtoSize", } // Generate the type and default constant definitions for this Descriptor. @@ -1875,6 +1875,9 @@ func (g *Generator) generateMessage(message *Descriptor) { for _, n := range methodNames { usedNames[n] = true } + if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) { + usedNames["Size"] = true + } fieldNames := make(map[*descriptor.FieldDescriptorProto]string) fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string) fieldTypes := make(map[*descriptor.FieldDescriptorProto]string) @@ -2210,6 +2213,9 @@ func (g *Generator) generateMessage(message *Descriptor) { if gogoproto.IsSizer(g.file.FileDescriptorProto, message.DescriptorProto) { g.P(`Size() int`) } + if gogoproto.IsProtoSizer(g.file.FileDescriptorProto, message.DescriptorProto) { + g.P(`ProtoSize() int`) + } g.Out() g.P("}") } diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go b/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go index 048cd9b369..258d6a9b6a 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go @@ -181,6 +181,11 @@ func (g *Generator) GetFieldName(message *Descriptor, field *descriptor.FieldDes return fieldname + "_" } } + if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) { + if fieldname == "Size" { + return fieldname + "_" + } + } return fieldname } @@ -198,6 +203,11 @@ func (g *Generator) GetOneOfFieldName(message *Descriptor, field *descriptor.Fie return fieldname + "_" } } + if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) { + if fieldname == "Size" { + return fieldname + "_" + } + } return fieldname } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile b/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile index fb838ed2d7..f1f06564a1 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile @@ -39,5 +39,5 @@ test: install generate-test-pbs generate-test-pbs: make install make -C testdata - make -C proto3_proto + protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto make diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go index ae276fd77c..e98ddec981 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go @@ -29,8 +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. -// Protocol buffer deep copy. -// TODO: MessageSet and RawMessage. +// Protocol buffer deep copy and merge. +// TODO: RawMessage. package proto @@ -75,12 +75,13 @@ func Merge(dst, src Message) { } func mergeStruct(out, in reflect.Value) { + sprop := GetProperties(in.Type()) for i := 0; i < in.NumField(); i++ { f := in.Type().Field(i) if strings.HasPrefix(f.Name, "XXX_") { continue } - mergeAny(out.Field(i), in.Field(i)) + mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) } if emIn, ok := in.Addr().Interface().(extendableProto); ok { @@ -98,7 +99,10 @@ func mergeStruct(out, in reflect.Value) { } } -func mergeAny(out, in reflect.Value) { +// mergeAny performs a merge between two values of the same type. +// viaPtr indicates whether the values were indirected through a pointer (implying proto2). +// prop is set if this is a struct field (it may be nil). +func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { if in.Type() == protoMessageType { if !in.IsNil() { if out.IsNil() { @@ -112,7 +116,21 @@ func mergeAny(out, in reflect.Value) { switch in.Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: + if !viaPtr && isProto3Zero(in) { + return + } out.Set(in) + case reflect.Interface: + // Probably a oneof field; copy non-nil values. + if in.IsNil() { + return + } + // Allocate destination if it is not set, or set to a different type. + // Otherwise we will merge as normal. + if out.IsNil() || out.Elem().Type() != in.Elem().Type() { + out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) + } + mergeAny(out.Elem(), in.Elem(), false, nil) case reflect.Map: if in.Len() == 0 { return @@ -127,7 +145,7 @@ func mergeAny(out, in reflect.Value) { switch elemKind { case reflect.Ptr: val = reflect.New(in.Type().Elem().Elem()) - mergeAny(val, in.MapIndex(key)) + mergeAny(val, in.MapIndex(key), false, nil) case reflect.Slice: val = in.MapIndex(key) val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) @@ -143,13 +161,21 @@ func mergeAny(out, in reflect.Value) { if out.IsNil() { out.Set(reflect.New(in.Elem().Type())) } - mergeAny(out.Elem(), in.Elem()) + mergeAny(out.Elem(), in.Elem(), true, nil) case reflect.Slice: if in.IsNil() { return } if in.Type().Elem().Kind() == reflect.Uint8 { // []byte is a scalar bytes field, not a repeated field. + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value, and should not + // be merged. + if prop != nil && prop.proto3 && in.Len() == 0 { + return + } + // Make a deep copy. // Append to []byte{} instead of []byte(nil) so that we never end up // with a nil result. @@ -167,7 +193,7 @@ func mergeAny(out, in reflect.Value) { default: for i := 0; i < n; i++ { x := reflect.Indirect(reflect.New(in.Type().Elem())) - mergeAny(x, in.Index(i)) + mergeAny(x, in.Index(i), false, nil) out.Set(reflect.Append(out, x)) } } @@ -184,7 +210,7 @@ func mergeExtension(out, in map[int32]Extension) { eOut := Extension{desc: eIn.desc} if eIn.value != nil { v := reflect.New(reflect.TypeOf(eIn.value)).Elem() - mergeAny(v, reflect.ValueOf(eIn.value)) + mergeAny(v, reflect.ValueOf(eIn.value), false, nil) eOut.value = v.Interface() } if eIn.enc != nil { diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go index 88622c305a..5810782fd8 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go @@ -46,6 +46,10 @@ import ( // errOverflow is returned when an integer is too large to be represented. var errOverflow = errors.New("proto: integer overflow") +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + // The fundamental decoders that interpret bytes on the wire. // Those that take integer types all return uint64 and are // therefore of type valueDecoder. @@ -314,6 +318,24 @@ func UnmarshalMerge(buf []byte, pb Message) error { return NewBuffer(buf).Unmarshal(pb) } +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +func (p *Buffer) DecodeGroup(pb Message) error { + typ, base, err := getbase(pb) + if err != nil { + return err + } + return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base) +} + // Unmarshal parses the protocol buffer representation in the // Buffer and places the decoded result in pb. If the struct // underlying pb does not match the data in the buffer, the results can be @@ -377,6 +399,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group continue } } + // Maybe it's a oneof? + if prop.oneofUnmarshaler != nil { + m := structPointer_Interface(base, st).(Message) + // First return value indicates whether tag is a oneof field. + ok, err = prop.oneofUnmarshaler(m, tag, wire, o) + if err == ErrInternalBadWireType { + // Map the error to something more descriptive. + // Do the formatting here to save generated code space. + err = fmt.Errorf("bad wiretype for oneof field in %T", m) + } + if ok { + continue + } + } err = o.skipAndSave(st, tag, wire, base, prop.unrecField) continue } @@ -518,9 +554,7 @@ func (o *Buffer) dec_string(p *Properties, base structPointer) error { if err != nil { return err } - sp := new(string) - *sp = s - *structPointer_String(base, p.field) = sp + *structPointer_String(base, p.field) = &s return nil } @@ -563,9 +597,13 @@ func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error return err } nb := int(nn) // number of bytes of encoded bools + fin := o.index + nb + if fin < o.index { + return errOverflow + } y := *v - for i := 0; i < nb; i++ { + for o.index < fin { u, err := p.valDec(o) if err != nil { return err @@ -677,7 +715,7 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { oi := o.index // index at the end of this map entry o.index -= len(raw) // move buffer back to start of map entry - mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V + mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V if mptr.Elem().IsNil() { mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) } @@ -729,8 +767,14 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { return fmt.Errorf("proto: bad map data tag %d", raw[0]) } } + keyelem, valelem := keyptr.Elem(), valptr.Elem() + if !keyelem.IsValid() || !valelem.IsValid() { + // We did not decode the key or the value in the map entry. + // Either way, it's an invalid map entry. + return fmt.Errorf("proto: bad map data: missing key/val") + } - v.SetMapIndex(keyptr.Elem(), valptr.Elem()) + v.SetMapIndex(keyelem, valelem) return nil } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go index 1512d605b2..231b07401a 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go @@ -60,9 +60,9 @@ func (e *RequiredNotSetError) Error() string { } var ( - // ErrRepeatedHasNil is the error returned if Marshal is called with + // errRepeatedHasNil is the error returned if Marshal is called with // a struct with a repeated field containing a nil element. - ErrRepeatedHasNil = errors.New("proto: repeated field has nil element") + errRepeatedHasNil = errors.New("proto: repeated field has nil element") // ErrNil is the error returned if Marshal is called with nil. ErrNil = errors.New("proto: Marshal called with nil") @@ -105,6 +105,11 @@ func (p *Buffer) EncodeVarint(x uint64) error { return nil } +// SizeVarint returns the varint encoding size of an integer. +func SizeVarint(x uint64) int { + return sizeVarint(x) +} + func sizeVarint(x uint64) (n int) { for { n++ @@ -228,6 +233,20 @@ func Marshal(pb Message) ([]byte, error) { return p.buf, err } +// EncodeMessage writes the protocol buffer to the Buffer, +// prefixed by a varint-encoded length. +func (p *Buffer) EncodeMessage(pb Message) error { + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return ErrNil + } + if err == nil { + var state errorState + err = p.enc_len_struct(GetProperties(t.Elem()), base, &state) + } + return err +} + // Marshal takes the protocol buffer // and encodes it into the wire format, writing the result to the // Buffer. @@ -318,7 +337,7 @@ func size_bool(p *Properties, base structPointer) int { func size_proto3_bool(p *Properties, base structPointer) int { v := *structPointer_BoolVal(base, p.field) - if !v { + if !v && !p.oneof { return 0 } return len(p.tagcode) + 1 // each bool takes exactly one byte @@ -361,7 +380,7 @@ func size_int32(p *Properties, base structPointer) (n int) { func size_proto3_int32(p *Properties, base structPointer) (n int) { v := structPointer_Word32Val(base, p.field) x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range - if x == 0 { + if x == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -407,7 +426,7 @@ func size_uint32(p *Properties, base structPointer) (n int) { func size_proto3_uint32(p *Properties, base structPointer) (n int) { v := structPointer_Word32Val(base, p.field) x := word32Val_Get(v) - if x == 0 { + if x == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -452,7 +471,7 @@ func size_int64(p *Properties, base structPointer) (n int) { func size_proto3_int64(p *Properties, base structPointer) (n int) { v := structPointer_Word64Val(base, p.field) x := word64Val_Get(v) - if x == 0 { + if x == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -495,7 +514,7 @@ func size_string(p *Properties, base structPointer) (n int) { func size_proto3_string(p *Properties, base structPointer) (n int) { v := *structPointer_StringVal(base, p.field) - if v == "" { + if v == "" && !p.oneof { return 0 } n += len(p.tagcode) @@ -529,7 +548,7 @@ func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error { } o.buf = append(o.buf, p.tagcode...) o.EncodeRawBytes(data) - return nil + return state.err } o.buf = append(o.buf, p.tagcode...) @@ -667,7 +686,7 @@ func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error func size_slice_byte(p *Properties, base structPointer) (n int) { s := *structPointer_Bytes(base, p.field) - if s == nil { + if s == nil && !p.oneof { return 0 } n += len(p.tagcode) @@ -677,7 +696,7 @@ func size_slice_byte(p *Properties, base structPointer) (n int) { func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { s := *structPointer_Bytes(base, p.field) - if len(s) == 0 { + if len(s) == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -939,7 +958,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err for i := 0; i < l; i++ { structp := s.Index(i) if structPointer_IsNil(structp) { - return ErrRepeatedHasNil + return errRepeatedHasNil } // Can the object marshal itself? @@ -958,7 +977,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err err := o.enc_len_struct(p.sprop, structp, &state) if err != nil && !state.shouldContinue(err, nil) { if err == ErrNil { - return ErrRepeatedHasNil + return errRepeatedHasNil } return err } @@ -1001,7 +1020,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error for i := 0; i < l; i++ { b := s.Index(i) if structPointer_IsNil(b) { - return ErrRepeatedHasNil + return errRepeatedHasNil } o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) @@ -1010,7 +1029,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error if err != nil && !state.shouldContinue(err, nil) { if err == ErrNil { - return ErrRepeatedHasNil + return errRepeatedHasNil } return err } @@ -1084,7 +1103,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { repeated MapFieldEntry map_field = N; */ - v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V + v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V if v.Len() == 0 { return nil } @@ -1101,11 +1120,15 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { return nil } - keys := v.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { + // Don't sort map keys. It is not required by the spec, and C++ doesn't do it. + for _, key := range v.MapKeys() { val := v.MapIndex(key) + // The only illegal map entry values are nil message pointers. + if val.Kind() == reflect.Ptr && val.IsNil() { + return errors.New("proto: map has nil element") + } + keycopy.Set(key) valcopy.Set(val) @@ -1118,7 +1141,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { } func size_new_map(p *Properties, base structPointer) int { - v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V + v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) @@ -1128,10 +1151,12 @@ func size_new_map(p *Properties, base structPointer) int { keycopy.Set(key) valcopy.Set(val) - // Tag codes are two bytes per map entry. - n += 2 - n += p.mkeyprop.size(p.mkeyprop, keybase) - n += p.mvalprop.size(p.mvalprop, valbase) + // Tag codes for key and val are the responsibility of the sub-sizer. + keysize := p.mkeyprop.size(p.mkeyprop, keybase) + valsize := p.mvalprop.size(p.mvalprop, valbase) + entry := keysize + valsize + // Add on tag code and length of map entry itself. + n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry } return n } @@ -1184,6 +1209,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { if p.Required && state.err == nil { state.err = &RequiredNotSetError{p.Name} } + } else if err == errRepeatedHasNil { + // Give more context to nil values in repeated fields. + return errors.New("repeated field " + p.OrigName + " has nil element") } else if !state.shouldContinue(err, p) { return err } @@ -1191,6 +1219,14 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { } } + // Do oneof fields. + if prop.oneofMarshaler != nil { + m := structPointer_Interface(base, prop.stype).(Message) + if err := prop.oneofMarshaler(m, o); err != nil { + return err + } + } + // Add unrecognized fields at the end. if prop.unrecField.IsValid() { v := *structPointer_Bytes(base, prop.unrecField) @@ -1216,6 +1252,12 @@ func size_struct(prop *StructProperties, base structPointer) (n int) { n += len(v) } + // Factor in any oneof fields. + if prop.oneofSizer != nil { + m := structPointer_Interface(base, prop.stype).(Message) + n += prop.oneofSizer(m) + } + return } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go index d8673a3e97..f5db1def3c 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go @@ -30,7 +30,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Protocol buffer comparison. -// TODO: MessageSet. package proto @@ -51,7 +50,9 @@ Equality is defined in this way: are equal, and extensions sets are equal. - Two set scalar fields are equal iff their values are equal. If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. + NaN != x for all x, including NaN. If the message is defined + in a proto3 .proto file, fields are not "set"; specifically, + zero length proto3 "bytes" fields are equal (nil == {}). - Two repeated fields are equal iff their lengths are the same, and their corresponding elements are equal (a "bytes" field, although represented by []byte, is not a repeated field) @@ -89,6 +90,7 @@ func Equal(a, b Message) bool { // v1 and v2 are known to have the same type. func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) for i := 0; i < v1.NumField(); i++ { f := v1.Type().Field(i) if strings.HasPrefix(f.Name, "XXX_") { @@ -114,7 +116,7 @@ func equalStruct(v1, v2 reflect.Value) bool { } f1, f2 = f1.Elem(), f2.Elem() } - if !equalAny(f1, f2) { + if !equalAny(f1, f2, sprop.Prop[i]) { return false } } @@ -141,7 +143,8 @@ func equalStruct(v1, v2 reflect.Value) bool { } // v1 and v2 are known to have the same type. -func equalAny(v1, v2 reflect.Value) bool { +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { if v1.Type() == protoMessageType { m1, _ := v1.Interface().(Message) m2, _ := v2.Interface().(Message) @@ -154,6 +157,17 @@ func equalAny(v1, v2 reflect.Value) bool { return v1.Float() == v2.Float() case reflect.Int32, reflect.Int64: return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2, nil) case reflect.Map: if v1.Len() != v2.Len() { return false @@ -164,16 +178,22 @@ func equalAny(v1, v2 reflect.Value) bool { // This key was not found in the second map. return false } - if !equalAny(v1.MapIndex(key), val2) { + if !equalAny(v1.MapIndex(key), val2, nil) { return false } } return true case reflect.Ptr: - return equalAny(v1.Elem(), v2.Elem()) + return equalAny(v1.Elem(), v2.Elem(), prop) case reflect.Slice: if v1.Type().Elem().Kind() == reflect.Uint8 { // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } if v1.IsNil() != v2.IsNil() { return false } @@ -184,7 +204,7 @@ func equalAny(v1, v2 reflect.Value) bool { return false } for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i)) { + if !equalAny(v1.Index(i), v2.Index(i), prop) { return false } } @@ -219,7 +239,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { if m1 != nil && m2 != nil { // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) { + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { return false } continue @@ -247,7 +267,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) return false } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) { + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { return false } } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go index f7667fab48..054f4f1df7 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go @@ -37,6 +37,7 @@ package proto import ( "errors" + "fmt" "reflect" "strconv" "sync" @@ -221,7 +222,7 @@ func ClearExtension(pb extendableProto, extension *ExtensionDesc) { } // GetExtension parses and returns the given extension of pb. -// If the extension is not present it returns ErrMissingExtension. +// If the extension is not present and has no default value it returns ErrMissingExtension. func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { if err := checkExtensionTypes(pb, extension); err != nil { return nil, err @@ -230,8 +231,11 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er emap := pb.ExtensionMap() e, ok := emap[extension.Field] if !ok { - return nil, ErrMissingExtension + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) } + if e.value != nil { // Already decoded. Check the descriptor, though. if e.desc != extension { @@ -257,12 +261,46 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er return e.value, nil } +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + // decodeExtension decodes an extension encoded in b. func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { o := NewBuffer(b) t := reflect.TypeOf(extension.ExtensionType) - rep := extension.repeated() props := extensionProperties(extension) @@ -284,7 +322,7 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { return nil, err } - if !rep || o.index >= len(o.buf) { + if o.index >= len(o.buf) { break } } @@ -321,6 +359,14 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{ if typ != reflect.TypeOf(value) { return errors.New("proto: bad extension value type") } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) + } pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} return nil diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go index 87c6b9d1ac..0de8f8dffd 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go @@ -30,171 +30,237 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* - Package proto converts data structures to and from the wire format of - protocol buffers. It works in concert with the Go source code generated - for .proto files by the protocol compiler. +Package proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. - A summary of the properties of the protocol buffer interface - for a protocol buffer variable v: +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - Helpers for getting values are superseded by the - GetFoo methods and their use is deprecated. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed with the enum's type name. Enum types have - a String method, and a Enum method to assist in message construction. - - Nested groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Marshal and Unmarshal are functions to encode and decode the wire format. + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. - The simplest way to describe this is to see an example. - Given file test.proto, containing +When the .proto file specifies `syntax="proto3"`, there are some differences: - package example; + - 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. - enum FOO { X = 17; }; +The simplest way to describe this is to see an example. +Given file test.proto, containing - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + oneof union { + int32 number = 6; + string name = 7; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/golang/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err } + *x = FOO(value) + return nil + } - The resulting file, test.pb.go, is: + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} - package example + type isTest_Union interface { + isTest_Union() + } - import "github.com/golang/protobuf/proto" + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union } - var FOO_value = map[string]int32{ - "X": 17, + return nil + } + const Default_Test_Type int32 = 77 + + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label } + return "" + } - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) + return Default_Test_Type + } + + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup } + return nil + } - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - XXX_unrecognized []byte `json:"-"` + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } + + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField } - func (this *Test) Reset() { *this = Test{} } - func (this *Test) String() string { return proto.CompactTextString(this) } - const Default_Test_Type int32 = 77 + return "" + } - func (this *Test) GetLabel() string { - if this != nil && this.Label != nil { - return *this.Label - } - return "" + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number } + return 0 + } - func (this *Test) GetType() int32 { - if this != nil && this.Type != nil { - return *this.Type - } - return Default_Test_Type + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name } + return "" + } - func (this *Test) GetOptionalgroup() *Test_OptionalGroup { - if this != nil { - return this.Optionalgroup - } - return nil + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } + +To create and play with a Test object: + + package main + + import ( + "log" + + "github.com/golang/protobuf/proto" + pb "./example.pb" + ) + + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + Union: &pb.Test_Name{"fred"}, } - - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - XXX_unrecognized []byte `json:"-"` + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) } - func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} } - func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) } - - func (this *Test_OptionalGroup) GetRequiredField() string { - if this != nil && this.RequiredField != nil { - return *this.RequiredField - } - return "" + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) } - - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) } - - To create and play with a Test object: - - package main - - import ( - "log" - - "github.com/golang/protobuf/proto" - "./example.pb" - ) - - func main() { - test := &example.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Optionalgroup: &example.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := new(example.Test) - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // etc. + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. } + // etc. + } */ package proto @@ -203,6 +269,7 @@ import ( "fmt" "log" "reflect" + "sort" "strconv" "sync" ) @@ -377,13 +444,13 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, // DebugPrint dumps the encoded data in b in a debugging format with a header // including the string s. Used in testing but made available for general debugging. -func (o *Buffer) DebugPrint(s string, b []byte) { +func (p *Buffer) DebugPrint(s string, b []byte) { var u uint64 - obuf := o.buf - index := o.index - o.buf = b - o.index = 0 + obuf := p.buf + index := p.index + p.buf = b + p.index = 0 depth := 0 fmt.Printf("\n--- %s ---\n", s) @@ -394,12 +461,12 @@ out: fmt.Print(" ") } - index := o.index - if index == len(o.buf) { + index := p.index + if index == len(p.buf) { break } - op, err := o.DecodeVarint() + op, err := p.DecodeVarint() if err != nil { fmt.Printf("%3d: fetching op err %v\n", index, err) break out @@ -416,7 +483,7 @@ out: case WireBytes: var r []byte - r, err = o.DecodeRawBytes(false) + r, err = p.DecodeRawBytes(false) if err != nil { break out } @@ -437,7 +504,7 @@ out: fmt.Printf("\n") case WireFixed32: - u, err = o.DecodeFixed32() + u, err = p.DecodeFixed32() if err != nil { fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) break out @@ -445,16 +512,15 @@ out: fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) case WireFixed64: - u, err = o.DecodeFixed64() + u, err = p.DecodeFixed64() if err != nil { fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) break out } fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - break case WireVarint: - u, err = o.DecodeVarint() + u, err = p.DecodeVarint() if err != nil { fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) break out @@ -462,30 +528,22 @@ out: fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) case WireStartGroup: - if err != nil { - fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err) - break out - } fmt.Printf("%3d: t=%3d start\n", index, tag) depth++ case WireEndGroup: depth-- - if err != nil { - fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err) - break out - } fmt.Printf("%3d: t=%3d end\n", index, tag) } } if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth) + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) } fmt.Printf("\n") - o.buf = obuf - o.index = index + p.buf = obuf + p.index = index } // SetDefaults sets unset protocol buffer fields to their default values. @@ -599,13 +657,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) { for _, ni := range dm.nested { f := v.Field(ni) - if f.IsNil() { - continue - } - // f is *T or []*T - if f.Kind() == reflect.Ptr { + // f is *T or []*T or map[T]*T + switch f.Kind() { + case reflect.Ptr: + if f.IsNil() { + continue + } setDefaults(f, recur, zeros) - } else { + + case reflect.Slice: for i := 0; i < f.Len(); i++ { e := f.Index(i) if e.IsNil() { @@ -613,6 +673,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) { } setDefaults(e, recur, zeros) } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } } } } @@ -638,10 +707,6 @@ type scalarField struct { value interface{} // the proto-declared default value, or nil } -func ptrToStruct(t reflect.Type) bool { - return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct -} - // t is a struct type. func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { sprop := GetProperties(t) @@ -653,99 +718,177 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { } ft := t.Field(fi).Type - // nested messages - if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) { + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: dm.nested = append(dm.nested, fi) - continue + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) } - - sf := scalarField{ - index: fi, - kind: ft.Elem().Kind(), - } - - // scalar fields without defaults - if !prop.HasDefault { - dm.scalars = append(dm.scalars, sf) - continue - } - - // a scalar field: either *T or []byte - switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - log.Printf("proto: bad default bool %q: %v", prop.Default, err) - continue - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - log.Printf("proto: bad default float32 %q: %v", prop.Default, err) - continue - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - log.Printf("proto: bad default float64 %q: %v", prop.Default, err) - continue - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - log.Printf("proto: bad default int32 %q: %v", prop.Default, err) - continue - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - log.Printf("proto: bad default int64 %q: %v", prop.Default, err) - continue - } - sf.value = x - case reflect.String: - sf.value = prop.Default - case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - log.Printf("proto: bad default uint32 %q: %v", prop.Default, err) - continue - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - log.Printf("proto: bad default uint64 %q: %v", prop.Default, err) - continue - } - sf.value = x - default: - log.Printf("proto: unhandled def kind %v", ft.Elem().Kind()) - continue - } - - dm.scalars = append(dm.scalars, sf) } return dm } +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field + } + + case reflect.Slice: + switch ft.Elem().Kind() { + case reflect.Ptr: + nestedMessage = true // repeated message + case reflect.Uint8: + canHaveDefault = true // bytes field + } + + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } + } + + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + // Map fields may have key types of non-float scalars, strings and enums. // The easiest way to sort them in some deterministic order is to use fmt. // If this turns out to be inefficient we can always consider other options, // such as doing a Schwartzian transform. -type mapKeys []reflect.Value +func mapKeys(vs []reflect.Value) sort.Interface { + s := mapKeySorter{ + vs: vs, + // default Less function: textual comparison + less: func(a, b reflect.Value) bool { + return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface()) + }, + } -func (s mapKeys) Len() int { return len(s) } -func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s mapKeys) Less(i, j int) bool { - return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) + // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps; + // numeric keys are sorted numerically. + if len(vs) == 0 { + return s + } + switch vs[0].Kind() { + case reflect.Int32, reflect.Int64: + s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } + case reflect.Uint32, reflect.Uint64: + s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } + } + + return s } + +type mapKeySorter struct { + vs []reflect.Value + less func(a, b reflect.Value) bool +} + +func (s mapKeySorter) Len() int { return len(s.vs) } +func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } +func (s mapKeySorter) Less(i, j int) bool { + return s.less(s.vs[i], s.vs[j]) +} + +// isProto3Zero reports whether v is a zero proto3 value. +func isProto3Zero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return !v.Bool() + case reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint32, reflect.Uint64: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.String: + return v.String() == "" + } + return false +} + +// ProtoPackageIsVersion1 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const ProtoPackageIsVersion1 = true diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go index 9d912bce19..e25e01e637 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go @@ -44,11 +44,11 @@ import ( "sort" ) -// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID. +// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. // A message type ID is required for storing a protocol buffer in a message set. -var ErrNoMessageTypeId = errors.New("proto does not have a message type ID") +var errNoMessageTypeID = errors.New("proto does not have a message type ID") -// The first two types (_MessageSet_Item and MessageSet) +// The first two types (_MessageSet_Item and messageSet) // model what the protocol compiler produces for the following protocol message: // message MessageSet { // repeated group Item = 1 { @@ -58,27 +58,20 @@ var ErrNoMessageTypeId = errors.New("proto does not have a message type ID") // } // That is the MessageSet wire format. We can't use a proto to generate these // because that would introduce a circular dependency between it and this package. -// -// When a proto1 proto has a field that looks like: -// optional message info = 3; -// the protocol compiler produces a field in the generated struct that looks like: -// Info *_proto_.MessageSet `protobuf:"bytes,3,opt,name=info"` -// The package is automatically inserted so there is no need for that proto file to -// import this package. type _MessageSet_Item struct { TypeId *int32 `protobuf:"varint,2,req,name=type_id"` Message []byte `protobuf:"bytes,3,req,name=message"` } -type MessageSet struct { +type messageSet struct { Item []*_MessageSet_Item `protobuf:"group,1,rep"` XXX_unrecognized []byte // TODO: caching? } -// Make sure MessageSet is a Message. -var _ Message = (*MessageSet)(nil) +// Make sure messageSet is a Message. +var _ Message = (*messageSet)(nil) // messageTypeIder is an interface satisfied by a protocol buffer type // that may be stored in a MessageSet. @@ -86,7 +79,7 @@ type messageTypeIder interface { MessageTypeId() int32 } -func (ms *MessageSet) find(pb Message) *_MessageSet_Item { +func (ms *messageSet) find(pb Message) *_MessageSet_Item { mti, ok := pb.(messageTypeIder) if !ok { return nil @@ -100,24 +93,24 @@ func (ms *MessageSet) find(pb Message) *_MessageSet_Item { return nil } -func (ms *MessageSet) Has(pb Message) bool { +func (ms *messageSet) Has(pb Message) bool { if ms.find(pb) != nil { return true } return false } -func (ms *MessageSet) Unmarshal(pb Message) error { +func (ms *messageSet) Unmarshal(pb Message) error { if item := ms.find(pb); item != nil { return Unmarshal(item.Message, pb) } if _, ok := pb.(messageTypeIder); !ok { - return ErrNoMessageTypeId + return errNoMessageTypeID } return nil // TODO: return error instead? } -func (ms *MessageSet) Marshal(pb Message) error { +func (ms *messageSet) Marshal(pb Message) error { msg, err := Marshal(pb) if err != nil { return err @@ -130,7 +123,7 @@ func (ms *MessageSet) Marshal(pb Message) error { mti, ok := pb.(messageTypeIder) if !ok { - return ErrNoMessageTypeId + return errNoMessageTypeID } mtid := mti.MessageTypeId() @@ -141,9 +134,9 @@ func (ms *MessageSet) Marshal(pb Message) error { return nil } -func (ms *MessageSet) Reset() { *ms = MessageSet{} } -func (ms *MessageSet) String() string { return CompactTextString(ms) } -func (*MessageSet) ProtoMessage() {} +func (ms *messageSet) Reset() { *ms = messageSet{} } +func (ms *messageSet) String() string { return CompactTextString(ms) } +func (*messageSet) ProtoMessage() {} // Support for the message_set_wire_format message option. @@ -169,7 +162,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { } sort.Ints(ids) - ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))} + ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))} for _, id := range ids { e := m[int32(id)] // Remove the wire type and field number varint, as well as the length varint. @@ -186,7 +179,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. // It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option. func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { - ms := new(MessageSet) + ms := new(messageSet) if err := Unmarshal(buf, ms); err != nil { return err } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go index 93259a3d65..749919d250 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go @@ -29,7 +29,7 @@ // (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 appengine,!appenginevm +// +build appengine // This file contains an implementation of proto field accesses using package reflect. // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can @@ -144,8 +144,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { return structPointer_ifield(p, f).(*map[int32]Extension) } -// Map returns the reflect.Value for the address of a map field in the struct. -func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { +// NewAt returns the reflect.Value for a pointer to a field in the struct. +func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { return structPointer_field(p, f).Addr() } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go index c52db1ca5e..e9be0fe92e 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -29,7 +29,7 @@ // (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 !appengine appenginevm +// +build !appengine // This file contains the implementation of the proto field accesses using package unsafe. @@ -130,8 +130,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) } -// Map returns the reflect.Value for the address of a map field in the struct. -func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { +// NewAt returns the reflect.Value for a pointer to a field in the struct. +func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go index 730a595797..d4531c0563 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go @@ -37,6 +37,7 @@ package proto import ( "fmt" + "log" "os" "reflect" "sort" @@ -84,6 +85,15 @@ type decoder func(p *Buffer, prop *Properties, base structPointer) error // A valueDecoder decodes a single integer in a particular encoding. type valueDecoder func(o *Buffer) (x uint64, err error) +// A oneofMarshaler does the marshaling for all oneof fields in a message. +type oneofMarshaler func(Message, *Buffer) error + +// A oneofUnmarshaler does the unmarshaling for a oneof field in a message. +type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) + +// A oneofSizer does the sizing for all oneof fields in a message. +type oneofSizer func(Message) int + // tagMap is an optimization over map[int]int for typical protocol buffer // use-cases. Encoded protocol buffers are often in tag order with small tag // numbers. @@ -132,6 +142,22 @@ type StructProperties struct { order []int // list of struct field numbers in tag order unrecField field // field id of the XXX_unrecognized []byte field extendable bool // is this an extendable proto + + oneofMarshaler oneofMarshaler + oneofUnmarshaler oneofUnmarshaler + oneofSizer oneofSizer + stype reflect.Type + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties } // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. @@ -156,6 +182,7 @@ type Properties struct { Packed bool // relevant for repeated primitives only Enum string // set for enum types only proto3 bool // whether this is known to be a proto3 field; set for []byte only + oneof bool // whether this is a oneof field Default string // default value HasDefault bool // whether an explicit default was provided @@ -208,6 +235,9 @@ func (p *Properties) String() string { if p.proto3 { s += ",proto3" } + if p.oneof { + s += ",oneof" + } if len(p.Enum) > 0 { s += ",enum=" + p.Enum } @@ -284,6 +314,8 @@ func (p *Properties) Parse(s string) { p.Enum = f[5:] case f == "proto3": p.proto3 = true + case f == "oneof": + p.oneof = true case strings.HasPrefix(f, "def="): p.HasDefault = true p.Default = f[4:] // rest of string @@ -440,7 +472,12 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock p.enc = (*Buffer).enc_slice_byte p.dec = (*Buffer).dec_slice_byte p.size = size_slice_byte - if p.proto3 { + // This is a []byte, which is either a bytes field, + // or the value of a map field. In the latter case, + // we always encode an empty []byte, so we should not + // use the proto3 enc/size funcs. + // f == nil iff this is the key/value of a map field. + if p.proto3 && f != nil { p.enc = (*Buffer).enc_proto3_slice_byte p.size = size_proto3_slice_byte } @@ -595,7 +632,7 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF } var ( - mutex sync.Mutex + propertiesMu sync.RWMutex propertiesMap = make(map[reflect.Type]*StructProperties) ) @@ -605,13 +642,26 @@ func GetProperties(t reflect.Type) *StructProperties { if t.Kind() != reflect.Struct { panic("proto: type must have kind struct") } - mutex.Lock() - sprop := getPropertiesLocked(t) - mutex.Unlock() + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + if collectStats { + stats.Chit++ + } + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() return sprop } -// getPropertiesLocked requires that mutex is held. +// getPropertiesLocked requires that propertiesMu is held. func getPropertiesLocked(t reflect.Type) *StructProperties { if prop, ok := propertiesMap[t]; ok { if collectStats { @@ -647,6 +697,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { if f.Name == "XXX_unrecognized" { // special case prop.unrecField = toField(&f) } + oneof := f.Tag.Get("protobuf_oneof") != "" // special case prop.Prop[i] = p prop.order[i] = i if debug { @@ -656,7 +707,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { } print("\n") } - if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") { + if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof { fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") } } @@ -664,6 +715,41 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { // Re-order prop.order. sort.Sort(prop) + type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + var oots []interface{} + prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs() + prop.stype = t + + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + // build required counts // build tags reqCount := 0 @@ -722,3 +808,35 @@ func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[ } enumValueMaps[typeName] = valueMap } + +// EnumValueMap returns the mapping from names to integers of the +// enum type enumType, or a nil if not found. +func EnumValueMap(enumType string) map[string]int32 { + return enumValueMaps[enumType] +} + +// A registry of all linked message types. +// The string is a fully-qualified proto name ("pkg.Message"). +var ( + protoTypes = make(map[string]reflect.Type) + revProtoTypes = make(map[reflect.Type]string) +) + +// RegisterType is called from generated code and maps from the fully qualified +// proto name to the type (pointer to struct) of the protocol buffer. +func RegisterType(x Message, name string) { + if _, ok := protoTypes[name]; ok { + // TODO: Some day, make this a panic. + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + protoTypes[name] = t + revProtoTypes[t] = name +} + +// MessageName returns the fully-qualified proto name for the given message type. +func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } + +// MessageType returns the message type (pointer to struct) for a named message. +func MessageType(name string) reflect.Type { return protoTypes[name] } diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile b/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile deleted file mode 100644 index 75144b582e..0000000000 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# Go support for Protocol Buffers - Google's data interchange format -# -# Copyright 2014 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. - - -include ../../Make.protobuf - -all: regenerate - -regenerate: - rm -f proto3.pb.go - make proto3.pb.go - -# The following rules are just aids to development. Not needed for typical testing. - -diff: regenerate - git diff proto3.pb.go diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go new file mode 100644 index 0000000000..37c7782092 --- /dev/null +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go @@ -0,0 +1,122 @@ +// Code generated by protoc-gen-go. +// source: proto3_proto/proto3.proto +// DO NOT EDIT! + +/* +Package proto3_proto is a generated protocol buffer package. + +It is generated from these files: + proto3_proto/proto3.proto + +It has these top-level messages: + Message + Nested + MessageWithMap +*/ +package proto3_proto + +import proto "github.com/golang/protobuf/proto" +import testdata "github.com/golang/protobuf/proto/testdata" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +type Message_Humour int32 + +const ( + Message_UNKNOWN Message_Humour = 0 + Message_PUNS Message_Humour = 1 + Message_SLAPSTICK Message_Humour = 2 + Message_BILL_BAILEY Message_Humour = 3 +) + +var Message_Humour_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PUNS", + 2: "SLAPSTICK", + 3: "BILL_BAILEY", +} +var Message_Humour_value = map[string]int32{ + "UNKNOWN": 0, + "PUNS": 1, + "SLAPSTICK": 2, + "BILL_BAILEY": 3, +} + +func (x Message_Humour) String() string { + return proto.EnumName(Message_Humour_name, int32(x)) +} + +type Message struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"` + HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + ResultCount int64 `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"` + TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"` + Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"` + Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"` + Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"` + Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"` + Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} + +func (m *Message) GetNested() *Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *Message) GetTerrain() map[string]*Nested { + if m != nil { + return m.Terrain + } + return nil +} + +func (m *Message) GetProto2Field() *testdata.SubDefaults { + if m != nil { + return m.Proto2Field + } + return nil +} + +func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults { + if m != nil { + return m.Proto2Value + } + return nil +} + +type Nested struct { + Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"` +} + +func (m *Nested) Reset() { *m = Nested{} } +func (m *Nested) String() string { return proto.CompactTextString(m) } +func (*Nested) ProtoMessage() {} + +type MessageWithMap struct { + ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func init() { + proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value) +} diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto b/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto index 3e327ded1d..e2311d9294 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto @@ -31,6 +31,8 @@ syntax = "proto3"; +import "testdata/test.proto"; + package proto3_proto; message Message { @@ -51,8 +53,16 @@ message Message { repeated uint64 key = 5; Nested nested = 6; + + map terrain = 10; + testdata.SubDefaults proto2_field = 11; + map proto2_value = 13; } message Nested { string bunny = 1; } + +message MessageWithMap { + map byte_mapping = 1; +} diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go index 720eac4705..2336b144c1 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go @@ -37,11 +37,11 @@ import ( "bufio" "bytes" "encoding" + "errors" "fmt" "io" "log" "math" - "os" "reflect" "sort" "strings" @@ -170,20 +170,12 @@ func writeName(w *textWriter, props *Properties) error { return nil } -var ( - messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem() -) - // raw is the interface satisfied by RawMessage. type raw interface { Bytes() []byte } func writeStruct(w *textWriter, sv reflect.Value) error { - if sv.Type() == messageSetType { - return writeMessageSet(w, sv.Addr().Interface().(*MessageSet)) - } - st := sv.Type() sprops := GetProperties(st) for i := 0; i < sv.NumField(); i++ { @@ -246,7 +238,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } if fv.Kind() == reflect.Map { // Map fields are rendered as a repeated struct with key/value fields. - keys := fv.MapKeys() // TODO: should we sort these for deterministic output? + keys := fv.MapKeys() sort.Sort(mapKeys(keys)) for _, key := range keys { val := fv.MapIndex(key) @@ -283,20 +275,23 @@ func writeStruct(w *textWriter, sv reflect.Value) error { if err := w.WriteByte('\n'); err != nil { return err } - // value - if _, err := w.WriteString("value:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { + // nil values aren't legal, but we can avoid panicking because of them. + if val.Kind() != reflect.Ptr || !val.IsNil() { + // value + if _, err := w.WriteString("value:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, val, props.mvalprop); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { return err } - } - if err := writeAny(w, val, props.mvalprop); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err } // close struct w.unindent() @@ -315,26 +310,34 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { // proto3 non-repeated scalar field; skip if zero value - switch fv.Kind() { - case reflect.Bool: - if !fv.Bool() { + if isProto3Zero(fv) { + continue + } + } + + if fv.Kind() == reflect.Interface { + // Check if it is a oneof. + if st.Field(i).Tag.Get("protobuf_oneof") != "" { + // fv is nil, or holds a pointer to generated struct. + // That generated struct has exactly one field, + // which has a protobuf struct tag. + if fv.IsNil() { continue } - case reflect.Int32, reflect.Int64: - if fv.Int() == 0 { - continue - } - case reflect.Uint32, reflect.Uint64: - if fv.Uint() == 0 { - continue - } - case reflect.Float32, reflect.Float64: - if fv.Float() == 0 { - continue - } - case reflect.String: - if fv.String() == "" { - continue + inner := fv.Elem().Elem() // interface -> *T -> T + tag := inner.Type().Field(0).Tag.Get("protobuf") + props = new(Properties) // Overwrite the outer props var, but not its pointee. + props.Parse(tag) + // Write the value in the oneof, not the oneof itself. + fv = inner.Field(0) + + // Special case to cope with malformed messages gracefully: + // If the value in the oneof is a nil pointer, don't panic + // in writeAny. + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Use errors.New so writeAny won't render quotes. + msg := errors.New("/* nil */") + fv = reflect.ValueOf(&msg).Elem() } } } @@ -514,44 +517,6 @@ func writeString(w *textWriter, s string) error { return w.WriteByte('"') } -func writeMessageSet(w *textWriter, ms *MessageSet) error { - for _, item := range ms.Item { - id := *item.TypeId - if msd, ok := messageSetMap[id]; ok { - // Known message set type. - if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil { - return err - } - w.indent() - - pb := reflect.New(msd.t.Elem()) - if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil { - if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil { - return err - } - } else { - if err := writeStruct(w, pb.Elem()); err != nil { - return err - } - } - } else { - // Unknown type. - if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil { - return err - } - w.indent() - if err := writeUnknownStruct(w, item.Message); err != nil { - return err - } - } - w.unindent() - if _, err := w.Write(gtNewline); err != nil { - return err - } - } - return nil -} - func writeUnknownStruct(w *textWriter, data []byte) (err error) { if !w.compact { if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { @@ -666,10 +631,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error { pb, err := GetExtension(ep, desc) if err != nil { - if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil { - return err - } - continue + return fmt.Errorf("failed getting extension: %v", err) } // Repeated extensions will appear as a slice. diff --git a/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go b/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go index ddd9579cdf..451323262c 100644 --- a/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go +++ b/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go @@ -119,6 +119,14 @@ func isWhitespace(c byte) bool { return false } +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} + func (p *textParser) skipWhitespace() { i := 0 for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { @@ -174,7 +182,7 @@ func (p *textParser) advance() { } unq, err := unquoteC(p.s[1:i], rune(p.s[0])) if err != nil { - p.errorf("invalid quoted string %v", p.s[0:i+1]) + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) return } p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] @@ -333,13 +341,13 @@ func (p *textParser) next() *token { p.advance() if p.done { p.cur.value = "" - } else if len(p.cur.value) > 0 && p.cur.value[0] == '"' { + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { // Look for multiple quoted strings separated by whitespace, // and concatenate them. cat := p.cur for { p.skipWhitespace() - if p.done || p.s[0] != '"' { + if p.done || !isQuote(p.s[0]) { break } p.advance() @@ -385,8 +393,7 @@ func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSet } // Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) { - sprops := GetProperties(st) +func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { i, ok := sprops.decoderOrigNames[name] if ok { return i, sprops.Prop[i], true @@ -438,7 +445,8 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr func (p *textParser) readStruct(sv reflect.Value, terminator string) error { st := sv.Type() - reqCount := GetProperties(st).reqCount + sprops := GetProperties(st) + reqCount := sprops.reqCount var reqFieldErr error fieldSet := make(map[string]bool) // A struct is a sequence of "name: value", terminated by one of @@ -520,99 +528,113 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { sl = reflect.Append(sl, ext) SetExtension(ep, desc, sl.Interface()) } - } else { - // This is a normal, non-extension field. - name := tok.value - fi, props, ok := structFieldByName(st, name) - if !ok { - return p.errorf("unknown field name %q in %v", name, st) + if err := p.consumeOptionalSeparator(); err != nil { + return err } + continue + } - dst := sv.Field(fi) + // This is a normal, non-extension field. + name := tok.value + var dst reflect.Value + fi, props, ok := structFieldByName(sprops, name) + if ok { + dst = sv.Field(fi) + } else if oop, ok := sprops.OneofTypes[name]; ok { + // It is a oneof. + props = oop.Prop + nv := reflect.New(oop.Type.Elem()) + dst = nv.Elem().Field(0) + sv.Field(oop.Field).Set(nv) + } + if !dst.IsValid() { + return p.errorf("unknown field name %q in %v", name, st) + } - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // Technically the "key" and "value" could come in any order, - // but in practice they won't. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - if err := p.consumeToken("key"); err != nil { - return err - } - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.mkeyprop); err != nil { - return err - } - if err := p.consumeToken("value"); err != nil { - return err - } - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(val, props.mvalprop); err != nil { - return err - } - if err := p.consumeToken(terminator); err != nil { - return err - } - - dst.SetMapIndex(key, val) - continue - } - - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) - } - - if err := p.checkForColon(props, st.Field(fi).Type); err != nil { + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { return err } - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } else if props.Required { - reqCount-- + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) } + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // Technically the "key" and "value" could come in any order, + // but in practice they won't. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + if err := p.consumeToken("key"); err != nil { + return err + } + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.mkeyprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken("value"); err != nil { + return err + } + if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.mvalprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken(terminator); err != nil { + return err + } + + dst.SetMapIndex(key, val) + continue } - // For backward compatibility, permit a semicolon or comma after a field. - tok = p.next() - if tok.err != nil { - return tok.err + // Check that it's not already set if it's not a repeated field. + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) } - if tok.value != ";" && tok.value != "," { - p.back() + + if err := p.checkForColon(props, dst.Type()); err != nil { + return err } + + // Parse into the field. + fieldSet[name] = true + if err := p.readAny(dst, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } else if props.Required { + reqCount-- + } + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + } if reqCount > 0 { @@ -621,6 +643,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { return reqFieldErr } +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in readStruct to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + func (p *textParser) readAny(v reflect.Value, props *Properties) error { tok := p.next() if tok.err != nil { @@ -645,18 +680,32 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error { fv.Set(reflect.ValueOf(bytes)) return nil } - // Repeated field. May already exist. - flen := fv.Len() - if flen == fv.Cap() { - nav := reflect.MakeSlice(at, flen, 2*flen+1) - reflect.Copy(nav, fv) - fv.Set(nav) + // Repeated field. + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + err := p.readAny(fv.Index(fv.Len()-1), props) + if err != nil { + return err + } + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "]" { + break + } + if tok.value != "," { + return p.errorf("Expected ']' or ',' found %q", tok.value) + } + } + return nil } - fv.SetLen(flen + 1) - - // Read one. + // One value of the repeated field. p.back() - return p.readAny(fv.Index(flen), props) + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + return p.readAny(fv.Index(fv.Len()-1), props) case reflect.Bool: // Either "true", "false", 1 or 0. switch tok.value { diff --git a/Godeps/_workspace/src/golang.org/x/net/http2/.gitignore b/Godeps/_workspace/src/golang.org/x/net/http2/.gitignore new file mode 100644 index 0000000000..190f12234a --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/http2/.gitignore @@ -0,0 +1,2 @@ +*~ +h2i/h2i diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/Dockerfile b/Godeps/_workspace/src/golang.org/x/net/http2/Dockerfile similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/Dockerfile rename to Godeps/_workspace/src/golang.org/x/net/http2/Dockerfile diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/Makefile b/Godeps/_workspace/src/golang.org/x/net/http2/Makefile similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/Makefile rename to Godeps/_workspace/src/golang.org/x/net/http2/Makefile diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/README b/Godeps/_workspace/src/golang.org/x/net/http2/README similarity index 67% rename from Godeps/_workspace/src/github.com/bradfitz/http2/README rename to Godeps/_workspace/src/golang.org/x/net/http2/README index 16cb516a69..aba8ae5ef6 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/README +++ b/Godeps/_workspace/src/golang.org/x/net/http2/README @@ -10,8 +10,11 @@ Status: * The client work has just started but shares a lot of code is coming along much quicker. -Docs are at https://godoc.org/github.com/bradfitz/http2 +Docs are at https://godoc.org/golang.org/x/net/http2 Demo test server at https://http2.golang.org/ -Help & bug reports welcome. +Help & bug reports welcome! + +Contributing: https://golang.org/doc/contribute.html +Bugs: https://github.com/golang/go/issues/new?title=x/net/http2:+ diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/buffer.go b/Godeps/_workspace/src/golang.org/x/net/http2/buffer.go similarity index 89% rename from Godeps/_workspace/src/github.com/bradfitz/http2/buffer.go rename to Godeps/_workspace/src/golang.org/x/net/http2/buffer.go index 48d7561ecf..c43954cf04 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/buffer.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/buffer.go @@ -19,8 +19,9 @@ type buffer struct { } var ( - errReadEmpty = errors.New("read from empty buffer") - errWriteFull = errors.New("write on full buffer") + errReadEmpty = errors.New("read from empty buffer") + errWriteClosed = errors.New("write on closed buffer") + errWriteFull = errors.New("write on full buffer") ) // Read copies bytes from the buffer into p. @@ -45,7 +46,7 @@ func (b *buffer) Len() int { // It is an error to write more data than the buffer can hold. func (b *buffer) Write(p []byte) (n int, err error) { if b.closed { - return 0, errors.New("closed") + return 0, errWriteClosed } // Slide existing data to beginning. diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/errors.go b/Godeps/_workspace/src/golang.org/x/net/http2/errors.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/errors.go rename to Godeps/_workspace/src/golang.org/x/net/http2/errors.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/flow.go b/Godeps/_workspace/src/golang.org/x/net/http2/flow.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/flow.go rename to Godeps/_workspace/src/golang.org/x/net/http2/flow.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/frame.go b/Godeps/_workspace/src/golang.org/x/net/http2/frame.go similarity index 99% rename from Godeps/_workspace/src/github.com/bradfitz/http2/frame.go rename to Godeps/_workspace/src/golang.org/x/net/http2/frame.go index 94c5e44ae5..e8b872a19b 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/frame.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/frame.go @@ -85,8 +85,8 @@ const ( // Continuation Frame FlagContinuationEndHeaders Flags = 0x4 - FlagPushPromiseEndHeaders = 0x4 - FlagPushPromisePadded = 0x8 + FlagPushPromiseEndHeaders Flags = 0x4 + FlagPushPromisePadded Flags = 0x8 ) var flagName = map[FrameType]map[Flags]string{ diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/gotrack.go b/Godeps/_workspace/src/golang.org/x/net/http2/gotrack.go similarity index 96% rename from Godeps/_workspace/src/github.com/bradfitz/http2/gotrack.go rename to Godeps/_workspace/src/golang.org/x/net/http2/gotrack.go index 6e1a3823ca..7dc2ef90db 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/gotrack.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/gotrack.go @@ -14,16 +14,20 @@ import ( "bytes" "errors" "fmt" + "os" "runtime" "strconv" "sync" ) -var DebugGoroutines = false +var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" type goroutineLock uint64 func newGoroutineLock() goroutineLock { + if !DebugGoroutines { + return 0 + } return goroutineLock(curGoroutineID()) } diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/.gitignore b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/.gitignore similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/.gitignore rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/.gitignore diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/Makefile b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/Makefile similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/Makefile rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/Makefile diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/README b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/README similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/README rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/README diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/h2demo.go b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/h2demo.go similarity index 93% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/h2demo.go rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/h2demo.go index de6caaa749..9429a72545 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/h2demo.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/h2demo.go @@ -31,7 +31,7 @@ import ( "camlistore.org/pkg/googlestorage" "camlistore.org/pkg/singleflight" - "github.com/bradfitz/http2" + "golang.org/x/net/http2" ) var ( @@ -51,7 +51,7 @@ func homeOldHTTP(w http.ResponseWriter, r *http.Request) {
  • Use Firefox Nightly or go to about:config and enable "network.http.spdy.enabled.http2draft"
  • Use Google Chrome Canary and/or go to chrome://flags/#enable-spdy4 to Enable SPDY/4 (Chrome's name for HTTP/2)
  • -

    See code & instructions for connecting at https://github.com/bradfitz/http2.

    +

    See code & instructions for connecting at https://github.com/golang/net/tree/master/http2.

    `) } @@ -73,12 +73,12 @@ href="https://http2.github.io/">HTTP/2 demo & interop server.

    This server exists for others in the HTTP/2 community to test their HTTP/2 client implementations and point out flaws in our server.

    The code is currently at github.com/bradfitz/http2 +href="https://golang.org/x/net/http2">github.com/bradfitz/http2 but will move to the Go standard library at some point in the future (enabled by default, without users needing to change their code).

    Contact info: bradfitz@golang.org, or file a bug.

    +href="https://golang.org/x/net/http2/issues">file a bug.

    Handlers for testing

      @@ -287,7 +287,7 @@ func newGopherTilesHandler() http.Handler { return } } - io.WriteString(w, "") + io.WriteString(w, "") fmt.Fprintf(w, "A grid of %d tiled images is below. Compare:

      ", xt*yt) for _, ms := range []int{0, 30, 200, 1000} { d := time.Duration(ms) * nanosPerMilli @@ -305,7 +305,16 @@ func newGopherTilesHandler() http.Handler { } io.WriteString(w, "
      \n") } - io.WriteString(w, "


      << Back to Go HTTP/2 demo server") + io.WriteString(w, `

      + +
      << Back to Go HTTP/2 demo server`) }) } diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/launch.go b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/launch.go similarity index 86% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/launch.go rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/launch.go index 2eb709bdd3..746661543e 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/launch.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/launch.go @@ -20,8 +20,9 @@ import ( "strings" "time" - "code.google.com/p/goauth2/oauth" - compute "code.google.com/p/google-api-go-client/compute/v1" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + compute "google.golang.org/api/compute/v1" ) var ( @@ -44,19 +45,18 @@ func readFile(v string) string { return strings.TrimSpace(string(slurp)) } -var config = &oauth.Config{ +var config = &oauth2.Config{ // The client-id and secret should be for an "Installed Application" when using // the CLI. Later we'll use a web application with a callback. - ClientId: readFile("client-id.dat"), + ClientID: readFile("client-id.dat"), ClientSecret: readFile("client-secret.dat"), - Scope: strings.Join([]string{ + Endpoint: google.Endpoint, + Scopes: []string{ compute.DevstorageFull_controlScope, compute.ComputeScope, "https://www.googleapis.com/auth/sqlservice", "https://www.googleapis.com/auth/sqlservice.admin", - }, " "), - AuthURL: "https://accounts.google.com/o/oauth2/auth", - TokenURL: "https://accounts.google.com/o/oauth2/token", + }, RedirectURL: "urn:ietf:wg:oauth:2.0:oob", } @@ -88,31 +88,32 @@ func main() { prefix := "https://www.googleapis.com/compute/v1/projects/" + *proj machType := prefix + "/zones/" + *zone + "/machineTypes/" + *mach - tr := &oauth.Transport{ - Config: config, - } - - tokenCache := oauth.CacheFile("token.dat") - token, err := tokenCache.Token() + const tokenFileName = "token.dat" + tokenFile := tokenCacheFile(tokenFileName) + tokenSource := oauth2.ReuseTokenSource(nil, tokenFile) + token, err := tokenSource.Token() if err != nil { if *writeObject != "" { log.Fatalf("Can't use --write_object without a valid token.dat file already cached.") } - log.Printf("Error getting token from %s: %v", string(tokenCache), err) + log.Printf("Error getting token from %s: %v", tokenFileName, err) log.Printf("Get auth code from %v", config.AuthCodeURL("my-state")) fmt.Print("\nEnter auth code: ") sc := bufio.NewScanner(os.Stdin) sc.Scan() authCode := strings.TrimSpace(sc.Text()) - token, err = tr.Exchange(authCode) + token, err = config.Exchange(oauth2.NoContext, authCode) if err != nil { log.Fatalf("Error exchanging auth code for a token: %v", err) } - tokenCache.PutToken(token) + if err := tokenFile.WriteToken(token); err != nil { + log.Fatalf("Error writing to %s: %v", tokenFileName, err) + } + tokenSource = oauth2.ReuseTokenSource(token, nil) } - tr.Token = token - oauthClient := &http.Client{Transport: tr} + oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource) + if *writeObject != "" { writeCloudStorageObject(oauthClient) return @@ -277,3 +278,25 @@ func writeCloudStorageObject(httpClient *http.Client) { log.Printf("Success.") os.Exit(0) } + +type tokenCacheFile string + +func (f tokenCacheFile) Token() (*oauth2.Token, error) { + slurp, err := ioutil.ReadFile(string(f)) + if err != nil { + return nil, err + } + t := new(oauth2.Token) + if err := json.Unmarshal(slurp, t); err != nil { + return nil, err + } + return t, nil +} + +func (f tokenCacheFile) WriteToken(t *oauth2.Token) error { + jt, err := json.Marshal(t) + if err != nil { + return err + } + return ioutil.WriteFile(string(f), jt, 0600) +} diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.key b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.key similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.key rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.key diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.pem b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.pem similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.pem rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.pem diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.srl b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.srl similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.srl rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.srl diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/server.crt b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/server.crt similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/server.crt rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/server.crt diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/server.key b/Godeps/_workspace/src/golang.org/x/net/http2/h2demo/server.key similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/server.key rename to Godeps/_workspace/src/golang.org/x/net/http2/h2demo/server.key diff --git a/Godeps/_workspace/src/golang.org/x/net/http2/h2i/README.md b/Godeps/_workspace/src/golang.org/x/net/http2/h2i/README.md new file mode 100644 index 0000000000..fb5c5efb0f --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/http2/h2i/README.md @@ -0,0 +1,97 @@ +# h2i + +**h2i** is an interactive HTTP/2 ("h2") console debugger. Miss the good ol' +days of telnetting to your HTTP/1.n servers? We're bringing you +back. + +Features: +- send raw HTTP/2 frames + - PING + - SETTINGS + - HEADERS + - etc +- type in HTTP/1.n and have it auto-HPACK/frame-ify it for HTTP/2 +- pretty print all received HTTP/2 frames from the peer (including HPACK decoding) +- tab completion of commands, options + +Not yet features, but soon: +- unnecessary CONTINUATION frames on short boundaries, to test peer implementations +- request bodies (DATA frames) +- send invalid frames for testing server implementations (supported by underlying Framer) + +Later: +- act like a server + +## Installation + +``` +$ go get golang.org/x/net/http2/h2i +$ h2i +``` + +## Demo + +``` +$ h2i +Usage: h2i + + -insecure + Whether to skip TLS cert validation + -nextproto string + Comma-separated list of NPN/ALPN protocol names to negotiate. (default "h2,h2-14") + +$ h2i google.com +Connecting to google.com:443 ... +Connected to 74.125.224.41:443 +Negotiated protocol "h2-14" +[FrameHeader SETTINGS len=18] + [MAX_CONCURRENT_STREAMS = 100] + [INITIAL_WINDOW_SIZE = 1048576] + [MAX_FRAME_SIZE = 16384] +[FrameHeader WINDOW_UPDATE len=4] + Window-Increment = 983041 + +h2i> PING h2iSayHI +[FrameHeader PING flags=ACK len=8] + Data = "h2iSayHI" +h2i> headers +(as HTTP/1.1)> GET / HTTP/1.1 +(as HTTP/1.1)> Host: ip.appspot.com +(as HTTP/1.1)> User-Agent: h2i/brad-n-blake +(as HTTP/1.1)> +Opening Stream-ID 1: + :authority = ip.appspot.com + :method = GET + :path = / + :scheme = https + user-agent = h2i/brad-n-blake +[FrameHeader HEADERS flags=END_HEADERS stream=1 len=77] + :status = "200" + alternate-protocol = "443:quic,p=1" + content-length = "15" + content-type = "text/html" + date = "Fri, 01 May 2015 23:06:56 GMT" + server = "Google Frontend" +[FrameHeader DATA flags=END_STREAM stream=1 len=15] + "173.164.155.78\n" +[FrameHeader PING len=8] + Data = "\x00\x00\x00\x00\x00\x00\x00\x00" +h2i> ping +[FrameHeader PING flags=ACK len=8] + Data = "h2i_ping" +h2i> ping +[FrameHeader PING flags=ACK len=8] + Data = "h2i_ping" +h2i> ping +[FrameHeader GOAWAY len=22] + Last-Stream-ID = 1; Error-Code = PROTOCOL_ERROR (1) + +ReadFrame: EOF +``` + +## Status + +Quick few hour hack. So much yet to do. Feel free to file issues for +bugs or wishlist items, but [@bmizerany](https://github.com/bmizerany/) +and I aren't yet accepting pull requests until things settle down. + diff --git a/Godeps/_workspace/src/golang.org/x/net/http2/h2i/h2i.go b/Godeps/_workspace/src/golang.org/x/net/http2/h2i/h2i.go new file mode 100644 index 0000000000..73efe86011 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/http2/h2i/h2i.go @@ -0,0 +1,489 @@ +// 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. +// See https://code.google.com/p/go/source/browse/CONTRIBUTORS +// Licensed under the same terms as Go itself: +// https://code.google.com/p/go/source/browse/LICENSE + +/* +The h2i command is an interactive HTTP/2 console. + +Usage: + $ h2i [flags] + +Interactive commands in the console: (all parts case-insensitive) + + ping [data] + settings ack + settings FOO=n BAR=z + headers (open a new stream by typing HTTP/1.1) +*/ +package main + +import ( + "bufio" + "bytes" + "crypto/tls" + "errors" + "flag" + "fmt" + "io" + "log" + "net" + "net/http" + "os" + "regexp" + "strconv" + "strings" + + "golang.org/x/crypto/ssh/terminal" + "golang.org/x/net/http2" + "golang.org/x/net/http2/hpack" +) + +// Flags +var ( + flagNextProto = flag.String("nextproto", "h2,h2-14", "Comma-separated list of NPN/ALPN protocol names to negotiate.") + flagInsecure = flag.Bool("insecure", false, "Whether to skip TLS cert validation") +) + +type command struct { + run func(*h2i, []string) error // required + + // complete optionally specifies tokens (case-insensitive) which are + // valid for this subcommand. + complete func() []string +} + +var commands = map[string]command{ + "ping": command{run: (*h2i).cmdPing}, + "settings": command{ + run: (*h2i).cmdSettings, + complete: func() []string { + return []string{ + "ACK", + http2.SettingHeaderTableSize.String(), + http2.SettingEnablePush.String(), + http2.SettingMaxConcurrentStreams.String(), + http2.SettingInitialWindowSize.String(), + http2.SettingMaxFrameSize.String(), + http2.SettingMaxHeaderListSize.String(), + } + }, + }, + "quit": command{run: (*h2i).cmdQuit}, + "headers": command{run: (*h2i).cmdHeaders}, +} + +func usage() { + fmt.Fprintf(os.Stderr, "Usage: h2i \n\n") + flag.PrintDefaults() + os.Exit(1) +} + +// withPort adds ":443" if another port isn't already present. +func withPort(host string) string { + if _, _, err := net.SplitHostPort(host); err != nil { + return net.JoinHostPort(host, "443") + } + return host +} + +// h2i is the app's state. +type h2i struct { + host string + tc *tls.Conn + framer *http2.Framer + term *terminal.Terminal + + // owned by the command loop: + streamID uint32 + hbuf bytes.Buffer + henc *hpack.Encoder + + // owned by the readFrames loop: + peerSetting map[http2.SettingID]uint32 + hdec *hpack.Decoder +} + +func main() { + flag.Usage = usage + flag.Parse() + if flag.NArg() != 1 { + usage() + } + log.SetFlags(0) + + host := flag.Arg(0) + app := &h2i{ + host: host, + peerSetting: make(map[http2.SettingID]uint32), + } + app.henc = hpack.NewEncoder(&app.hbuf) + + if err := app.Main(); err != nil { + if app.term != nil { + app.logf("%v\n", err) + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "\n") +} + +func (app *h2i) Main() error { + cfg := &tls.Config{ + ServerName: app.host, + NextProtos: strings.Split(*flagNextProto, ","), + InsecureSkipVerify: *flagInsecure, + } + + hostAndPort := withPort(app.host) + log.Printf("Connecting to %s ...", hostAndPort) + tc, err := tls.Dial("tcp", hostAndPort, cfg) + if err != nil { + return fmt.Errorf("Error dialing %s: %v", withPort(app.host), err) + } + log.Printf("Connected to %v", tc.RemoteAddr()) + defer tc.Close() + + if err := tc.Handshake(); err != nil { + return fmt.Errorf("TLS handshake: %v", err) + } + if !*flagInsecure { + if err := tc.VerifyHostname(app.host); err != nil { + return fmt.Errorf("VerifyHostname: %v", err) + } + } + state := tc.ConnectionState() + log.Printf("Negotiated protocol %q", state.NegotiatedProtocol) + if !state.NegotiatedProtocolIsMutual || state.NegotiatedProtocol == "" { + return fmt.Errorf("Could not negotiate protocol mutually") + } + + if _, err := io.WriteString(tc, http2.ClientPreface); err != nil { + return err + } + + app.framer = http2.NewFramer(tc, tc) + + oldState, err := terminal.MakeRaw(0) + if err != nil { + return err + } + defer terminal.Restore(0, oldState) + + var screen = struct { + io.Reader + io.Writer + }{os.Stdin, os.Stdout} + + app.term = terminal.NewTerminal(screen, "h2i> ") + lastWord := regexp.MustCompile(`.+\W(\w+)$`) + app.term.AutoCompleteCallback = func(line string, pos int, key rune) (newLine string, newPos int, ok bool) { + if key != '\t' { + return + } + if pos != len(line) { + // TODO: we're being lazy for now, only supporting tab completion at the end. + return + } + // Auto-complete for the command itself. + if !strings.Contains(line, " ") { + var name string + name, _, ok = lookupCommand(line) + if !ok { + return + } + return name, len(name), true + } + _, c, ok := lookupCommand(line[:strings.IndexByte(line, ' ')]) + if !ok || c.complete == nil { + return + } + if strings.HasSuffix(line, " ") { + app.logf("%s", strings.Join(c.complete(), " ")) + return line, pos, true + } + m := lastWord.FindStringSubmatch(line) + if m == nil { + return line, len(line), true + } + soFar := m[1] + var match []string + for _, cand := range c.complete() { + if len(soFar) > len(cand) || !strings.EqualFold(cand[:len(soFar)], soFar) { + continue + } + match = append(match, cand) + } + if len(match) == 0 { + return + } + if len(match) > 1 { + // TODO: auto-complete any common prefix + app.logf("%s", strings.Join(match, " ")) + return line, pos, true + } + newLine = line[:len(line)-len(soFar)] + match[0] + return newLine, len(newLine), true + + } + + errc := make(chan error, 2) + go func() { errc <- app.readFrames() }() + go func() { errc <- app.readConsole() }() + return <-errc +} + +func (app *h2i) logf(format string, args ...interface{}) { + fmt.Fprintf(app.term, format+"\n", args...) +} + +func (app *h2i) readConsole() error { + for { + line, err := app.term.ReadLine() + if err == io.EOF { + return nil + } + if err != nil { + return fmt.Errorf("terminal.ReadLine: %v", err) + } + f := strings.Fields(line) + if len(f) == 0 { + continue + } + cmd, args := f[0], f[1:] + if _, c, ok := lookupCommand(cmd); ok { + err = c.run(app, args) + } else { + app.logf("Unknown command %q", line) + } + if err == errExitApp { + return nil + } + if err != nil { + return err + } + } +} + +func lookupCommand(prefix string) (name string, c command, ok bool) { + prefix = strings.ToLower(prefix) + if c, ok = commands[prefix]; ok { + return prefix, c, ok + } + + for full, candidate := range commands { + if strings.HasPrefix(full, prefix) { + if c.run != nil { + return "", command{}, false // ambiguous + } + c = candidate + name = full + } + } + return name, c, c.run != nil +} + +var errExitApp = errors.New("internal sentinel error value to quit the console reading loop") + +func (a *h2i) cmdQuit(args []string) error { + if len(args) > 0 { + a.logf("the QUIT command takes no argument") + return nil + } + return errExitApp +} + +func (a *h2i) cmdSettings(args []string) error { + if len(args) == 1 && strings.EqualFold(args[0], "ACK") { + return a.framer.WriteSettingsAck() + } + var settings []http2.Setting + for _, arg := range args { + if strings.EqualFold(arg, "ACK") { + a.logf("Error: ACK must be only argument with the SETTINGS command") + return nil + } + eq := strings.Index(arg, "=") + if eq == -1 { + a.logf("Error: invalid argument %q (expected SETTING_NAME=nnnn)", arg) + return nil + } + sid, ok := settingByName(arg[:eq]) + if !ok { + a.logf("Error: unknown setting name %q", arg[:eq]) + return nil + } + val, err := strconv.ParseUint(arg[eq+1:], 10, 32) + if err != nil { + a.logf("Error: invalid argument %q (expected SETTING_NAME=nnnn)", arg) + return nil + } + settings = append(settings, http2.Setting{ + ID: sid, + Val: uint32(val), + }) + } + a.logf("Sending: %v", settings) + return a.framer.WriteSettings(settings...) +} + +func settingByName(name string) (http2.SettingID, bool) { + for _, sid := range [...]http2.SettingID{ + http2.SettingHeaderTableSize, + http2.SettingEnablePush, + http2.SettingMaxConcurrentStreams, + http2.SettingInitialWindowSize, + http2.SettingMaxFrameSize, + http2.SettingMaxHeaderListSize, + } { + if strings.EqualFold(sid.String(), name) { + return sid, true + } + } + return 0, false +} + +func (app *h2i) cmdPing(args []string) error { + if len(args) > 1 { + app.logf("invalid PING usage: only accepts 0 or 1 args") + return nil // nil means don't end the program + } + var data [8]byte + if len(args) == 1 { + copy(data[:], args[0]) + } else { + copy(data[:], "h2i_ping") + } + return app.framer.WritePing(false, data) +} + +func (app *h2i) cmdHeaders(args []string) error { + if len(args) > 0 { + app.logf("Error: HEADERS doesn't yet take arguments.") + // TODO: flags for restricting window size, to force CONTINUATION + // frames. + return nil + } + var h1req bytes.Buffer + app.term.SetPrompt("(as HTTP/1.1)> ") + defer app.term.SetPrompt("h2i> ") + for { + line, err := app.term.ReadLine() + if err != nil { + return err + } + h1req.WriteString(line) + h1req.WriteString("\r\n") + if line == "" { + break + } + } + req, err := http.ReadRequest(bufio.NewReader(&h1req)) + if err != nil { + app.logf("Invalid HTTP/1.1 request: %v", err) + return nil + } + if app.streamID == 0 { + app.streamID = 1 + } else { + app.streamID += 2 + } + app.logf("Opening Stream-ID %d:", app.streamID) + hbf := app.encodeHeaders(req) + if len(hbf) > 16<<10 { + app.logf("TODO: h2i doesn't yet write CONTINUATION frames. Copy it from transport.go") + return nil + } + return app.framer.WriteHeaders(http2.HeadersFrameParam{ + StreamID: app.streamID, + BlockFragment: hbf, + EndStream: req.Method == "GET" || req.Method == "HEAD", // good enough for now + EndHeaders: true, // for now + }) +} + +func (app *h2i) readFrames() error { + for { + f, err := app.framer.ReadFrame() + if err != nil { + return fmt.Errorf("ReadFrame: %v", err) + } + app.logf("%v", f) + switch f := f.(type) { + case *http2.PingFrame: + app.logf(" Data = %q", f.Data) + case *http2.SettingsFrame: + f.ForeachSetting(func(s http2.Setting) error { + app.logf(" %v", s) + app.peerSetting[s.ID] = s.Val + return nil + }) + case *http2.WindowUpdateFrame: + app.logf(" Window-Increment = %v\n", f.Increment) + case *http2.GoAwayFrame: + app.logf(" Last-Stream-ID = %d; Error-Code = %v (%d)\n", f.LastStreamID, f.ErrCode, f.ErrCode) + case *http2.DataFrame: + app.logf(" %q", f.Data()) + case *http2.HeadersFrame: + if f.HasPriority() { + app.logf(" PRIORITY = %v", f.Priority) + } + if app.hdec == nil { + // TODO: if the user uses h2i to send a SETTINGS frame advertising + // something larger, we'll need to respect SETTINGS_HEADER_TABLE_SIZE + // and stuff here instead of using the 4k default. But for now: + tableSize := uint32(4 << 10) + app.hdec = hpack.NewDecoder(tableSize, app.onNewHeaderField) + } + app.hdec.Write(f.HeaderBlockFragment()) + } + } +} + +// called from readLoop +func (app *h2i) onNewHeaderField(f hpack.HeaderField) { + if f.Sensitive { + app.logf(" %s = %q (SENSITIVE)", f.Name, f.Value) + } + app.logf(" %s = %q", f.Name, f.Value) +} + +func (app *h2i) encodeHeaders(req *http.Request) []byte { + app.hbuf.Reset() + + // TODO(bradfitz): figure out :authority-vs-Host stuff between http2 and Go + host := req.Host + if host == "" { + host = req.URL.Host + } + + path := req.URL.Path + if path == "" { + path = "/" + } + + app.writeHeader(":authority", host) // probably not right for all sites + app.writeHeader(":method", req.Method) + app.writeHeader(":path", path) + app.writeHeader(":scheme", "https") + + for k, vv := range req.Header { + lowKey := strings.ToLower(k) + if lowKey == "host" { + continue + } + for _, v := range vv { + app.writeHeader(lowKey, v) + } + } + return app.hbuf.Bytes() +} + +func (app *h2i) writeHeader(name, value string) { + app.henc.WriteField(hpack.HeaderField{Name: name, Value: value}) + app.logf(" %s = %s", name, value) +} diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/headermap.go b/Godeps/_workspace/src/golang.org/x/net/http2/headermap.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/headermap.go rename to Godeps/_workspace/src/golang.org/x/net/http2/headermap.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/hpack/encode.go b/Godeps/_workspace/src/golang.org/x/net/http2/hpack/encode.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/hpack/encode.go rename to Godeps/_workspace/src/golang.org/x/net/http2/hpack/encode.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/hpack/hpack.go b/Godeps/_workspace/src/golang.org/x/net/http2/hpack/hpack.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/hpack/hpack.go rename to Godeps/_workspace/src/golang.org/x/net/http2/hpack/hpack.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/hpack/huffman.go b/Godeps/_workspace/src/golang.org/x/net/http2/hpack/huffman.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/hpack/huffman.go rename to Godeps/_workspace/src/golang.org/x/net/http2/hpack/huffman.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/hpack/tables.go b/Godeps/_workspace/src/golang.org/x/net/http2/hpack/tables.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/hpack/tables.go rename to Godeps/_workspace/src/golang.org/x/net/http2/hpack/tables.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/http2.go b/Godeps/_workspace/src/golang.org/x/net/http2/http2.go similarity index 98% rename from Godeps/_workspace/src/github.com/bradfitz/http2/http2.go rename to Godeps/_workspace/src/golang.org/x/net/http2/http2.go index 136692a554..35f9b26e28 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/http2.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/http2.go @@ -13,7 +13,7 @@ // ConfigureServer. That ConfigureServer call will likely be automatic // or available via an empty import in the future. // -// This package currently targets draft-14. See http://http2.github.io/ +// See http://http2.github.io/ package http2 import ( diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/pipe.go b/Godeps/_workspace/src/golang.org/x/net/http2/pipe.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/pipe.go rename to Godeps/_workspace/src/golang.org/x/net/http2/pipe.go diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/server.go b/Godeps/_workspace/src/golang.org/x/net/http2/server.go similarity index 99% rename from Godeps/_workspace/src/github.com/bradfitz/http2/server.go rename to Godeps/_workspace/src/golang.org/x/net/http2/server.go index 6ac4c4aa2c..99cc673cc2 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/server.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/server.go @@ -55,7 +55,7 @@ import ( "sync" "time" - "github.com/bradfitz/http2/hpack" + "golang.org/x/net/http2/hpack" ) const ( @@ -631,6 +631,9 @@ func (sc *serverConn) serve() { case wm := <-sc.wantWriteFrameCh: sc.writeFrame(wm) case <-sc.wroteFrameCh: + if sc.writingFrame != true { + panic("internal error: expected to be already writing a frame") + } sc.writingFrame = false sc.scheduleFrameWrite() case fg, ok := <-sc.readFrameCh: @@ -752,6 +755,7 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) { if sc.writingFrame { panic("internal error: can only be writing one frame at a time") } + sc.writingFrame = true st := wm.stream if st != nil { @@ -768,7 +772,6 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) { } } - sc.writingFrame = true sc.needsFrameFlush = true if endsStream(wm.write) { if st == nil { diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/transport.go b/Godeps/_workspace/src/golang.org/x/net/http2/transport.go similarity index 99% rename from Godeps/_workspace/src/github.com/bradfitz/http2/transport.go rename to Godeps/_workspace/src/golang.org/x/net/http2/transport.go index ea62188db5..73f358eefe 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/transport.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/transport.go @@ -19,7 +19,7 @@ import ( "strings" "sync" - "github.com/bradfitz/http2/hpack" + "golang.org/x/net/http2/hpack" ) type Transport struct { @@ -186,7 +186,7 @@ func (t *Transport) newClientConn(host, port, key string) (*clientConn, error) { NextProtos: []string{NextProtoTLS}, InsecureSkipVerify: t.InsecureTLSDial, } - tconn, err := tls.Dial("tcp", host+":"+port, cfg) + tconn, err := tls.Dial("tcp", net.JoinHostPort(host, port), cfg) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/write.go b/Godeps/_workspace/src/golang.org/x/net/http2/write.go similarity index 99% rename from Godeps/_workspace/src/github.com/bradfitz/http2/write.go rename to Godeps/_workspace/src/golang.org/x/net/http2/write.go index 7b9bdd3a6a..02f0743de6 100644 --- a/Godeps/_workspace/src/github.com/bradfitz/http2/write.go +++ b/Godeps/_workspace/src/golang.org/x/net/http2/write.go @@ -13,7 +13,7 @@ import ( "net/http" "time" - "github.com/bradfitz/http2/hpack" + "golang.org/x/net/http2/hpack" ) // writeFramer is implemented by any type that is used to write frames. diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/writesched.go b/Godeps/_workspace/src/golang.org/x/net/http2/writesched.go similarity index 100% rename from Godeps/_workspace/src/github.com/bradfitz/http2/writesched.go rename to Godeps/_workspace/src/golang.org/x/net/http2/writesched.go diff --git a/Godeps/_workspace/src/google.golang.org/grpc/.travis.yml b/Godeps/_workspace/src/google.golang.org/grpc/.travis.yml index 2503560142..3f83776ec5 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/.travis.yml +++ b/Godeps/_workspace/src/google.golang.org/grpc/.travis.yml @@ -1,4 +1,14 @@ language: go +before_install: + - go get github.com/axw/gocov/gocov + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover + +install: + - mkdir -p "$GOPATH/src/google.golang.org" + - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/google.golang.org/grpc" + script: - make test testrace + - make coverage diff --git a/Godeps/_workspace/src/google.golang.org/grpc/grpc-auth-support.md b/Godeps/_workspace/src/google.golang.org/grpc/Documentation/grpc-auth-support.md similarity index 73% rename from Godeps/_workspace/src/google.golang.org/grpc/grpc-auth-support.md rename to Godeps/_workspace/src/google.golang.org/grpc/Documentation/grpc-auth-support.md index f80cbbdb27..5a075f6132 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/grpc-auth-support.md +++ b/Godeps/_workspace/src/google.golang.org/grpc/Documentation/grpc-auth-support.md @@ -1,6 +1,6 @@ # Authentication -As outlined here gRPC supports a number of different mechanisms for asserting identity between an client and server. We'll present some code-samples here demonstrating how to provide TLS support encryption and identity assertions as well as passing OAuth2 tokens to services that support it. +As outlined in the [gRPC authentication guide](http://www.grpc.io/docs/guides/auth.html) there are a number of different mechanisms for asserting identity between an client and server. We'll present some code-samples here demonstrating how to provide TLS support encryption and identity assertions as well as passing OAuth2 tokens to services that support it. # Enabling TLS on a gRPC client diff --git a/Godeps/_workspace/src/google.golang.org/grpc/Makefile b/Godeps/_workspace/src/google.golang.org/grpc/Makefile index 0dc225ff41..12e84e4e5b 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/Makefile +++ b/Godeps/_workspace/src/google.golang.org/grpc/Makefile @@ -45,3 +45,6 @@ testrace: testdeps clean: go clean google.golang.org/grpc/... + +coverage: testdeps + ./coverage.sh --coveralls diff --git a/Godeps/_workspace/src/google.golang.org/grpc/README.md b/Godeps/_workspace/src/google.golang.org/grpc/README.md index f16d406a8e..37b05f0953 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/README.md +++ b/Godeps/_workspace/src/google.golang.org/grpc/README.md @@ -2,12 +2,12 @@ [![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc) -The Go implementation of [gRPC](https://github.com/grpc/grpc) +The Go implementation of [gRPC](http://www.grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start](http://www.grpc.io/docs/) guide. Installation ------------ -To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the library is to run: +To install this package, you need to install Go 1.4 or above and setup your Go workspace on your computer. The simplest way to install the library is to run: ``` $ go get google.golang.org/grpc @@ -18,11 +18,15 @@ Prerequisites This requires Go 1.4 or above. +Constraints +----------- +The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](http://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants. + Documentation ------------- -You can find more detailed documentation and examples in the [examples directory](examples/). +See [API documentation](https://godoc.org/google.golang.org/grpc) for package and API descriptions and find examples in the [examples directory](examples/). Status ------ -Alpha - ready for early adopters. +Beta release diff --git a/Godeps/_workspace/src/google.golang.org/grpc/benchmark/client/main.go b/Godeps/_workspace/src/google.golang.org/grpc/benchmark/client/main.go index f9e2a83dbd..e7f0a8fb2c 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/benchmark/client/main.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/benchmark/client/main.go @@ -92,13 +92,6 @@ func closeLoopUnary() { func closeLoopStream() { s, conn, tc := buildConnection() - stream, err := tc.StreamingCall(context.Background()) - if err != nil { - grpclog.Fatalf("%v.StreamingCall(_) = _, %v", tc, err) - } - for i := 0; i < 100; i++ { - streamCaller(tc, stream) - } ch := make(chan int, *maxConcurrentRPCs*4) var ( mu sync.Mutex @@ -108,7 +101,15 @@ func closeLoopStream() { // Distribute RPCs over maxConcurrentCalls workers. for i := 0; i < *maxConcurrentRPCs; i++ { go func() { - for _ = range ch { + stream, err := tc.StreamingCall(context.Background()) + if err != nil { + grpclog.Fatalf("%v.StreamingCall(_) = _, %v", tc, err) + } + // Do some warm up. + for i := 0; i < 100; i++ { + streamCaller(tc, stream) + } + for range ch { start := time.Now() streamCaller(tc, stream) elapse := time.Since(start) diff --git a/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.pb.go index 619c450cad..c080709e13 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.pb.go @@ -27,18 +27,22 @@ It has these top-level messages: package grpc_testing import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - // 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. +const _ = proto.ProtoPackageIsVersion1 type PayloadType int32 @@ -65,6 +69,7 @@ var PayloadType_value = map[string]int32{ func (x PayloadType) String() string { return proto.EnumName(PayloadType_name, int32(x)) } +func (PayloadType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } type ClientType int32 @@ -85,6 +90,7 @@ var ClientType_value = map[string]int32{ func (x ClientType) String() string { return proto.EnumName(ClientType_name, int32(x)) } +func (ClientType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } type ServerType int32 @@ -105,6 +111,7 @@ var ServerType_value = map[string]int32{ func (x ServerType) String() string { return proto.EnumName(ServerType_name, int32(x)) } +func (ServerType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } type RpcType int32 @@ -125,15 +132,17 @@ var RpcType_value = map[string]int32{ func (x RpcType) String() string { return proto.EnumName(RpcType_name, int32(x)) } +func (RpcType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } type StatsRequest struct { // run number TestNum int32 `protobuf:"varint,1,opt,name=test_num" json:"test_num,omitempty"` } -func (m *StatsRequest) Reset() { *m = StatsRequest{} } -func (m *StatsRequest) String() string { return proto.CompactTextString(m) } -func (*StatsRequest) ProtoMessage() {} +func (m *StatsRequest) Reset() { *m = StatsRequest{} } +func (m *StatsRequest) String() string { return proto.CompactTextString(m) } +func (*StatsRequest) ProtoMessage() {} +func (*StatsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } type ServerStats struct { // wall clock time @@ -144,9 +153,10 @@ type ServerStats struct { TimeSystem float64 `protobuf:"fixed64,3,opt,name=time_system" json:"time_system,omitempty"` } -func (m *ServerStats) Reset() { *m = ServerStats{} } -func (m *ServerStats) String() string { return proto.CompactTextString(m) } -func (*ServerStats) ProtoMessage() {} +func (m *ServerStats) Reset() { *m = ServerStats{} } +func (m *ServerStats) String() string { return proto.CompactTextString(m) } +func (*ServerStats) ProtoMessage() {} +func (*ServerStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } type Payload struct { // The type of data in body. @@ -155,9 +165,10 @@ type Payload struct { Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` } -func (m *Payload) Reset() { *m = Payload{} } -func (m *Payload) String() string { return proto.CompactTextString(m) } -func (*Payload) ProtoMessage() {} +func (m *Payload) Reset() { *m = Payload{} } +func (m *Payload) String() string { return proto.CompactTextString(m) } +func (*Payload) ProtoMessage() {} +func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } type HistogramData struct { Bucket []uint32 `protobuf:"varint,1,rep,name=bucket" json:"bucket,omitempty"` @@ -168,9 +179,10 @@ type HistogramData struct { Count float64 `protobuf:"fixed64,6,opt,name=count" json:"count,omitempty"` } -func (m *HistogramData) Reset() { *m = HistogramData{} } -func (m *HistogramData) String() string { return proto.CompactTextString(m) } -func (*HistogramData) ProtoMessage() {} +func (m *HistogramData) Reset() { *m = HistogramData{} } +func (m *HistogramData) String() string { return proto.CompactTextString(m) } +func (*HistogramData) ProtoMessage() {} +func (*HistogramData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } type ClientConfig struct { ServerTargets []string `protobuf:"bytes,1,rep,name=server_targets" json:"server_targets,omitempty"` @@ -184,41 +196,141 @@ type ClientConfig struct { RpcType RpcType `protobuf:"varint,8,opt,name=rpc_type,enum=grpc.testing.RpcType" json:"rpc_type,omitempty"` } -func (m *ClientConfig) Reset() { *m = ClientConfig{} } -func (m *ClientConfig) String() string { return proto.CompactTextString(m) } -func (*ClientConfig) ProtoMessage() {} +func (m *ClientConfig) Reset() { *m = ClientConfig{} } +func (m *ClientConfig) String() string { return proto.CompactTextString(m) } +func (*ClientConfig) ProtoMessage() {} +func (*ClientConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } // Request current stats type Mark struct { } -func (m *Mark) Reset() { *m = Mark{} } -func (m *Mark) String() string { return proto.CompactTextString(m) } -func (*Mark) ProtoMessage() {} +func (m *Mark) Reset() { *m = Mark{} } +func (m *Mark) String() string { return proto.CompactTextString(m) } +func (*Mark) ProtoMessage() {} +func (*Mark) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } type ClientArgs struct { - Setup *ClientConfig `protobuf:"bytes,1,opt,name=setup" json:"setup,omitempty"` - Mark *Mark `protobuf:"bytes,2,opt,name=mark" json:"mark,omitempty"` + // Types that are valid to be assigned to Argtype: + // *ClientArgs_Setup + // *ClientArgs_Mark + Argtype isClientArgs_Argtype `protobuf_oneof:"argtype"` } -func (m *ClientArgs) Reset() { *m = ClientArgs{} } -func (m *ClientArgs) String() string { return proto.CompactTextString(m) } -func (*ClientArgs) ProtoMessage() {} +func (m *ClientArgs) Reset() { *m = ClientArgs{} } +func (m *ClientArgs) String() string { return proto.CompactTextString(m) } +func (*ClientArgs) ProtoMessage() {} +func (*ClientArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +type isClientArgs_Argtype interface { + isClientArgs_Argtype() +} + +type ClientArgs_Setup struct { + Setup *ClientConfig `protobuf:"bytes,1,opt,name=setup,oneof"` +} +type ClientArgs_Mark struct { + Mark *Mark `protobuf:"bytes,2,opt,name=mark,oneof"` +} + +func (*ClientArgs_Setup) isClientArgs_Argtype() {} +func (*ClientArgs_Mark) isClientArgs_Argtype() {} + +func (m *ClientArgs) GetArgtype() isClientArgs_Argtype { + if m != nil { + return m.Argtype + } + return nil +} func (m *ClientArgs) GetSetup() *ClientConfig { - if m != nil { - return m.Setup + if x, ok := m.GetArgtype().(*ClientArgs_Setup); ok { + return x.Setup } return nil } func (m *ClientArgs) GetMark() *Mark { - if m != nil { - return m.Mark + if x, ok := m.GetArgtype().(*ClientArgs_Mark); ok { + return x.Mark } return nil } +// XXX_OneofFuncs is for the internal use of the proto package. +func (*ClientArgs) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _ClientArgs_OneofMarshaler, _ClientArgs_OneofUnmarshaler, _ClientArgs_OneofSizer, []interface{}{ + (*ClientArgs_Setup)(nil), + (*ClientArgs_Mark)(nil), + } +} + +func _ClientArgs_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*ClientArgs) + // argtype + switch x := m.Argtype.(type) { + case *ClientArgs_Setup: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Setup); err != nil { + return err + } + case *ClientArgs_Mark: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Mark); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("ClientArgs.Argtype has unexpected type %T", x) + } + return nil +} + +func _ClientArgs_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*ClientArgs) + switch tag { + case 1: // argtype.setup + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ClientConfig) + err := b.DecodeMessage(msg) + m.Argtype = &ClientArgs_Setup{msg} + return true, err + case 2: // argtype.mark + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Mark) + err := b.DecodeMessage(msg) + m.Argtype = &ClientArgs_Mark{msg} + return true, err + default: + return false, nil + } +} + +func _ClientArgs_OneofSizer(msg proto.Message) (n int) { + m := msg.(*ClientArgs) + // argtype + switch x := m.Argtype.(type) { + case *ClientArgs_Setup: + s := proto.Size(x.Setup) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *ClientArgs_Mark: + s := proto.Size(x.Mark) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + type ClientStats struct { Latencies *HistogramData `protobuf:"bytes,1,opt,name=latencies" json:"latencies,omitempty"` TimeElapsed float64 `protobuf:"fixed64,3,opt,name=time_elapsed" json:"time_elapsed,omitempty"` @@ -226,9 +338,10 @@ type ClientStats struct { TimeSystem float64 `protobuf:"fixed64,5,opt,name=time_system" json:"time_system,omitempty"` } -func (m *ClientStats) Reset() { *m = ClientStats{} } -func (m *ClientStats) String() string { return proto.CompactTextString(m) } -func (*ClientStats) ProtoMessage() {} +func (m *ClientStats) Reset() { *m = ClientStats{} } +func (m *ClientStats) String() string { return proto.CompactTextString(m) } +func (*ClientStats) ProtoMessage() {} +func (*ClientStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (m *ClientStats) GetLatencies() *HistogramData { if m != nil { @@ -241,9 +354,10 @@ type ClientStatus struct { Stats *ClientStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"` } -func (m *ClientStatus) Reset() { *m = ClientStatus{} } -func (m *ClientStatus) String() string { return proto.CompactTextString(m) } -func (*ClientStatus) ProtoMessage() {} +func (m *ClientStatus) Reset() { *m = ClientStatus{} } +func (m *ClientStatus) String() string { return proto.CompactTextString(m) } +func (*ClientStatus) ProtoMessage() {} +func (*ClientStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (m *ClientStatus) GetStats() *ClientStats { if m != nil { @@ -258,41 +372,141 @@ type ServerConfig struct { EnableSsl bool `protobuf:"varint,3,opt,name=enable_ssl" json:"enable_ssl,omitempty"` } -func (m *ServerConfig) Reset() { *m = ServerConfig{} } -func (m *ServerConfig) String() string { return proto.CompactTextString(m) } -func (*ServerConfig) ProtoMessage() {} +func (m *ServerConfig) Reset() { *m = ServerConfig{} } +func (m *ServerConfig) String() string { return proto.CompactTextString(m) } +func (*ServerConfig) ProtoMessage() {} +func (*ServerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } type ServerArgs struct { - Setup *ServerConfig `protobuf:"bytes,1,opt,name=setup" json:"setup,omitempty"` - Mark *Mark `protobuf:"bytes,2,opt,name=mark" json:"mark,omitempty"` + // Types that are valid to be assigned to Argtype: + // *ServerArgs_Setup + // *ServerArgs_Mark + Argtype isServerArgs_Argtype `protobuf_oneof:"argtype"` } -func (m *ServerArgs) Reset() { *m = ServerArgs{} } -func (m *ServerArgs) String() string { return proto.CompactTextString(m) } -func (*ServerArgs) ProtoMessage() {} +func (m *ServerArgs) Reset() { *m = ServerArgs{} } +func (m *ServerArgs) String() string { return proto.CompactTextString(m) } +func (*ServerArgs) ProtoMessage() {} +func (*ServerArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +type isServerArgs_Argtype interface { + isServerArgs_Argtype() +} + +type ServerArgs_Setup struct { + Setup *ServerConfig `protobuf:"bytes,1,opt,name=setup,oneof"` +} +type ServerArgs_Mark struct { + Mark *Mark `protobuf:"bytes,2,opt,name=mark,oneof"` +} + +func (*ServerArgs_Setup) isServerArgs_Argtype() {} +func (*ServerArgs_Mark) isServerArgs_Argtype() {} + +func (m *ServerArgs) GetArgtype() isServerArgs_Argtype { + if m != nil { + return m.Argtype + } + return nil +} func (m *ServerArgs) GetSetup() *ServerConfig { - if m != nil { - return m.Setup + if x, ok := m.GetArgtype().(*ServerArgs_Setup); ok { + return x.Setup } return nil } func (m *ServerArgs) GetMark() *Mark { - if m != nil { - return m.Mark + if x, ok := m.GetArgtype().(*ServerArgs_Mark); ok { + return x.Mark } return nil } +// XXX_OneofFuncs is for the internal use of the proto package. +func (*ServerArgs) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _ServerArgs_OneofMarshaler, _ServerArgs_OneofUnmarshaler, _ServerArgs_OneofSizer, []interface{}{ + (*ServerArgs_Setup)(nil), + (*ServerArgs_Mark)(nil), + } +} + +func _ServerArgs_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*ServerArgs) + // argtype + switch x := m.Argtype.(type) { + case *ServerArgs_Setup: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Setup); err != nil { + return err + } + case *ServerArgs_Mark: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Mark); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("ServerArgs.Argtype has unexpected type %T", x) + } + return nil +} + +func _ServerArgs_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*ServerArgs) + switch tag { + case 1: // argtype.setup + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ServerConfig) + err := b.DecodeMessage(msg) + m.Argtype = &ServerArgs_Setup{msg} + return true, err + case 2: // argtype.mark + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Mark) + err := b.DecodeMessage(msg) + m.Argtype = &ServerArgs_Mark{msg} + return true, err + default: + return false, nil + } +} + +func _ServerArgs_OneofSizer(msg proto.Message) (n int) { + m := msg.(*ServerArgs) + // argtype + switch x := m.Argtype.(type) { + case *ServerArgs_Setup: + s := proto.Size(x.Setup) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *ServerArgs_Mark: + s := proto.Size(x.Mark) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + type ServerStatus struct { Stats *ServerStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"` Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` } -func (m *ServerStatus) Reset() { *m = ServerStatus{} } -func (m *ServerStatus) String() string { return proto.CompactTextString(m) } -func (*ServerStatus) ProtoMessage() {} +func (m *ServerStatus) Reset() { *m = ServerStatus{} } +func (m *ServerStatus) String() string { return proto.CompactTextString(m) } +func (*ServerStatus) ProtoMessage() {} +func (*ServerStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } func (m *ServerStatus) GetStats() *ServerStats { if m != nil { @@ -312,9 +526,10 @@ type SimpleRequest struct { Payload *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"` } -func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } -func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } -func (*SimpleRequest) ProtoMessage() {} +func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } +func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } +func (*SimpleRequest) ProtoMessage() {} +func (*SimpleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } func (m *SimpleRequest) GetPayload() *Payload { if m != nil { @@ -327,9 +542,10 @@ type SimpleResponse struct { Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"` } -func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } -func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } -func (*SimpleResponse) ProtoMessage() {} +func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } +func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } +func (*SimpleResponse) ProtoMessage() {} +func (*SimpleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } func (m *SimpleResponse) GetPayload() *Payload { if m != nil { @@ -339,12 +555,30 @@ func (m *SimpleResponse) GetPayload() *Payload { } func init() { + proto.RegisterType((*StatsRequest)(nil), "grpc.testing.StatsRequest") + proto.RegisterType((*ServerStats)(nil), "grpc.testing.ServerStats") + proto.RegisterType((*Payload)(nil), "grpc.testing.Payload") + proto.RegisterType((*HistogramData)(nil), "grpc.testing.HistogramData") + proto.RegisterType((*ClientConfig)(nil), "grpc.testing.ClientConfig") + proto.RegisterType((*Mark)(nil), "grpc.testing.Mark") + proto.RegisterType((*ClientArgs)(nil), "grpc.testing.ClientArgs") + proto.RegisterType((*ClientStats)(nil), "grpc.testing.ClientStats") + proto.RegisterType((*ClientStatus)(nil), "grpc.testing.ClientStatus") + proto.RegisterType((*ServerConfig)(nil), "grpc.testing.ServerConfig") + proto.RegisterType((*ServerArgs)(nil), "grpc.testing.ServerArgs") + proto.RegisterType((*ServerStatus)(nil), "grpc.testing.ServerStatus") + proto.RegisterType((*SimpleRequest)(nil), "grpc.testing.SimpleRequest") + proto.RegisterType((*SimpleResponse)(nil), "grpc.testing.SimpleResponse") proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value) proto.RegisterEnum("grpc.testing.ClientType", ClientType_name, ClientType_value) proto.RegisterEnum("grpc.testing.ServerType", ServerType_name, ServerType_value) proto.RegisterEnum("grpc.testing.RpcType", RpcType_name, RpcType_value) } +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + // Client API for TestService service type TestServiceClient interface { @@ -419,9 +653,9 @@ func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { s.RegisterService(&_TestService_serviceDesc, srv) } -func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(SimpleRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(TestServiceServer).UnaryCall(ctx, in) @@ -639,3 +873,69 @@ var _Worker_serviceDesc = grpc.ServiceDesc{ }, }, } + +var fileDescriptor0 = []byte{ + // 988 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x56, 0x5f, 0x6f, 0x1b, 0x45, + 0x10, 0xef, 0xc5, 0xff, 0xe2, 0x39, 0x27, 0x44, 0xab, 0x52, 0x39, 0x69, 0x11, 0x70, 0x05, 0x11, + 0x22, 0x91, 0x56, 0x46, 0x42, 0xea, 0x0b, 0x91, 0xeb, 0x1a, 0x52, 0x29, 0x71, 0xa2, 0xbd, 0x04, + 0xd4, 0xa7, 0xd3, 0xc6, 0xde, 0xb8, 0xa7, 0x9c, 0xef, 0xae, 0xb7, 0x7b, 0xa8, 0xe6, 0x09, 0xf1, + 0x19, 0xf8, 0x0a, 0x3c, 0x20, 0xbe, 0x24, 0xb3, 0xb3, 0x7b, 0x89, 0x9d, 0x9a, 0x36, 0x52, 0x9f, + 0x72, 0x3b, 0xf3, 0x9b, 0xdf, 0xce, 0xfe, 0xe6, 0x8f, 0x03, 0xa0, 0xa5, 0xd2, 0xfb, 0x79, 0x91, + 0xe9, 0x8c, 0x75, 0xa6, 0x45, 0x3e, 0xde, 0x37, 0x86, 0x38, 0x9d, 0x06, 0xdf, 0x42, 0x27, 0xd4, + 0x42, 0x2b, 0x2e, 0xdf, 0x94, 0x68, 0x62, 0xdb, 0xb0, 0x6e, 0x5c, 0x51, 0x5a, 0xce, 0xba, 0xde, + 0x17, 0xde, 0x6e, 0x83, 0xb7, 0xcc, 0x79, 0x54, 0xce, 0x82, 0x14, 0xfc, 0x50, 0x16, 0xbf, 0xc9, + 0x82, 0x02, 0xd8, 0x97, 0xd0, 0xd1, 0xf1, 0x4c, 0x46, 0x32, 0x11, 0xb9, 0x92, 0x13, 0x42, 0x7b, + 0xdc, 0x37, 0xb6, 0xa1, 0x35, 0xb1, 0x87, 0xd0, 0x26, 0x48, 0xa9, 0x64, 0xd1, 0x5d, 0x23, 0xff, + 0xba, 0x31, 0x9c, 0xe3, 0x99, 0x7d, 0x0e, 0x84, 0x8d, 0xd4, 0x5c, 0x69, 0x39, 0xeb, 0xd6, 0xc8, + 0x0d, 0xc6, 0x14, 0x92, 0x25, 0x38, 0x82, 0xd6, 0xa9, 0x98, 0x27, 0x99, 0x98, 0xb0, 0xef, 0xa0, + 0xae, 0xe7, 0xb9, 0xa4, 0x3b, 0x36, 0x7b, 0xdb, 0xfb, 0x8b, 0x4f, 0xd8, 0x77, 0xa0, 0x33, 0x04, + 0x70, 0x82, 0x31, 0x06, 0xf5, 0x8b, 0x6c, 0x32, 0xa7, 0x2b, 0x3b, 0x9c, 0xbe, 0x83, 0x7f, 0x3d, + 0xd8, 0x38, 0x8c, 0x95, 0xce, 0xa6, 0x85, 0x98, 0xbd, 0x10, 0x5a, 0xb0, 0x07, 0xd0, 0xbc, 0x28, + 0xc7, 0x57, 0x52, 0x23, 0x6d, 0x6d, 0x77, 0x83, 0xbb, 0x93, 0x91, 0x60, 0x16, 0xa7, 0x91, 0x92, + 0x32, 0x75, 0x49, 0xb7, 0xf0, 0x1c, 0xe2, 0x91, 0x5c, 0xe2, 0xad, 0x75, 0xd5, 0x9c, 0x4b, 0xbc, + 0x25, 0xd7, 0x16, 0xd4, 0x14, 0x6a, 0x56, 0x27, 0xab, 0xf9, 0x64, 0x5f, 0xc1, 0x26, 0xfe, 0x89, + 0xb2, 0xcb, 0x48, 0xbd, 0x29, 0x45, 0x21, 0x55, 0xb7, 0x41, 0xce, 0x0e, 0x5a, 0x4f, 0x2e, 0x43, + 0x6b, 0x63, 0xf7, 0xa1, 0x31, 0xce, 0xca, 0x54, 0x77, 0x9b, 0xe4, 0xb4, 0x87, 0xe0, 0x8f, 0x1a, + 0x74, 0x06, 0x49, 0x2c, 0x53, 0x3d, 0xc8, 0xd2, 0xcb, 0x78, 0xca, 0xbe, 0x46, 0x32, 0x12, 0x3f, + 0xd2, 0xa2, 0x98, 0x4a, 0xad, 0x28, 0xe9, 0x36, 0xdf, 0xb0, 0xd6, 0x33, 0x6b, 0x64, 0xcf, 0xc0, + 0x1f, 0x53, 0x58, 0x44, 0x7a, 0xad, 0x91, 0x5e, 0xdd, 0x65, 0xbd, 0x2c, 0x2f, 0xc9, 0x05, 0xe3, + 0xeb, 0x6f, 0xf6, 0x19, 0x80, 0x4c, 0xc5, 0x45, 0x82, 0x15, 0x51, 0x09, 0xbd, 0x6e, 0x9d, 0xb7, + 0xad, 0x25, 0x54, 0x09, 0x3b, 0x80, 0x47, 0x59, 0xa9, 0x95, 0x16, 0xe9, 0x04, 0x49, 0x22, 0x24, + 0x54, 0x51, 0x8e, 0xe9, 0x8c, 0x5f, 0x8b, 0x34, 0x95, 0x09, 0x3d, 0xbc, 0xc1, 0xb7, 0x17, 0x30, + 0x1c, 0x21, 0xa7, 0xb2, 0x18, 0x58, 0x00, 0xfb, 0x06, 0x3e, 0x71, 0xa9, 0xb9, 0x10, 0xab, 0x47, + 0x83, 0x6f, 0x5a, 0xb3, 0xc3, 0x51, 0x63, 0xe5, 0xb6, 0xa4, 0x91, 0x8a, 0x7f, 0x97, 0x24, 0x4c, + 0x83, 0xfb, 0xce, 0x16, 0xa2, 0x89, 0x3d, 0x85, 0xfb, 0x42, 0xcd, 0xd3, 0x71, 0x54, 0x3d, 0xf6, + 0x75, 0x21, 0xc5, 0x44, 0x75, 0x5b, 0x04, 0x65, 0xe4, 0x73, 0xcf, 0xb4, 0x1e, 0x8c, 0x58, 0xc7, + 0x94, 0xad, 0x2a, 0xeb, 0xa4, 0xca, 0xa7, 0xcb, 0xaa, 0x60, 0xb6, 0x24, 0x49, 0xab, 0xb0, 0x1f, + 0x41, 0x13, 0xea, 0xc7, 0xa2, 0xb8, 0x0a, 0x4a, 0x00, 0x4b, 0xd5, 0x2f, 0xa6, 0x8a, 0xf5, 0xa0, + 0xa1, 0xa4, 0x2e, 0x73, 0x6a, 0x45, 0xbf, 0xb7, 0xb3, 0x4a, 0x5a, 0x5b, 0xb2, 0xc3, 0x7b, 0xdc, + 0x42, 0xd9, 0x2e, 0xd4, 0x67, 0xc8, 0x44, 0xd5, 0xf0, 0x7b, 0x6c, 0x39, 0xc4, 0xdc, 0x81, 0x50, + 0x42, 0x3c, 0x6f, 0x43, 0x0b, 0x0b, 0x69, 0x92, 0x0c, 0xfe, 0xf1, 0xc0, 0xb7, 0x74, 0x76, 0xdc, + 0x9e, 0x41, 0x3b, 0x11, 0x5a, 0xa6, 0xe3, 0x58, 0x2a, 0x77, 0xf9, 0xc3, 0x65, 0xa6, 0xa5, 0xee, + 0xe6, 0x37, 0xe8, 0x77, 0x26, 0xb5, 0xf6, 0x81, 0x49, 0xad, 0xbf, 0x7f, 0x52, 0x1b, 0xef, 0x4c, + 0xea, 0x41, 0xd5, 0xac, 0x26, 0xd5, 0x52, 0xb1, 0x27, 0x28, 0x92, 0x49, 0xda, 0xe5, 0xb9, 0xbd, + 0x4a, 0x24, 0xbb, 0x75, 0x2c, 0x2e, 0xf8, 0xd3, 0xc3, 0x35, 0x44, 0x8d, 0xec, 0xda, 0x1d, 0xfb, + 0xb8, 0x6a, 0xf7, 0x9b, 0xb9, 0xbf, 0xd5, 0xc7, 0x36, 0xc0, 0xf6, 0xb1, 0xba, 0xfe, 0x66, 0x5d, + 0x68, 0x55, 0xed, 0xb0, 0xe6, 0x16, 0x98, 0xeb, 0x81, 0xf7, 0x77, 0xb8, 0x29, 0xb4, 0xa5, 0xbc, + 0x43, 0xa1, 0x17, 0x93, 0xfd, 0xc8, 0x42, 0x87, 0xd5, 0xd3, 0xef, 0x24, 0xde, 0xc2, 0x06, 0x76, + 0xe2, 0x99, 0x6d, 0x97, 0x67, 0x85, 0x76, 0xaf, 0xa5, 0xef, 0xe0, 0x6f, 0xdc, 0x76, 0x61, 0x3c, + 0xcb, 0x13, 0x59, 0x2d, 0xf6, 0x1f, 0x61, 0x03, 0xd7, 0x4d, 0x9e, 0xa5, 0x4a, 0x46, 0x77, 0xdb, + 0xa5, 0x9d, 0x0a, 0x4f, 0xb2, 0x3e, 0x5e, 0x88, 0xa7, 0xb1, 0xb4, 0xd7, 0x5d, 0x83, 0x68, 0x2e, + 0x9f, 0x40, 0xcb, 0x8d, 0x29, 0xc9, 0xeb, 0xdf, 0x1e, 0x32, 0x47, 0xcf, 0x2b, 0x54, 0xd0, 0x87, + 0xcd, 0x2a, 0x4d, 0x4b, 0xb3, 0x48, 0xe1, 0xdd, 0x85, 0x62, 0xef, 0x00, 0xfc, 0x85, 0xac, 0x71, + 0x0f, 0x77, 0x06, 0x27, 0xc7, 0xa7, 0x7c, 0x18, 0x86, 0xfd, 0xe7, 0x47, 0xc3, 0xad, 0x7b, 0xa8, + 0xcf, 0xe6, 0xf9, 0x68, 0xc9, 0xe6, 0x31, 0x80, 0x26, 0xef, 0x8f, 0x5e, 0x9c, 0x1c, 0x6f, 0xad, + 0xed, 0xfd, 0x50, 0x0d, 0x38, 0xc5, 0x3f, 0x00, 0x16, 0xbe, 0x1a, 0x0d, 0x0e, 0xf9, 0xc9, 0xe8, + 0xe4, 0x3c, 0x8c, 0x06, 0x47, 0x2f, 0x87, 0xa3, 0x33, 0x64, 0x41, 0xde, 0xbe, 0x71, 0x54, 0x16, + 0xcf, 0xc4, 0xdd, 0xb4, 0xe0, 0xed, 0xb8, 0x70, 0xc8, 0x7f, 0x19, 0xf2, 0xc5, 0x38, 0x67, 0xf1, + 0xf6, 0x1e, 0x43, 0xcb, 0x2d, 0x1b, 0xd6, 0x86, 0xc6, 0xf9, 0xa8, 0xcf, 0x5f, 0x21, 0x6e, 0x03, + 0xda, 0xe1, 0x19, 0x1f, 0xf6, 0x8f, 0x5f, 0x8e, 0x7e, 0xde, 0xf2, 0x7a, 0x58, 0x40, 0xff, 0x0c, + 0x9f, 0x6c, 0x6e, 0x88, 0xc7, 0x92, 0xfd, 0x04, 0xed, 0xf3, 0x54, 0x14, 0xf3, 0x81, 0x48, 0x12, + 0x76, 0x6b, 0xf0, 0x97, 0x0a, 0xbd, 0xf3, 0x68, 0xb5, 0xd3, 0xc9, 0x3b, 0xc2, 0xbe, 0xd0, 0x38, + 0x0e, 0xf8, 0x8b, 0x36, 0xfd, 0x48, 0xae, 0x5d, 0xef, 0xa9, 0xd7, 0xfb, 0xcb, 0x83, 0xe6, 0xaf, + 0x59, 0x71, 0x85, 0x6b, 0x62, 0x80, 0xef, 0x2a, 0x53, 0x93, 0x34, 0x5b, 0xf9, 0x8b, 0x63, 0xc6, + 0x6a, 0x67, 0xe7, 0xff, 0x76, 0x41, 0xa9, 0x0c, 0x1f, 0x1b, 0x42, 0x1b, 0x49, 0xac, 0xae, 0x6c, + 0xe5, 0xc0, 0xaf, 0xa2, 0x59, 0x1c, 0x20, 0x43, 0x73, 0xd1, 0xa4, 0xff, 0x75, 0xbe, 0xff, 0x2f, + 0x00, 0x00, 0xff, 0xff, 0xe3, 0xb1, 0x00, 0x4d, 0xf9, 0x08, 0x00, 0x00, +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.proto b/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.proto index e3a27f861b..b0b2f80b56 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.proto +++ b/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing/test.proto @@ -17,7 +17,7 @@ enum PayloadType { message StatsRequest { // run number - optional int32 test_num = 1; + int32 test_num = 1; } message ServerStats { diff --git a/Godeps/_workspace/src/google.golang.org/grpc/call.go b/Godeps/_workspace/src/google.golang.org/grpc/call.go index 63b7966c16..d4ae68bee1 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/call.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/call.go @@ -34,13 +34,13 @@ package grpc import ( + "bytes" "io" "time" "golang.org/x/net/context" "golang.org/x/net/trace" "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/transport" ) @@ -48,7 +48,7 @@ import ( // On error, it returns the error and indicates whether the call should be retried. // // TODO(zhaoq): Check whether the received message sequence is valid. -func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error { +func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error { // Try to acquire header metadata from the server if there is any. var err error c.headerMD, err = stream.Header() @@ -57,7 +57,7 @@ func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream } p := &parser{s: stream} for { - if err = recv(p, codec, reply); err != nil { + if err = recv(p, dopts.codec, stream, dopts.dc, reply); err != nil { if err == io.EOF { break } @@ -69,7 +69,7 @@ func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream } // sendRequest writes out various information of an RPC such as Context and Message. -func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) { +func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) { stream, err := t.NewStream(ctx, callHdr) if err != nil { return nil, err @@ -81,8 +81,11 @@ func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t } } }() - // TODO(zhaoq): Support compression. - outBuf, err := encode(codec, args, compressionNone) + var cbuf *bytes.Buffer + if compressor != nil { + cbuf = new(bytes.Buffer) + } + outBuf, err := encode(codec, args, compressor, cbuf) if err != nil { return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err) } @@ -94,14 +97,6 @@ func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t return stream, nil } -// callInfo contains all related configuration and information about an RPC. -type callInfo struct { - failFast bool - headerMD metadata.MD - trailerMD metadata.MD - traceInfo traceInfo // in trace.go -} - // Invoke is called by the generated code. It sends the RPC request on the // wire and returns after response is received. func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) { @@ -116,7 +111,6 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli o.after(&c) } }() - if EnableTracing { c.traceInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method) defer c.traceInfo.tr.Finish() @@ -133,16 +127,11 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli } }() } - callHdr := &transport.CallHdr{ - Host: cc.authority, - Method: method, - } topts := &transport.Options{ Last: true, Delay: false, } var ( - ts int // track the transport sequence number lastErr error // record the error that happened ) for { @@ -155,7 +144,14 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli if lastErr != nil && c.failFast { return toRPCErr(lastErr) } - t, ts, err = cc.wait(ctx, ts) + callHdr := &transport.CallHdr{ + Host: cc.authority, + Method: method, + } + if cc.dopts.cp != nil { + callHdr.SendCompress = cc.dopts.cp.Type() + } + t, err = cc.dopts.picker.Pick(ctx) if err != nil { if lastErr != nil { // This was a retry; return the error from the last attempt. @@ -166,7 +162,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli if c.traceInfo.tr != nil { c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true) } - stream, err = sendRequest(ctx, cc.dopts.codec, callHdr, t, args, topts) + stream, err = sendRequest(ctx, cc.dopts.codec, cc.dopts.cp, callHdr, t, args, topts) if err != nil { if _, ok := err.(transport.ConnectionError); ok { lastErr = err @@ -178,7 +174,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli return toRPCErr(err) } // Receive the response - lastErr = recvResponse(cc.dopts.codec, t, &c, stream, reply) + lastErr = recvResponse(cc.dopts, t, &c, stream, reply) if _, ok := lastErr.(transport.ConnectionError); ok { continue } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/clientconn.go b/Godeps/_workspace/src/google.golang.org/grpc/clientconn.go index aacba5b9c7..28e74da8b9 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/clientconn.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/clientconn.go @@ -42,6 +42,7 @@ import ( "time" "golang.org/x/net/context" + "golang.org/x/net/trace" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/transport" @@ -72,6 +73,9 @@ var ( // values passed to Dial. type dialOptions struct { codec Codec + cp Compressor + dc Decompressor + picker Picker block bool insecure bool copts transport.ConnectOptions @@ -87,6 +91,29 @@ func WithCodec(c Codec) DialOption { } } +// WithCompressor returns a DialOption which sets a CompressorGenerator for generating message +// compressor. +func WithCompressor(cp Compressor) DialOption { + return func(o *dialOptions) { + o.cp = cp + } +} + +// WithDecompressor returns a DialOption which sets a DecompressorGenerator for generating +// message decompressor. +func WithDecompressor(dc Decompressor) DialOption { + return func(o *dialOptions) { + o.dc = dc + } +} + +// WithPicker returns a DialOption which sets a picker for connection selection. +func WithPicker(p Picker) DialOption { + return func(o *dialOptions) { + o.picker = p + } +} + // WithBlock returns a DialOption which makes caller of Dial blocks until the underlying // connection is up. Without this, Dial returns immediately and connecting the server // happens in background. @@ -96,6 +123,8 @@ func WithBlock() DialOption { } } +// WithInsecure returns a DialOption which disables transport security for this ClientConn. +// Note that transport security is required unless WithInsecure is set. func WithInsecure() DialOption { return func(o *dialOptions) { o.insecure = true @@ -141,62 +170,29 @@ func WithUserAgent(s string) DialOption { // Dial creates a client connection the given target. func Dial(target string, opts ...DialOption) (*ClientConn, error) { - if target == "" { - return nil, ErrUnspecTarget - } cc := &ClientConn{ - target: target, - shutdownChan: make(chan struct{}), + target: target, } for _, opt := range opts { opt(&cc.dopts) } - if !cc.dopts.insecure { - var ok bool - for _, c := range cc.dopts.copts.AuthOptions { - if _, ok := c.(credentials.TransportAuthenticator); !ok { - continue - } - ok = true - } - if !ok { - return nil, ErrNoTransportSecurity - } - } else { - for _, c := range cc.dopts.copts.AuthOptions { - if c.RequireTransportSecurity() { - return nil, ErrCredentialsMisuse - } + if cc.dopts.codec == nil { + // Set the default codec. + cc.dopts.codec = protoCodec{} + } + if cc.dopts.picker == nil { + cc.dopts.picker = &unicastPicker{ + target: target, } } + if err := cc.dopts.picker.Init(cc); err != nil { + return nil, err + } colonPos := strings.LastIndex(target, ":") if colonPos == -1 { colonPos = len(target) } cc.authority = target[:colonPos] - if cc.dopts.codec == nil { - // Set the default codec. - cc.dopts.codec = protoCodec{} - } - cc.stateCV = sync.NewCond(&cc.mu) - if cc.dopts.block { - if err := cc.resetTransport(false); err != nil { - cc.Close() - return nil, err - } - // Start to monitor the error status of transport. - go cc.transportMonitor() - } else { - // Start a goroutine connecting to the server asynchronously. - go func() { - if err := cc.resetTransport(false); err != nil { - grpclog.Printf("Failed to dial %s: %v; please retry.", target, err) - cc.Close() - return - } - go cc.transportMonitor() - }() - } return cc, nil } @@ -212,7 +208,7 @@ const ( Ready // TransientFailure indicates the ClientConn has seen a failure but expects to recover. TransientFailure - // Shutdown indicates the ClientConn has stated shutting down. + // Shutdown indicates the ClientConn has started shutting down. Shutdown ) @@ -235,50 +231,137 @@ func (s ConnectivityState) String() string { // ClientConn represents a client connection to an RPC service. type ClientConn struct { + target string + authority string + dopts dialOptions +} + +// State returns the connectivity state of cc. +// This is EXPERIMENTAL API. +func (cc *ClientConn) State() (ConnectivityState, error) { + return cc.dopts.picker.State() +} + +// WaitForStateChange blocks until the state changes to something other than the sourceState. +// It returns the new state or error. +// This is EXPERIMENTAL API. +func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { + return cc.dopts.picker.WaitForStateChange(ctx, sourceState) +} + +// Close starts to tear down the ClientConn. +func (cc *ClientConn) Close() error { + return cc.dopts.picker.Close() +} + +// Conn is a client connection to a single destination. +type Conn struct { target string - authority string dopts dialOptions + resetChan chan int shutdownChan chan struct{} + events trace.EventLog mu sync.Mutex state ConnectivityState stateCV *sync.Cond // ready is closed and becomes nil when a new transport is up or failed // due to timeout. - ready chan struct{} - // Every time a new transport is created, this is incremented by 1. Used - // to avoid trying to recreate a transport while the new one is already - // under construction. - transportSeq int - transport transport.ClientTransport + ready chan struct{} + transport transport.ClientTransport } -// State returns the connectivity state of the ClientConn -func (cc *ClientConn) State() ConnectivityState { +// NewConn creates a Conn. +func NewConn(cc *ClientConn) (*Conn, error) { + if cc.target == "" { + return nil, ErrUnspecTarget + } + c := &Conn{ + target: cc.target, + dopts: cc.dopts, + resetChan: make(chan int, 1), + shutdownChan: make(chan struct{}), + } + if EnableTracing { + c.events = trace.NewEventLog("grpc.ClientConn", c.target) + } + if !c.dopts.insecure { + var ok bool + for _, cd := range c.dopts.copts.AuthOptions { + if _, ok := cd.(credentials.TransportAuthenticator); !ok { + continue + } + ok = true + } + if !ok { + return nil, ErrNoTransportSecurity + } + } else { + for _, cd := range c.dopts.copts.AuthOptions { + if cd.RequireTransportSecurity() { + return nil, ErrCredentialsMisuse + } + } + } + c.stateCV = sync.NewCond(&c.mu) + if c.dopts.block { + if err := c.resetTransport(false); err != nil { + c.Close() + return nil, err + } + // Start to monitor the error status of transport. + go c.transportMonitor() + } else { + // Start a goroutine connecting to the server asynchronously. + go func() { + if err := c.resetTransport(false); err != nil { + grpclog.Printf("Failed to dial %s: %v; please retry.", c.target, err) + c.Close() + return + } + c.transportMonitor() + }() + } + return c, nil +} + +// printf records an event in cc's event log, unless cc has been closed. +// REQUIRES cc.mu is held. +func (cc *Conn) printf(format string, a ...interface{}) { + if cc.events != nil { + cc.events.Printf(format, a...) + } +} + +// errorf records an error in cc's event log, unless cc has been closed. +// REQUIRES cc.mu is held. +func (cc *Conn) errorf(format string, a ...interface{}) { + if cc.events != nil { + cc.events.Errorf(format, a...) + } +} + +// State returns the connectivity state of the Conn +func (cc *Conn) State() ConnectivityState { cc.mu.Lock() defer cc.mu.Unlock() return cc.state } -// WaitForStateChange blocks until the state changes to something other than the sourceState -// or timeout fires. It returns false if timeout fires and true otherwise. -func (cc *ClientConn) WaitForStateChange(timeout time.Duration, sourceState ConnectivityState) bool { - start := time.Now() +// WaitForStateChange blocks until the state changes to something other than the sourceState. +func (cc *Conn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { cc.mu.Lock() defer cc.mu.Unlock() if sourceState != cc.state { - return true - } - expired := timeout <= time.Since(start) - if expired { - return false + return cc.state, nil } done := make(chan struct{}) + var err error go func() { select { - case <-time.After(timeout - time.Since(start)): + case <-ctx.Done(): cc.mu.Lock() - expired = true + err = ctx.Err() cc.stateCV.Broadcast() cc.mu.Unlock() case <-done: @@ -287,31 +370,38 @@ func (cc *ClientConn) WaitForStateChange(timeout time.Duration, sourceState Conn defer close(done) for sourceState == cc.state { cc.stateCV.Wait() - if expired { - return false + if err != nil { + return cc.state, err } } - return true + return cc.state, nil } -func (cc *ClientConn) resetTransport(closeTransport bool) error { +// NotifyReset tries to signal the underlying transport needs to be reset due to +// for example a name resolution change in flight. +func (cc *Conn) NotifyReset() { + select { + case cc.resetChan <- 0: + default: + } +} + +func (cc *Conn) resetTransport(closeTransport bool) error { var retries int start := time.Now() for { cc.mu.Lock() - cc.state = Connecting - cc.stateCV.Broadcast() - t := cc.transport - ts := cc.transportSeq - // Avoid wait() picking up a dying transport unnecessarily. - cc.transportSeq = 0 + cc.printf("connecting") if cc.state == Shutdown { + // cc.Close() has been invoked. cc.mu.Unlock() return ErrClientConnClosing } + cc.state = Connecting + cc.stateCV.Broadcast() cc.mu.Unlock() if closeTransport { - t.Close() + cc.transport.Close() } // Adjust timeout for the current try. copts := cc.dopts.copts @@ -335,11 +425,25 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error { copts.Timeout = timeout } connectTime := time.Now() - newTransport, err := transport.NewClientTransport(cc.target, &copts) + addr, err := cc.dopts.picker.PickAddr() + var newTransport transport.ClientTransport + if err == nil { + newTransport, err = transport.NewClientTransport(addr, &copts) + } if err != nil { cc.mu.Lock() + if cc.state == Shutdown { + // cc.Close() has been invoked. + cc.mu.Unlock() + return ErrClientConnClosing + } + cc.errorf("transient failure: %v", err) cc.state = TransientFailure cc.stateCV.Broadcast() + if cc.ready != nil { + close(cc.ready) + cc.ready = nil + } cc.mu.Unlock() sleepTime -= time.Since(connectTime) if sleepTime < 0 { @@ -347,16 +451,20 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error { } // Fail early before falling into sleep. if cc.dopts.copts.Timeout > 0 && cc.dopts.copts.Timeout < sleepTime+time.Since(start) { + cc.mu.Lock() + cc.errorf("connection timeout") + cc.mu.Unlock() cc.Close() return ErrClientConnTimeout } closeTransport = false time.Sleep(sleepTime) retries++ - grpclog.Printf("grpc: ClientConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target) + grpclog.Printf("grpc: Conn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target) continue } cc.mu.Lock() + cc.printf("ready") if cc.state == Shutdown { // cc.Close() has been invoked. cc.mu.Unlock() @@ -366,7 +474,6 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error { cc.state = Ready cc.stateCV.Broadcast() cc.transport = newTransport - cc.transportSeq = ts + 1 if cc.ready != nil { close(cc.ready) cc.ready = nil @@ -376,44 +483,64 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error { } } +func (cc *Conn) reconnect() bool { + cc.mu.Lock() + if cc.state == Shutdown { + // cc.Close() has been invoked. + cc.mu.Unlock() + return false + } + cc.state = TransientFailure + cc.stateCV.Broadcast() + cc.mu.Unlock() + if err := cc.resetTransport(true); err != nil { + // The ClientConn is closing. + cc.mu.Lock() + cc.printf("transport exiting: %v", err) + cc.mu.Unlock() + grpclog.Printf("grpc: Conn.transportMonitor exits due to: %v", err) + return false + } + return true +} + // Run in a goroutine to track the error in transport and create the // new transport if an error happens. It returns when the channel is closing. -func (cc *ClientConn) transportMonitor() { +func (cc *Conn) transportMonitor() { for { select { // shutdownChan is needed to detect the teardown when // the ClientConn is idle (i.e., no RPC in flight). case <-cc.shutdownChan: return - case <-cc.transport.Error(): - cc.mu.Lock() - cc.state = TransientFailure - cc.stateCV.Broadcast() - cc.mu.Unlock() - if err := cc.resetTransport(true); err != nil { - // The ClientConn is closing. - grpclog.Printf("grpc: ClientConn.transportMonitor exits due to: %v", err) + case <-cc.resetChan: + if !cc.reconnect() { return } - continue + case <-cc.transport.Error(): + if !cc.reconnect() { + return + } + // Tries to drain reset signal if there is any since it is out-dated. + select { + case <-cc.resetChan: + default: + } } } } -// When wait returns, either the new transport is up or ClientConn is -// closing. Used to avoid working on a dying transport. It updates and -// returns the transport and its version when there is no error. -func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTransport, int, error) { +// Wait blocks until i) the new transport is up or ii) ctx is done or iii) cc is closed. +func (cc *Conn) Wait(ctx context.Context) (transport.ClientTransport, error) { for { cc.mu.Lock() switch { case cc.state == Shutdown: cc.mu.Unlock() - return nil, 0, ErrClientConnClosing - case ts < cc.transportSeq: - // Worked on a dying transport. Try the new one immediately. - defer cc.mu.Unlock() - return cc.transport, cc.transportSeq, nil + return nil, ErrClientConnClosing + case cc.state == Ready: + cc.mu.Unlock() + return cc.transport, nil default: ready := cc.ready if ready == nil { @@ -423,7 +550,7 @@ func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTranspo cc.mu.Unlock() select { case <-ctx.Done(): - return nil, 0, transport.ContextErr(ctx.Err()) + return nil, transport.ContextErr(ctx.Err()) // Wait until the new transport is ready or failed. case <-ready: } @@ -431,12 +558,12 @@ func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTranspo } } -// Close starts to tear down the ClientConn. Returns ErrClientConnClosing if +// Close starts to tear down the Conn. Returns ErrClientConnClosing if // it has been closed (mostly due to dial time-out). // TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in // some edge cases (e.g., the caller opens and closes many ClientConn's in a // tight loop. -func (cc *ClientConn) Close() error { +func (cc *Conn) Close() error { cc.mu.Lock() defer cc.mu.Unlock() if cc.state == Shutdown { @@ -444,6 +571,10 @@ func (cc *ClientConn) Close() error { } cc.state = Shutdown cc.stateCV.Broadcast() + if cc.events != nil { + cc.events.Finish() + cc.events = nil + } if cc.ready != nil { close(cc.ready) cc.ready = nil diff --git a/Godeps/_workspace/src/google.golang.org/grpc/coverage.sh b/Godeps/_workspace/src/google.golang.org/grpc/coverage.sh new file mode 100644 index 0000000000..120235374a --- /dev/null +++ b/Godeps/_workspace/src/google.golang.org/grpc/coverage.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +set -e + +workdir=.cover +profile="$workdir/cover.out" +mode=set +end2endtest="google.golang.org/grpc/test" + +generate_cover_data() { + rm -rf "$workdir" + mkdir "$workdir" + + for pkg in "$@"; do + if [ $pkg == "google.golang.org/grpc" -o $pkg == "google.golang.org/grpc/transport" -o $pkg == "google.golang.org/grpc/metadata" -o $pkg == "google.golang.org/grpc/credentials" ] + then + f="$workdir/$(echo $pkg | tr / -)" + go test -covermode="$mode" -coverprofile="$f.cover" "$pkg" + go test -covermode="$mode" -coverpkg "$pkg" -coverprofile="$f.e2e.cover" "$end2endtest" + fi + done + + echo "mode: $mode" >"$profile" + grep -h -v "^mode:" "$workdir"/*.cover >>"$profile" +} + +show_cover_report() { + go tool cover -${1}="$profile" +} + +push_to_coveralls() { + goveralls -coverprofile="$profile" +} + +generate_cover_data $(go list ./...) +show_cover_report func +case "$1" in +"") + ;; +--html) + show_cover_report html ;; +--coveralls) + push_to_coveralls ;; +*) + echo >&2 "error: invalid option: $1" ;; +esac +rm -rf "$workdir" diff --git a/Godeps/_workspace/src/google.golang.org/grpc/credentials/credentials.go b/Godeps/_workspace/src/google.golang.org/grpc/credentials/credentials.go index 3cec7e4916..0b0b89b6aa 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/credentials/credentials.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/credentials/credentials.go @@ -87,19 +87,6 @@ type AuthInfo interface { AuthType() string } -type authInfoKey struct{} - -// NewContext creates a new context with authInfo attached. -func NewContext(ctx context.Context, authInfo AuthInfo) context.Context { - return context.WithValue(ctx, authInfoKey{}, authInfo) -} - -// FromContext returns the authInfo in ctx if it exists. -func FromContext(ctx context.Context) (authInfo AuthInfo, ok bool) { - authInfo, ok = ctx.Value(authInfoKey{}).(AuthInfo) - return -} - // TransportAuthenticator defines the common interface for all the live gRPC wire // protocols and supported transport security protocols (e.g., TLS, SSL). type TransportAuthenticator interface { @@ -119,7 +106,7 @@ type TransportAuthenticator interface { // TLSInfo contains the auth information for a TLS authenticated connection. // It implements the AuthInfo interface. type TLSInfo struct { - state tls.ConnectionState + State tls.ConnectionState } func (t TLSInfo) AuthType() string { diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/README.md b/Godeps/_workspace/src/google.golang.org/grpc/examples/README.md index e5c03c38e0..b65f8c5e63 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/README.md +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/README.md @@ -3,14 +3,15 @@ gRPC in 3 minutes (Go) BACKGROUND ------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto](examples/helloworld/proto/helloworld.proto). +For this sample, we've already generated the server and client stubs from [helloworld.proto](helloworld/helloworld/helloworld.proto). PREREQUISITES ------------- - This requires Go 1.4 - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) -```sh + +``` $ go help gopath $ # ensure the PATH contains $GOPATH/bin $ export PATH=$PATH:$GOPATH/bin @@ -19,35 +20,38 @@ $ export PATH=$PATH:$GOPATH/bin INSTALL ------- -```sh -$ go get -u github.com/grpc/grpc-go/examples/greeter_client -$ go get -u github.com/grpc/grpc-go/examples/greeter_server +``` +$ go get -u google.golang.org/grpc/examples/helloworld/greeter_client +$ go get -u google.golang.org/grpc/examples/helloworld/greeter_server ``` TRY IT! ------- - Run the server -```sh + +``` $ greeter_server & ``` - Run the client -```sh + +``` $ greeter_client ``` OPTIONAL - Rebuilding the generated code ---------------------------------------- -1 First [install protoc](https://github.com/google/protobuf/blob/master/INSTALL.txt) +1 First [install protoc](https://github.com/google/protobuf/blob/master/README.md) - For now, this needs to be installed from source - This is will change once proto3 is officially released 2 Install the protoc Go plugin. -```sh + +``` $ go get -a github.com/golang/protobuf/protoc-gen-go $ $ # from this dir; invoke protoc -$ protoc -I ./helloworld/proto/ ./helloworld/proto/helloworld.proto --go_out=plugins=grpc:helloworld +$ protoc -I ./helloworld/helloworld/ ./helloworld/helloworld/helloworld.proto --go_out=plugins=grpc:helloworld ``` diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/gotutorial.md b/Godeps/_workspace/src/google.golang.org/grpc/examples/gotutorial.md index 8df15a4a4e..39833fdf3d 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/gotutorial.md +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/gotutorial.md @@ -33,7 +33,7 @@ You also should have the relevant tools installed to generate the server and cli ## Defining the service -Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc/tree/master/examples)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/route_guide/proto/route_guide.proto`](examples/route_guide/proto/route_guide.proto). +Our first step (as you'll know from the [quick start](http://www.grpc.io/docs/#quick-start)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/route_guide/proto/route_guide.proto`](examples/route_guide/proto/route_guide.proto). To define a service, you specify a named `service` in your .proto file: @@ -227,7 +227,7 @@ func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) e } ``` -In the method body we use the `RouteGuide_RecordRouteServer`s `Recv()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the the error returned from `Read()` after each call. If this is `nil`, the stream is still good and it can continue reading; if it's `io.EOF` the message stream has ended and the server can return its `RouteSummary`. If it has any other value, we return the error "as is" so that it'll be translated to an RPC status by the gRPC layer. +In the method body we use the `RouteGuide_RecordRouteServer`s `Recv()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the the error returned from `Recv()` after each call. If this is `nil`, the stream is still good and it can continue reading; if it's `io.EOF` the message stream has ended and the server can return its `RouteSummary`. If it has any other value, we return the error "as is" so that it'll be translated to an RPC status by the gRPC layer. #### Bidirectional streaming RPC Finally, let's look at our bidirectional streaming RPC `RouteChat()`. diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/greeter_server/main.go b/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/greeter_server/main.go index ba985df4c2..66010a5120 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/greeter_server/main.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/greeter_server/main.go @@ -46,7 +46,7 @@ const ( port = ":50051" ) -// server is used to implement hellowrld.GreeterServer. +// server is used to implement helloworld.GreeterServer. type server struct{} // SayHello implements helloworld.GreeterServer diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.pb.go index 1ff931a384..97df856880 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.pb.go @@ -15,40 +15,52 @@ It has these top-level messages: package helloworld import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - // 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. +const _ = proto.ProtoPackageIsVersion1 // The request message containing the user's name. type HelloRequest struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` } -func (m *HelloRequest) Reset() { *m = HelloRequest{} } -func (m *HelloRequest) String() string { return proto.CompactTextString(m) } -func (*HelloRequest) ProtoMessage() {} +func (m *HelloRequest) Reset() { *m = HelloRequest{} } +func (m *HelloRequest) String() string { return proto.CompactTextString(m) } +func (*HelloRequest) ProtoMessage() {} +func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } // The response message containing the greetings type HelloReply struct { Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` } -func (m *HelloReply) Reset() { *m = HelloReply{} } -func (m *HelloReply) String() string { return proto.CompactTextString(m) } -func (*HelloReply) ProtoMessage() {} +func (m *HelloReply) Reset() { *m = HelloReply{} } +func (m *HelloReply) String() string { return proto.CompactTextString(m) } +func (*HelloReply) ProtoMessage() {} +func (*HelloReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func init() { + proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest") + proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply") } +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + // Client API for Greeter service type GreeterClient interface { @@ -84,9 +96,9 @@ func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { s.RegisterService(&_Greeter_serviceDesc, srv) } -func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(HelloRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(GreeterServer).SayHello(ctx, in) @@ -107,3 +119,19 @@ var _Greeter_serviceDesc = grpc.ServiceDesc{ }, Streams: []grpc.StreamDesc{}, } + +var fileDescriptor0 = []byte{ + // 181 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9, + 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88, + 0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, + 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92, + 0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71, + 0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a, + 0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64, + 0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x00, 0xad, 0x50, 0x62, 0x70, 0x32, 0xe3, 0x92, 0xce, 0xcc, 0xd7, + 0x4b, 0x2f, 0x2a, 0x48, 0xd6, 0x4b, 0xad, 0x48, 0xcc, 0x2d, 0xc8, 0x49, 0x2d, 0x46, 0x52, 0xeb, + 0xc4, 0x0f, 0x56, 0x1c, 0x0e, 0x62, 0x07, 0x80, 0xbc, 0x14, 0xc0, 0xb8, 0x88, 0x89, 0xd9, 0xc3, + 0x27, 0x3c, 0x89, 0x0d, 0xec, 0x43, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x0a, 0xdc, + 0xe8, 0xf5, 0x00, 0x00, 0x00, +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.proto b/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.proto index 7d58870a70..0bee1fcfcf 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.proto +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.proto @@ -29,7 +29,9 @@ syntax = "proto3"; -option java_package = "io.grpc.examples"; +option java_multiple_files = true; +option java_package = "io.grpc.examples.helloworld"; +option java_outer_classname = "HelloWorldProto"; option objc_class_prefix = "HLW"; package helloworld; diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/README.md b/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/README.md index 7571621dae..a7c0c2b0e5 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/README.md +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/README.md @@ -2,7 +2,7 @@ The route guide server and client demonstrate how to use grpc go libraries to perform unary, client streaming, server streaming and full duplex RPCs. -Please refer to [Getting Started Guide for Go] (examples/gotutorial.md) for more information. +Please refer to [gRPC Basics: Go] (http://www.grpc.io/docs/tutorials/basic/go.html) for more information. See the definition of the route guide service in proto/route_guide.proto. diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.pb.go index fcf5c7484f..4f5f5c13d0 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.pb.go @@ -3,7 +3,7 @@ // DO NOT EDIT! /* -Package proto is a generated protocol buffer package. +Package routeguide is a generated protocol buffer package. It is generated from these files: route_guide.proto @@ -17,7 +17,9 @@ It has these top-level messages: */ package routeguide -import proto1 "github.com/golang/protobuf/proto" +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" import ( context "golang.org/x/net/context" @@ -25,11 +27,13 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto1.Marshal +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 // Points are represented as latitude-longitude pairs in the E7 representation // (degrees multiplied by 10**7 and rounded to the nearest integer). @@ -40,9 +44,10 @@ type Point struct { Longitude int32 `protobuf:"varint,2,opt,name=longitude" json:"longitude,omitempty"` } -func (m *Point) Reset() { *m = Point{} } -func (m *Point) String() string { return proto1.CompactTextString(m) } -func (*Point) ProtoMessage() {} +func (m *Point) Reset() { *m = Point{} } +func (m *Point) String() string { return proto.CompactTextString(m) } +func (*Point) ProtoMessage() {} +func (*Point) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } // A latitude-longitude rectangle, represented as two diagonally opposite // points "lo" and "hi". @@ -53,9 +58,10 @@ type Rectangle struct { Hi *Point `protobuf:"bytes,2,opt,name=hi" json:"hi,omitempty"` } -func (m *Rectangle) Reset() { *m = Rectangle{} } -func (m *Rectangle) String() string { return proto1.CompactTextString(m) } -func (*Rectangle) ProtoMessage() {} +func (m *Rectangle) Reset() { *m = Rectangle{} } +func (m *Rectangle) String() string { return proto.CompactTextString(m) } +func (*Rectangle) ProtoMessage() {} +func (*Rectangle) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *Rectangle) GetLo() *Point { if m != nil { @@ -81,9 +87,10 @@ type Feature struct { Location *Point `protobuf:"bytes,2,opt,name=location" json:"location,omitempty"` } -func (m *Feature) Reset() { *m = Feature{} } -func (m *Feature) String() string { return proto1.CompactTextString(m) } -func (*Feature) ProtoMessage() {} +func (m *Feature) Reset() { *m = Feature{} } +func (m *Feature) String() string { return proto.CompactTextString(m) } +func (*Feature) ProtoMessage() {} +func (*Feature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (m *Feature) GetLocation() *Point { if m != nil { @@ -100,9 +107,10 @@ type RouteNote struct { Message string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` } -func (m *RouteNote) Reset() { *m = RouteNote{} } -func (m *RouteNote) String() string { return proto1.CompactTextString(m) } -func (*RouteNote) ProtoMessage() {} +func (m *RouteNote) Reset() { *m = RouteNote{} } +func (m *RouteNote) String() string { return proto.CompactTextString(m) } +func (*RouteNote) ProtoMessage() {} +func (*RouteNote) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (m *RouteNote) GetLocation() *Point { if m != nil { @@ -127,13 +135,23 @@ type RouteSummary struct { ElapsedTime int32 `protobuf:"varint,4,opt,name=elapsed_time" json:"elapsed_time,omitempty"` } -func (m *RouteSummary) Reset() { *m = RouteSummary{} } -func (m *RouteSummary) String() string { return proto1.CompactTextString(m) } -func (*RouteSummary) ProtoMessage() {} +func (m *RouteSummary) Reset() { *m = RouteSummary{} } +func (m *RouteSummary) String() string { return proto.CompactTextString(m) } +func (*RouteSummary) ProtoMessage() {} +func (*RouteSummary) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func init() { + proto.RegisterType((*Point)(nil), "routeguide.Point") + proto.RegisterType((*Rectangle)(nil), "routeguide.Rectangle") + proto.RegisterType((*Feature)(nil), "routeguide.Feature") + proto.RegisterType((*RouteNote)(nil), "routeguide.RouteNote") + proto.RegisterType((*RouteSummary)(nil), "routeguide.RouteSummary") } +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + // Client API for RouteGuide service type RouteGuideClient interface { @@ -141,8 +159,8 @@ type RouteGuideClient interface { // // Obtains the feature at a given position. // - // If no feature is found for the given point, a feature with an empty name - // should be returned. + // A feature with an empty name is returned if there's no feature at the given + // position. GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error) // A server-to-client streaming RPC. // @@ -173,7 +191,7 @@ func NewRouteGuideClient(cc *grpc.ClientConn) RouteGuideClient { func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error) { out := new(Feature) - err := grpc.Invoke(ctx, "/proto.RouteGuide/GetFeature", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/routeguide.RouteGuide/GetFeature", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -181,7 +199,7 @@ func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...gr } func (c *routeGuideClient) ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error) { - stream, err := grpc.NewClientStream(ctx, &_RouteGuide_serviceDesc.Streams[0], c.cc, "/proto.RouteGuide/ListFeatures", opts...) + stream, err := grpc.NewClientStream(ctx, &_RouteGuide_serviceDesc.Streams[0], c.cc, "/routeguide.RouteGuide/ListFeatures", opts...) if err != nil { return nil, err } @@ -213,7 +231,7 @@ func (x *routeGuideListFeaturesClient) Recv() (*Feature, error) { } func (c *routeGuideClient) RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error) { - stream, err := grpc.NewClientStream(ctx, &_RouteGuide_serviceDesc.Streams[1], c.cc, "/proto.RouteGuide/RecordRoute", opts...) + stream, err := grpc.NewClientStream(ctx, &_RouteGuide_serviceDesc.Streams[1], c.cc, "/routeguide.RouteGuide/RecordRoute", opts...) if err != nil { return nil, err } @@ -247,7 +265,7 @@ func (x *routeGuideRecordRouteClient) CloseAndRecv() (*RouteSummary, error) { } func (c *routeGuideClient) RouteChat(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RouteChatClient, error) { - stream, err := grpc.NewClientStream(ctx, &_RouteGuide_serviceDesc.Streams[2], c.cc, "/proto.RouteGuide/RouteChat", opts...) + stream, err := grpc.NewClientStream(ctx, &_RouteGuide_serviceDesc.Streams[2], c.cc, "/routeguide.RouteGuide/RouteChat", opts...) if err != nil { return nil, err } @@ -284,8 +302,8 @@ type RouteGuideServer interface { // // Obtains the feature at a given position. // - // If no feature is found for the given point, a feature with an empty name - // should be returned. + // A feature with an empty name is returned if there's no feature at the given + // position. GetFeature(context.Context, *Point) (*Feature, error) // A server-to-client streaming RPC. // @@ -310,9 +328,9 @@ func RegisterRouteGuideServer(s *grpc.Server, srv RouteGuideServer) { s.RegisterService(&_RouteGuide_serviceDesc, srv) } -func _RouteGuide_GetFeature_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _RouteGuide_GetFeature_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(Point) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(RouteGuideServer).GetFeature(ctx, in) @@ -396,7 +414,7 @@ func (x *routeGuideRouteChatServer) Recv() (*RouteNote, error) { } var _RouteGuide_serviceDesc = grpc.ServiceDesc{ - ServiceName: "proto.RouteGuide", + ServiceName: "routeguide.RouteGuide", HandlerType: (*RouteGuideServer)(nil), Methods: []grpc.MethodDesc{ { @@ -423,3 +441,33 @@ var _RouteGuide_serviceDesc = grpc.ServiceDesc{ }, }, } + +var fileDescriptor0 = []byte{ + // 412 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x53, 0xd1, 0x6a, 0xa3, 0x40, + 0x14, 0xcd, 0x98, 0x64, 0xb3, 0x5e, 0x5d, 0x96, 0xcc, 0xb2, 0x20, 0xd9, 0x85, 0xb6, 0xf6, 0x25, + 0x2f, 0x95, 0x90, 0x42, 0x1e, 0x5b, 0x9a, 0x40, 0xf3, 0x12, 0x4a, 0x6a, 0xf3, 0x1e, 0xa6, 0x3a, + 0x35, 0x03, 0xea, 0x88, 0x8e, 0xd0, 0x7e, 0x40, 0xbf, 0xa0, 0x7f, 0xd0, 0x2f, 0xed, 0x38, 0x6a, + 0x62, 0xda, 0x84, 0xbe, 0x39, 0xe7, 0x9e, 0x73, 0xef, 0xb9, 0xe7, 0x22, 0xf4, 0x53, 0x9e, 0x0b, + 0xba, 0x0e, 0x72, 0xe6, 0x53, 0x27, 0x49, 0xb9, 0xe0, 0x18, 0x14, 0xa4, 0x10, 0xfb, 0x06, 0xba, + 0x4b, 0xce, 0x62, 0x81, 0x07, 0xf0, 0x33, 0x24, 0x82, 0x89, 0xdc, 0xa7, 0x16, 0x3a, 0x45, 0xc3, + 0xae, 0xbb, 0x7d, 0xe3, 0xff, 0xa0, 0x87, 0x3c, 0x0e, 0xca, 0xa2, 0xa6, 0x8a, 0x3b, 0xc0, 0xbe, + 0x07, 0xdd, 0xa5, 0x9e, 0x20, 0x71, 0x10, 0x52, 0x7c, 0x06, 0x5a, 0xc8, 0x55, 0x03, 0x63, 0xdc, + 0x77, 0x76, 0x83, 0x1c, 0x35, 0xc5, 0x95, 0xc5, 0x82, 0xb2, 0x61, 0xaa, 0xcd, 0x61, 0xca, 0x86, + 0xd9, 0x0b, 0xe8, 0xdd, 0x52, 0x22, 0xf2, 0x94, 0x62, 0x0c, 0x9d, 0x98, 0x44, 0xa5, 0x27, 0xdd, + 0x55, 0xdf, 0xf8, 0x42, 0x7a, 0xe5, 0x9e, 0x74, 0xc7, 0xe3, 0xe3, 0x7d, 0xb6, 0x14, 0x7b, 0x25, + 0x0d, 0x16, 0xd5, 0x3b, 0x2e, 0xf6, 0xb5, 0xe8, 0x5b, 0x2d, 0xb6, 0xa0, 0x17, 0xd1, 0x2c, 0x23, + 0x41, 0xb9, 0xb8, 0xee, 0xd6, 0x4f, 0xfb, 0x0d, 0x81, 0xa9, 0xda, 0x3e, 0xe4, 0x51, 0x44, 0xd2, + 0x17, 0x7c, 0x02, 0x46, 0x52, 0xa8, 0xd7, 0x1e, 0xcf, 0x63, 0x51, 0x85, 0x08, 0x0a, 0x9a, 0x15, + 0x08, 0x3e, 0x87, 0x5f, 0x4f, 0xe5, 0x56, 0x15, 0xa5, 0x8c, 0xd2, 0xac, 0xc0, 0x92, 0x24, 0xef, + 0xe0, 0xb3, 0x4c, 0xa6, 0xe9, 0x51, 0xab, 0x5d, 0xde, 0xa1, 0x7e, 0xcb, 0xe4, 0x4c, 0x1a, 0x92, + 0x24, 0xa3, 0xfe, 0x5a, 0x30, 0x99, 0x49, 0x47, 0xd5, 0x8d, 0x0a, 0x5b, 0x49, 0x68, 0xfc, 0xaa, + 0x01, 0x28, 0x57, 0xf3, 0x62, 0x1d, 0x3c, 0x01, 0x98, 0x53, 0x51, 0x67, 0xf9, 0x75, 0xd3, 0xc1, + 0x9f, 0x26, 0x54, 0xf1, 0xec, 0x16, 0xbe, 0x02, 0x73, 0x21, 0xa7, 0x56, 0x40, 0x86, 0xff, 0x36, + 0x69, 0xdb, 0x6b, 0x1f, 0x51, 0x8f, 0x90, 0xd4, 0x1b, 0x92, 0xc5, 0x53, 0x5f, 0x79, 0x39, 0x34, + 0xd8, 0xda, 0xeb, 0xd8, 0xc8, 0xd1, 0x6e, 0x0d, 0x11, 0xbe, 0xae, 0x4e, 0x36, 0xdb, 0x10, 0xf1, + 0x69, 0x78, 0x7d, 0xc9, 0xc1, 0x61, 0xb8, 0x90, 0x8f, 0xd0, 0x74, 0x02, 0xff, 0x18, 0x77, 0x82, + 0x34, 0xf1, 0x1c, 0xfa, 0x4c, 0xa2, 0x24, 0xa4, 0x59, 0x83, 0x3e, 0xfd, 0xbd, 0xcb, 0x68, 0x59, + 0xfc, 0x13, 0x4b, 0xf4, 0xae, 0xb5, 0xdd, 0xd5, 0xfc, 0xf1, 0x87, 0xfa, 0x45, 0x2e, 0x3f, 0x02, + 0x00, 0x00, 0xff, 0xff, 0xf3, 0xe2, 0x76, 0x5e, 0x37, 0x03, 0x00, 0x00, +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.proto b/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.proto index bee7ac51ab..12c4495ffa 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.proto +++ b/Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/routeguide/route_guide.proto @@ -29,6 +29,11 @@ syntax = "proto3"; +option java_multiple_files = true; +option java_package = "io.grpc.examples.routeguide"; +option java_outer_classname = "RouteGuideProto"; +option objc_class_prefix = "RTG"; + package routeguide; // Interface exported by the server. @@ -37,8 +42,8 @@ service RouteGuide { // // Obtains the feature at a given position. // - // If no feature is found for the given point, a feature with an empty name - // should be returned. + // A feature with an empty name is returned if there's no feature at the given + // position. rpc GetFeature(Point) returns (Feature) {} // A server-to-client streaming RPC. diff --git a/Godeps/_workspace/src/google.golang.org/grpc/grpclog/logger.go b/Godeps/_workspace/src/google.golang.org/grpc/grpclog/logger.go index cc6e27c064..2cc09be489 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/grpclog/logger.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/grpclog/logger.go @@ -42,6 +42,8 @@ import ( ) // Use golang's standard logger by default. +// Access is not mutex-protected: do not modify except in init() +// functions. var logger Logger = log.New(os.Stderr, "", log.LstdFlags) // Logger mimics golang's standard Logger as an interface. @@ -54,7 +56,8 @@ type Logger interface { Println(args ...interface{}) } -// SetLogger sets the logger that is used in grpc. +// SetLogger sets the logger that is used in grpc. Call only from +// init() functions. func SetLogger(l Logger) { logger = l } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.pb.go index 6bfbe49730..8e89dc9f27 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.pb.go @@ -15,6 +15,8 @@ It has these top-level messages: package grpc_health_v1alpha import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" import ( context "golang.org/x/net/context" @@ -23,6 +25,12 @@ import ( // 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. +const _ = proto.ProtoPackageIsVersion1 type HealthCheckResponse_ServingStatus int32 @@ -46,24 +54,31 @@ var HealthCheckResponse_ServingStatus_value = map[string]int32{ func (x HealthCheckResponse_ServingStatus) String() string { return proto.EnumName(HealthCheckResponse_ServingStatus_name, int32(x)) } - -type HealthCheckRequest struct { - Service string `protobuf:"bytes,2,opt,name=service" json:"service,omitempty"` +func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{1, 0} } -func (m *HealthCheckRequest) Reset() { *m = HealthCheckRequest{} } -func (m *HealthCheckRequest) String() string { return proto.CompactTextString(m) } -func (*HealthCheckRequest) ProtoMessage() {} +type HealthCheckRequest struct { + Service string `protobuf:"bytes,1,opt,name=service" json:"service,omitempty"` +} + +func (m *HealthCheckRequest) Reset() { *m = HealthCheckRequest{} } +func (m *HealthCheckRequest) String() string { return proto.CompactTextString(m) } +func (*HealthCheckRequest) ProtoMessage() {} +func (*HealthCheckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } type HealthCheckResponse struct { Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,enum=grpc.health.v1alpha.HealthCheckResponse_ServingStatus" json:"status,omitempty"` } -func (m *HealthCheckResponse) Reset() { *m = HealthCheckResponse{} } -func (m *HealthCheckResponse) String() string { return proto.CompactTextString(m) } -func (*HealthCheckResponse) ProtoMessage() {} +func (m *HealthCheckResponse) Reset() { *m = HealthCheckResponse{} } +func (m *HealthCheckResponse) String() string { return proto.CompactTextString(m) } +func (*HealthCheckResponse) ProtoMessage() {} +func (*HealthCheckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func init() { + proto.RegisterType((*HealthCheckRequest)(nil), "grpc.health.v1alpha.HealthCheckRequest") + proto.RegisterType((*HealthCheckResponse)(nil), "grpc.health.v1alpha.HealthCheckResponse") proto.RegisterEnum("grpc.health.v1alpha.HealthCheckResponse_ServingStatus", HealthCheckResponse_ServingStatus_name, HealthCheckResponse_ServingStatus_value) } @@ -71,59 +86,77 @@ func init() { var _ context.Context var _ grpc.ClientConn -// Client API for HealthCheck service +// Client API for Health service -type HealthCheckClient interface { +type HealthClient interface { Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) } -type healthCheckClient struct { +type healthClient struct { cc *grpc.ClientConn } -func NewHealthCheckClient(cc *grpc.ClientConn) HealthCheckClient { - return &healthCheckClient{cc} +func NewHealthClient(cc *grpc.ClientConn) HealthClient { + return &healthClient{cc} } -func (c *healthCheckClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { +func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { out := new(HealthCheckResponse) - err := grpc.Invoke(ctx, "/grpc.health.v1alpha.HealthCheck/Check", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/grpc.health.v1alpha.Health/Check", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -// Server API for HealthCheck service +// Server API for Health service -type HealthCheckServer interface { +type HealthServer interface { Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) } -func RegisterHealthCheckServer(s *grpc.Server, srv HealthCheckServer) { - s.RegisterService(&_HealthCheck_serviceDesc, srv) +func RegisterHealthServer(s *grpc.Server, srv HealthServer) { + s.RegisterService(&_Health_serviceDesc, srv) } -func _HealthCheck_Check_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(HealthCheckRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } - out, err := srv.(HealthCheckServer).Check(ctx, in) + out, err := srv.(HealthServer).Check(ctx, in) if err != nil { return nil, err } return out, nil } -var _HealthCheck_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.health.v1alpha.HealthCheck", - HandlerType: (*HealthCheckServer)(nil), +var _Health_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.health.v1alpha.Health", + HandlerType: (*HealthServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Check", - Handler: _HealthCheck_Check_Handler, + Handler: _Health_Check_Handler, }, }, Streams: []grpc.StreamDesc{}, } + +var fileDescriptor0 = []byte{ + // 209 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x48, 0x4d, 0xcc, + 0x29, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4e, 0x2f, 0x2a, 0x48, 0xd6, 0x83, + 0x0a, 0x95, 0x19, 0x26, 0xe6, 0x14, 0x64, 0x24, 0x2a, 0xe9, 0x71, 0x09, 0x79, 0x80, 0x45, 0x9c, + 0x33, 0x52, 0x93, 0xb3, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x24, 0xb8, 0xd8, 0x8b, + 0x53, 0x8b, 0xca, 0x32, 0x93, 0x53, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0x60, 0x5c, 0xa5, + 0x85, 0x8c, 0x5c, 0xc2, 0x28, 0x1a, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0xfc, 0xb8, 0xd8, + 0x8a, 0x4b, 0x12, 0x4b, 0x4a, 0x8b, 0xc1, 0x1a, 0xf8, 0x8c, 0xcc, 0xf4, 0xb0, 0xd8, 0xa6, 0x87, + 0x45, 0xa7, 0x5e, 0x30, 0xc8, 0xe4, 0xbc, 0xf4, 0x60, 0xb0, 0xee, 0x20, 0xa8, 0x29, 0x4a, 0x56, + 0x5c, 0xbc, 0x28, 0x12, 0x42, 0xdc, 0x5c, 0xec, 0xa1, 0x7e, 0xde, 0x7e, 0xfe, 0xe1, 0x7e, 0x02, + 0x0c, 0x20, 0x4e, 0xb0, 0x6b, 0x50, 0x98, 0xa7, 0x9f, 0xbb, 0x00, 0xa3, 0x10, 0x3f, 0x17, 0xb7, + 0x9f, 0x7f, 0x48, 0x3c, 0x4c, 0x80, 0xc9, 0x28, 0x85, 0x8b, 0x0d, 0x62, 0x91, 0x50, 0x14, 0x17, + 0x2b, 0xd8, 0x32, 0x21, 0x75, 0xc2, 0xce, 0x01, 0xfb, 0x5c, 0x4a, 0x83, 0x58, 0x77, 0x27, 0xb1, + 0x81, 0x43, 0xd5, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x3f, 0xd0, 0xe1, 0x65, 0x01, 0x00, + 0x00, +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.proto b/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.proto index 1ca5bbc169..91c7f06e9b 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.proto +++ b/Godeps/_workspace/src/google.golang.org/grpc/health/grpc_health_v1alpha/health.proto @@ -3,7 +3,7 @@ syntax = "proto3"; package grpc.health.v1alpha; message HealthCheckRequest { - string service = 2; + string service = 1; } message HealthCheckResponse { @@ -15,6 +15,6 @@ message HealthCheckResponse { ServingStatus status = 1; } -service HealthCheck{ +service Health{ rpc Check(HealthCheckRequest) returns (HealthCheckResponse); } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/interop/client/client.go b/Godeps/_workspace/src/google.golang.org/grpc/interop/client/client.go index 4f715d35ee..deb9c3d848 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/interop/client/client.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/interop/client/client.go @@ -35,29 +35,20 @@ package main import ( "flag" - "io" - "io/ioutil" "net" "strconv" - "strings" - "time" - "github.com/golang/protobuf/proto" - "golang.org/x/net/context" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" "google.golang.org/grpc" - "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/oauth" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/interop" testpb "google.golang.org/grpc/interop/grpc_testing" - "google.golang.org/grpc/metadata" ) var ( useTLS = flag.Bool("use_tls", false, "Connection uses TLS if true, else plain TCP") - caFile = flag.String("tls_ca_file", "testdata/ca.pem", "The file containning the CA root cert file") + testCA = flag.Bool("use_test_ca", false, "Whether to replace platform root CAs with test CA as the CA root") serviceAccountKeyFile = flag.String("service_account_key_file", "", "Path to service account json key file") oauthScope = flag.String("oauth_scope", "", "The scope for OAuth2 tokens") defaultServiceAccount = flag.String("default_service_account", "", "Email of GCE default service account") @@ -72,7 +63,7 @@ var ( server_streaming : single request with response streaming; ping_pong : full-duplex streaming; empty_stream : full-duplex streaming with zero message; - timeout_on_sleeping_server: fullduplex streaming; + timeout_on_sleeping_server: fullduplex streaming on a sleeping server; compute_engine_creds: large_unary with compute engine auth; service_account_creds: large_unary with service account auth; jwt_token_creds: large_unary with jwt token auth; @@ -80,411 +71,11 @@ var ( oauth2_auth_token: large_unary with oauth2 token auth; cancel_after_begin: cancellation after metadata has been sent but before payloads are sent; cancel_after_first_response: cancellation after receiving 1st message from the server.`) + + // The test CA root cert file + testCAFile = "testdata/ca.pem" ) -var ( - reqSizes = []int{27182, 8, 1828, 45904} - respSizes = []int{31415, 9, 2653, 58979} - largeReqSize = 271828 - largeRespSize = 314159 -) - -func newPayload(t testpb.PayloadType, size int) *testpb.Payload { - if size < 0 { - grpclog.Fatalf("Requested a response with invalid length %d", size) - } - body := make([]byte, size) - switch t { - case testpb.PayloadType_COMPRESSABLE: - case testpb.PayloadType_UNCOMPRESSABLE: - grpclog.Fatalf("PayloadType UNCOMPRESSABLE is not supported") - default: - grpclog.Fatalf("Unsupported payload type: %d", t) - } - return &testpb.Payload{ - Type: t.Enum(), - Body: body, - } -} - -func doEmptyUnaryCall(tc testpb.TestServiceClient) { - reply, err := tc.EmptyCall(context.Background(), &testpb.Empty{}) - if err != nil { - grpclog.Fatal("/TestService/EmptyCall RPC failed: ", err) - } - if !proto.Equal(&testpb.Empty{}, reply) { - grpclog.Fatalf("/TestService/EmptyCall receives %v, want %v", reply, testpb.Empty{}) - } - grpclog.Println("EmptyUnaryCall done") -} - -func doLargeUnaryCall(tc testpb.TestServiceClient) { - pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) - req := &testpb.SimpleRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseSize: proto.Int32(int32(largeRespSize)), - Payload: pl, - } - reply, err := tc.UnaryCall(context.Background(), req) - if err != nil { - grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) - } - t := reply.GetPayload().GetType() - s := len(reply.GetPayload().GetBody()) - if t != testpb.PayloadType_COMPRESSABLE || s != largeRespSize { - grpclog.Fatalf("Got the reply with type %d len %d; want %d, %d", t, s, testpb.PayloadType_COMPRESSABLE, largeRespSize) - } - grpclog.Println("LargeUnaryCall done") -} - -func doClientStreaming(tc testpb.TestServiceClient) { - stream, err := tc.StreamingInputCall(context.Background()) - if err != nil { - grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err) - } - var sum int - for _, s := range reqSizes { - pl := newPayload(testpb.PayloadType_COMPRESSABLE, s) - req := &testpb.StreamingInputCallRequest{ - Payload: pl, - } - if err := stream.Send(req); err != nil { - grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) - } - sum += s - grpclog.Printf("Sent a request of size %d, aggregated size %d", s, sum) - - } - reply, err := stream.CloseAndRecv() - if err != nil { - grpclog.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) - } - if reply.GetAggregatedPayloadSize() != int32(sum) { - grpclog.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum) - } - grpclog.Println("ClientStreaming done") -} - -func doServerStreaming(tc testpb.TestServiceClient) { - respParam := make([]*testpb.ResponseParameters, len(respSizes)) - for i, s := range respSizes { - respParam[i] = &testpb.ResponseParameters{ - Size: proto.Int32(int32(s)), - } - } - req := &testpb.StreamingOutputCallRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseParameters: respParam, - } - stream, err := tc.StreamingOutputCall(context.Background(), req) - if err != nil { - grpclog.Fatalf("%v.StreamingOutputCall(_) = _, %v", tc, err) - } - var rpcStatus error - var respCnt int - var index int - for { - reply, err := stream.Recv() - if err != nil { - rpcStatus = err - break - } - t := reply.GetPayload().GetType() - if t != testpb.PayloadType_COMPRESSABLE { - grpclog.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE) - } - size := len(reply.GetPayload().GetBody()) - if size != int(respSizes[index]) { - grpclog.Fatalf("Got reply body of length %d, want %d", size, respSizes[index]) - } - index++ - respCnt++ - } - if rpcStatus != io.EOF { - grpclog.Fatalf("Failed to finish the server streaming rpc: %v", err) - } - if respCnt != len(respSizes) { - grpclog.Fatalf("Got %d reply, want %d", len(respSizes), respCnt) - } - grpclog.Println("ServerStreaming done") -} - -func doPingPong(tc testpb.TestServiceClient) { - stream, err := tc.FullDuplexCall(context.Background()) - if err != nil { - grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) - } - var index int - for index < len(reqSizes) { - respParam := []*testpb.ResponseParameters{ - { - Size: proto.Int32(int32(respSizes[index])), - }, - } - pl := newPayload(testpb.PayloadType_COMPRESSABLE, reqSizes[index]) - req := &testpb.StreamingOutputCallRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseParameters: respParam, - Payload: pl, - } - if err := stream.Send(req); err != nil { - grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) - } - reply, err := stream.Recv() - if err != nil { - grpclog.Fatalf("%v.Recv() = %v", stream, err) - } - t := reply.GetPayload().GetType() - if t != testpb.PayloadType_COMPRESSABLE { - grpclog.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE) - } - size := len(reply.GetPayload().GetBody()) - if size != int(respSizes[index]) { - grpclog.Fatalf("Got reply body of length %d, want %d", size, respSizes[index]) - } - index++ - } - if err := stream.CloseSend(); err != nil { - grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil) - } - if _, err := stream.Recv(); err != io.EOF { - grpclog.Fatalf("%v failed to complele the ping pong test: %v", stream, err) - } - grpclog.Println("Pingpong done") -} - -func doEmptyStream(tc testpb.TestServiceClient) { - stream, err := tc.FullDuplexCall(context.Background()) - if err != nil { - grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) - } - if err := stream.CloseSend(); err != nil { - grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil) - } - if _, err := stream.Recv(); err != io.EOF { - grpclog.Fatalf("%v failed to complete the empty stream test: %v", stream, err) - } - grpclog.Println("Emptystream done") -} - -func doTimeoutOnSleepingServer(tc testpb.TestServiceClient) { - ctx, _ := context.WithTimeout(context.Background(), 1*time.Millisecond) - stream, err := tc.FullDuplexCall(ctx) - if err != nil { - if grpc.Code(err) == codes.DeadlineExceeded { - grpclog.Println("TimeoutOnSleepingServer done") - return - } - grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) - } - pl := newPayload(testpb.PayloadType_COMPRESSABLE, 27182) - req := &testpb.StreamingOutputCallRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - Payload: pl, - } - if err := stream.Send(req); err != nil { - grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) - } - if _, err := stream.Recv(); grpc.Code(err) != codes.DeadlineExceeded { - grpclog.Fatalf("%v.Recv() = _, %v, want error code %d", stream, err, codes.DeadlineExceeded) - } - grpclog.Println("TimeoutOnSleepingServer done") -} - -func doComputeEngineCreds(tc testpb.TestServiceClient) { - pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) - req := &testpb.SimpleRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseSize: proto.Int32(int32(largeRespSize)), - Payload: pl, - FillUsername: proto.Bool(true), - FillOauthScope: proto.Bool(true), - } - reply, err := tc.UnaryCall(context.Background(), req) - if err != nil { - grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) - } - user := reply.GetUsername() - scope := reply.GetOauthScope() - if user != *defaultServiceAccount { - grpclog.Fatalf("Got user name %q, want %q.", user, *defaultServiceAccount) - } - if !strings.Contains(*oauthScope, scope) { - grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, *oauthScope) - } - grpclog.Println("ComputeEngineCreds done") -} - -func getServiceAccountJSONKey() []byte { - jsonKey, err := ioutil.ReadFile(*serviceAccountKeyFile) - if err != nil { - grpclog.Fatalf("Failed to read the service account key file: %v", err) - } - return jsonKey -} - -func doServiceAccountCreds(tc testpb.TestServiceClient) { - pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) - req := &testpb.SimpleRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseSize: proto.Int32(int32(largeRespSize)), - Payload: pl, - FillUsername: proto.Bool(true), - FillOauthScope: proto.Bool(true), - } - reply, err := tc.UnaryCall(context.Background(), req) - if err != nil { - grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) - } - jsonKey := getServiceAccountJSONKey() - user := reply.GetUsername() - scope := reply.GetOauthScope() - if !strings.Contains(string(jsonKey), user) { - grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) - } - if !strings.Contains(*oauthScope, scope) { - grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, *oauthScope) - } - grpclog.Println("ServiceAccountCreds done") -} - -func doJWTTokenCreds(tc testpb.TestServiceClient) { - pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) - req := &testpb.SimpleRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseSize: proto.Int32(int32(largeRespSize)), - Payload: pl, - FillUsername: proto.Bool(true), - } - reply, err := tc.UnaryCall(context.Background(), req) - if err != nil { - grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) - } - jsonKey := getServiceAccountJSONKey() - user := reply.GetUsername() - if !strings.Contains(string(jsonKey), user) { - grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) - } - grpclog.Println("JWTtokenCreds done") -} - -func getToken() *oauth2.Token { - jsonKey := getServiceAccountJSONKey() - config, err := google.JWTConfigFromJSON(jsonKey, *oauthScope) - if err != nil { - grpclog.Fatalf("Failed to get the config: %v", err) - } - token, err := config.TokenSource(context.Background()).Token() - if err != nil { - grpclog.Fatalf("Failed to get the token: %v", err) - } - return token -} - -func doOauth2TokenCreds(tc testpb.TestServiceClient) { - pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) - req := &testpb.SimpleRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseSize: proto.Int32(int32(largeRespSize)), - Payload: pl, - FillUsername: proto.Bool(true), - FillOauthScope: proto.Bool(true), - } - reply, err := tc.UnaryCall(context.Background(), req) - if err != nil { - grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) - } - jsonKey := getServiceAccountJSONKey() - user := reply.GetUsername() - scope := reply.GetOauthScope() - if !strings.Contains(string(jsonKey), user) { - grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) - } - if !strings.Contains(*oauthScope, scope) { - grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, *oauthScope) - } - grpclog.Println("Oauth2TokenCreds done") -} - -func doPerRPCCreds(tc testpb.TestServiceClient) { - jsonKey := getServiceAccountJSONKey() - pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) - req := &testpb.SimpleRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseSize: proto.Int32(int32(largeRespSize)), - Payload: pl, - FillUsername: proto.Bool(true), - FillOauthScope: proto.Bool(true), - } - token := getToken() - kv := map[string]string{"authorization": token.TokenType + " " + token.AccessToken} - ctx := metadata.NewContext(context.Background(), metadata.MD{"authorization": []string{kv["authorization"]}}) - reply, err := tc.UnaryCall(ctx, req) - if err != nil { - grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) - } - user := reply.GetUsername() - scope := reply.GetOauthScope() - if !strings.Contains(string(jsonKey), user) { - grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) - } - if !strings.Contains(*oauthScope, scope) { - grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, *oauthScope) - } - grpclog.Println("PerRPCCreds done") -} - -var ( - testMetadata = metadata.MD{ - "key1": []string{"value1"}, - "key2": []string{"value2"}, - } -) - -func doCancelAfterBegin(tc testpb.TestServiceClient) { - ctx, cancel := context.WithCancel(metadata.NewContext(context.Background(), testMetadata)) - stream, err := tc.StreamingInputCall(ctx) - if err != nil { - grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err) - } - cancel() - _, err = stream.CloseAndRecv() - if grpc.Code(err) != codes.Canceled { - grpclog.Fatalf("%v.CloseAndRecv() got error code %d, want %d", stream, grpc.Code(err), codes.Canceled) - } - grpclog.Println("CancelAfterBegin done") -} - -func doCancelAfterFirstResponse(tc testpb.TestServiceClient) { - ctx, cancel := context.WithCancel(context.Background()) - stream, err := tc.FullDuplexCall(ctx) - if err != nil { - grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) - } - respParam := []*testpb.ResponseParameters{ - { - Size: proto.Int32(31415), - }, - } - pl := newPayload(testpb.PayloadType_COMPRESSABLE, 27182) - req := &testpb.StreamingOutputCallRequest{ - ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), - ResponseParameters: respParam, - Payload: pl, - } - if err := stream.Send(req); err != nil { - grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) - } - if _, err := stream.Recv(); err != nil { - grpclog.Fatalf("%v.Recv() = %v", stream, err) - } - cancel() - if _, err := stream.Recv(); grpc.Code(err) != codes.Canceled { - grpclog.Fatalf("%v compleled with error code %d, want %d", stream, grpc.Code(err), codes.Canceled) - } - grpclog.Println("CancelAfterFirstResponse done") -} - func main() { flag.Parse() serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort)) @@ -495,9 +86,9 @@ func main() { sn = *tlsServerName } var creds credentials.TransportAuthenticator - if *caFile != "" { + if *testCA { var err error - creds, err = credentials.NewClientTLSFromFile(*caFile, sn) + creds, err = credentials.NewClientTLSFromFile(testCAFile, sn) if err != nil { grpclog.Fatalf("Failed to create TLS credentials %v", err) } @@ -520,7 +111,7 @@ func main() { } opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) } else if *testCase == "oauth2_auth_token" { - opts = append(opts, grpc.WithPerRPCCredentials(oauth.NewOauthAccess(getToken()))) + opts = append(opts, grpc.WithPerRPCCredentials(oauth.NewOauthAccess(interop.GetToken(*serviceAccountKeyFile, *oauthScope)))) } } else { opts = append(opts, grpc.WithInsecure()) @@ -533,48 +124,48 @@ func main() { tc := testpb.NewTestServiceClient(conn) switch *testCase { case "empty_unary": - doEmptyUnaryCall(tc) + interop.DoEmptyUnaryCall(tc) case "large_unary": - doLargeUnaryCall(tc) + interop.DoLargeUnaryCall(tc) case "client_streaming": - doClientStreaming(tc) + interop.DoClientStreaming(tc) case "server_streaming": - doServerStreaming(tc) + interop.DoServerStreaming(tc) case "ping_pong": - doPingPong(tc) + interop.DoPingPong(tc) case "empty_stream": - doEmptyStream(tc) + interop.DoEmptyStream(tc) case "timeout_on_sleeping_server": - doTimeoutOnSleepingServer(tc) + interop.DoTimeoutOnSleepingServer(tc) case "compute_engine_creds": if !*useTLS { grpclog.Fatalf("TLS is not enabled. TLS is required to execute compute_engine_creds test case.") } - doComputeEngineCreds(tc) + interop.DoComputeEngineCreds(tc, *defaultServiceAccount, *oauthScope) case "service_account_creds": if !*useTLS { grpclog.Fatalf("TLS is not enabled. TLS is required to execute service_account_creds test case.") } - doServiceAccountCreds(tc) + interop.DoServiceAccountCreds(tc, *serviceAccountKeyFile, *oauthScope) case "jwt_token_creds": if !*useTLS { grpclog.Fatalf("TLS is not enabled. TLS is required to execute jwt_token_creds test case.") } - doJWTTokenCreds(tc) + interop.DoJWTTokenCreds(tc, *serviceAccountKeyFile) case "per_rpc_creds": if !*useTLS { grpclog.Fatalf("TLS is not enabled. TLS is required to execute per_rpc_creds test case.") } - doPerRPCCreds(tc) + interop.DoPerRPCCreds(tc, *serviceAccountKeyFile, *oauthScope) case "oauth2_auth_token": if !*useTLS { grpclog.Fatalf("TLS is not enabled. TLS is required to execute oauth2_auth_token test case.") } - doOauth2TokenCreds(tc) + interop.DoOauth2TokenCreds(tc, *serviceAccountKeyFile, *oauthScope) case "cancel_after_begin": - doCancelAfterBegin(tc) + interop.DoCancelAfterBegin(tc) case "cancel_after_first_response": - doCancelAfterFirstResponse(tc) + interop.DoCancelAfterFirstResponse(tc) default: grpclog.Fatal("Unsupported test case: ", *testCase) } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/interop/grpc_testing/test.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/interop/grpc_testing/test.pb.go index b25e98b8e4..7b0803f552 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/interop/grpc_testing/test.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/interop/grpc_testing/test.pb.go @@ -22,6 +22,7 @@ It has these top-level messages: package grpc_testing import proto "github.com/golang/protobuf/proto" +import fmt "fmt" import math "math" import ( @@ -29,14 +30,15 @@ import ( grpc "google.golang.org/grpc" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - // 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. +const _ = proto.ProtoPackageIsVersion1 + // The type of payload that should be returned. type PayloadType int32 @@ -76,14 +78,16 @@ func (x *PayloadType) UnmarshalJSON(data []byte) error { *x = PayloadType(value) return nil } +func (PayloadType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } type Empty struct { XXX_unrecognized []byte `json:"-"` } -func (m *Empty) Reset() { *m = Empty{} } -func (m *Empty) String() string { return proto.CompactTextString(m) } -func (*Empty) ProtoMessage() {} +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } // A block of data, to simply increase gRPC message size. type Payload struct { @@ -94,9 +98,10 @@ type Payload struct { XXX_unrecognized []byte `json:"-"` } -func (m *Payload) Reset() { *m = Payload{} } -func (m *Payload) String() string { return proto.CompactTextString(m) } -func (*Payload) ProtoMessage() {} +func (m *Payload) Reset() { *m = Payload{} } +func (m *Payload) String() string { return proto.CompactTextString(m) } +func (*Payload) ProtoMessage() {} +func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *Payload) GetType() PayloadType { if m != nil && m.Type != nil { @@ -129,9 +134,10 @@ type SimpleRequest struct { XXX_unrecognized []byte `json:"-"` } -func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } -func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } -func (*SimpleRequest) ProtoMessage() {} +func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } +func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } +func (*SimpleRequest) ProtoMessage() {} +func (*SimpleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (m *SimpleRequest) GetResponseType() PayloadType { if m != nil && m.ResponseType != nil { @@ -180,9 +186,10 @@ type SimpleResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } -func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } -func (*SimpleResponse) ProtoMessage() {} +func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } +func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } +func (*SimpleResponse) ProtoMessage() {} +func (*SimpleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (m *SimpleResponse) GetPayload() *Payload { if m != nil { @@ -212,9 +219,10 @@ type StreamingInputCallRequest struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingInputCallRequest) Reset() { *m = StreamingInputCallRequest{} } -func (m *StreamingInputCallRequest) String() string { return proto.CompactTextString(m) } -func (*StreamingInputCallRequest) ProtoMessage() {} +func (m *StreamingInputCallRequest) Reset() { *m = StreamingInputCallRequest{} } +func (m *StreamingInputCallRequest) String() string { return proto.CompactTextString(m) } +func (*StreamingInputCallRequest) ProtoMessage() {} +func (*StreamingInputCallRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (m *StreamingInputCallRequest) GetPayload() *Payload { if m != nil { @@ -230,9 +238,10 @@ type StreamingInputCallResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingInputCallResponse) Reset() { *m = StreamingInputCallResponse{} } -func (m *StreamingInputCallResponse) String() string { return proto.CompactTextString(m) } -func (*StreamingInputCallResponse) ProtoMessage() {} +func (m *StreamingInputCallResponse) Reset() { *m = StreamingInputCallResponse{} } +func (m *StreamingInputCallResponse) String() string { return proto.CompactTextString(m) } +func (*StreamingInputCallResponse) ProtoMessage() {} +func (*StreamingInputCallResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } func (m *StreamingInputCallResponse) GetAggregatedPayloadSize() int32 { if m != nil && m.AggregatedPayloadSize != nil { @@ -252,9 +261,10 @@ type ResponseParameters struct { XXX_unrecognized []byte `json:"-"` } -func (m *ResponseParameters) Reset() { *m = ResponseParameters{} } -func (m *ResponseParameters) String() string { return proto.CompactTextString(m) } -func (*ResponseParameters) ProtoMessage() {} +func (m *ResponseParameters) Reset() { *m = ResponseParameters{} } +func (m *ResponseParameters) String() string { return proto.CompactTextString(m) } +func (*ResponseParameters) ProtoMessage() {} +func (*ResponseParameters) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (m *ResponseParameters) GetSize() int32 { if m != nil && m.Size != nil { @@ -284,9 +294,10 @@ type StreamingOutputCallRequest struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingOutputCallRequest) Reset() { *m = StreamingOutputCallRequest{} } -func (m *StreamingOutputCallRequest) String() string { return proto.CompactTextString(m) } -func (*StreamingOutputCallRequest) ProtoMessage() {} +func (m *StreamingOutputCallRequest) Reset() { *m = StreamingOutputCallRequest{} } +func (m *StreamingOutputCallRequest) String() string { return proto.CompactTextString(m) } +func (*StreamingOutputCallRequest) ProtoMessage() {} +func (*StreamingOutputCallRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (m *StreamingOutputCallRequest) GetResponseType() PayloadType { if m != nil && m.ResponseType != nil { @@ -316,9 +327,10 @@ type StreamingOutputCallResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingOutputCallResponse) Reset() { *m = StreamingOutputCallResponse{} } -func (m *StreamingOutputCallResponse) String() string { return proto.CompactTextString(m) } -func (*StreamingOutputCallResponse) ProtoMessage() {} +func (m *StreamingOutputCallResponse) Reset() { *m = StreamingOutputCallResponse{} } +func (m *StreamingOutputCallResponse) String() string { return proto.CompactTextString(m) } +func (*StreamingOutputCallResponse) ProtoMessage() {} +func (*StreamingOutputCallResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (m *StreamingOutputCallResponse) GetPayload() *Payload { if m != nil { @@ -328,9 +340,22 @@ func (m *StreamingOutputCallResponse) GetPayload() *Payload { } func init() { + proto.RegisterType((*Empty)(nil), "grpc.testing.Empty") + proto.RegisterType((*Payload)(nil), "grpc.testing.Payload") + proto.RegisterType((*SimpleRequest)(nil), "grpc.testing.SimpleRequest") + proto.RegisterType((*SimpleResponse)(nil), "grpc.testing.SimpleResponse") + proto.RegisterType((*StreamingInputCallRequest)(nil), "grpc.testing.StreamingInputCallRequest") + proto.RegisterType((*StreamingInputCallResponse)(nil), "grpc.testing.StreamingInputCallResponse") + proto.RegisterType((*ResponseParameters)(nil), "grpc.testing.ResponseParameters") + proto.RegisterType((*StreamingOutputCallRequest)(nil), "grpc.testing.StreamingOutputCallRequest") + proto.RegisterType((*StreamingOutputCallResponse)(nil), "grpc.testing.StreamingOutputCallResponse") proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value) } +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + // Client API for TestService service type TestServiceClient interface { @@ -539,9 +564,9 @@ func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { s.RegisterService(&_TestService_serviceDesc, srv) } -func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(Empty) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(TestServiceServer).EmptyCall(ctx, in) @@ -551,9 +576,9 @@ func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, codec return out, nil } -func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(SimpleRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(TestServiceServer).UnaryCall(ctx, in) @@ -700,3 +725,43 @@ var _TestService_serviceDesc = grpc.ServiceDesc{ }, }, } + +var fileDescriptor0 = []byte{ + // 567 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x54, 0x51, 0x6f, 0xd2, 0x50, + 0x14, 0xb6, 0x03, 0x64, 0x1c, 0x58, 0x43, 0x0e, 0x59, 0x64, 0x9d, 0x89, 0x4b, 0x7d, 0xb0, 0x9a, + 0x88, 0x86, 0x44, 0x1f, 0x35, 0x73, 0x63, 0x71, 0x09, 0x03, 0x6c, 0xe1, 0x99, 0x5c, 0xe1, 0x0e, + 0x9b, 0x94, 0xb6, 0xb6, 0xb7, 0x46, 0x7c, 0xf0, 0x8f, 0xf9, 0x67, 0xfc, 0x11, 0xfe, 0x00, 0xef, + 0xbd, 0x6d, 0xa1, 0x40, 0x17, 0x99, 0xc6, 0xbd, 0xb5, 0xdf, 0xf9, 0xce, 0x77, 0xbe, 0xef, 0x9e, + 0xdb, 0x02, 0x30, 0x1a, 0xb2, 0x96, 0x1f, 0x78, 0xcc, 0xc3, 0xda, 0x2c, 0xf0, 0x27, 0x2d, 0x01, + 0xd8, 0xee, 0x4c, 0x2f, 0x43, 0xa9, 0x33, 0xf7, 0xd9, 0x42, 0xef, 0x42, 0x79, 0x40, 0x16, 0x8e, + 0x47, 0xa6, 0xf8, 0x1c, 0x8a, 0x6c, 0xe1, 0xd3, 0xa6, 0x72, 0xa2, 0x18, 0x6a, 0xfb, 0xa8, 0x95, + 0x6d, 0x68, 0x25, 0xa4, 0x21, 0x27, 0x98, 0x92, 0x86, 0x08, 0xc5, 0x8f, 0xde, 0x74, 0xd1, 0xdc, + 0xe3, 0xf4, 0x9a, 0x29, 0x9f, 0xf5, 0x5f, 0x0a, 0x1c, 0x58, 0xf6, 0xdc, 0x77, 0xa8, 0x49, 0x3f, + 0x47, 0xbc, 0x15, 0xdf, 0xc0, 0x41, 0x40, 0x43, 0xdf, 0x73, 0x43, 0x3a, 0xde, 0x4d, 0xbd, 0x96, + 0xf2, 0xc5, 0x1b, 0x3e, 0xce, 0xf4, 0x87, 0xf6, 0x37, 0x2a, 0xc7, 0x95, 0x56, 0x24, 0x8b, 0x63, + 0xf8, 0x02, 0xca, 0x7e, 0xac, 0xd0, 0x2c, 0xf0, 0x72, 0xb5, 0x7d, 0x98, 0x2b, 0x6f, 0xa6, 0x2c, + 0xa1, 0x7a, 0x6d, 0x3b, 0xce, 0x38, 0x0a, 0x69, 0xe0, 0x92, 0x39, 0x6d, 0x16, 0x79, 0xdb, 0xbe, + 0x59, 0x13, 0xe0, 0x28, 0xc1, 0xd0, 0x80, 0xba, 0x24, 0x79, 0x24, 0x62, 0x9f, 0xc6, 0xe1, 0xc4, + 0xe3, 0xee, 0x4b, 0x92, 0xa7, 0x0a, 0xbc, 0x2f, 0x60, 0x4b, 0xa0, 0xfa, 0x77, 0x50, 0xd3, 0xd4, + 0xb1, 0xab, 0xac, 0x23, 0x65, 0x27, 0x47, 0x1a, 0xec, 0x2f, 0xcd, 0x88, 0x88, 0x15, 0x73, 0xf9, + 0x8e, 0x8f, 0xa0, 0x9a, 0xf5, 0x50, 0x90, 0x65, 0xf0, 0x56, 0xf3, 0xbb, 0x70, 0x64, 0xb1, 0x80, + 0x92, 0x39, 0x97, 0xbe, 0x74, 0xfd, 0x88, 0x9d, 0x11, 0xc7, 0x49, 0x37, 0x70, 0x5b, 0x2b, 0xfa, + 0x10, 0xb4, 0x3c, 0xb5, 0x24, 0xd9, 0x6b, 0x78, 0x40, 0x66, 0xb3, 0x80, 0xce, 0x08, 0xa3, 0xd3, + 0x71, 0xd2, 0x13, 0xaf, 0x46, 0x91, 0xab, 0x39, 0x5c, 0x95, 0x13, 0x69, 0xb1, 0x23, 0xfd, 0x12, + 0x30, 0xd5, 0x18, 0x90, 0x80, 0xc7, 0x62, 0x34, 0x08, 0xc5, 0x25, 0xca, 0xb4, 0xca, 0x67, 0x11, + 0xd7, 0x76, 0x79, 0xf5, 0x0b, 0x11, 0x0b, 0x4a, 0x16, 0x0e, 0x29, 0x34, 0x0a, 0xf5, 0x9f, 0x4a, + 0xc6, 0x61, 0x3f, 0x62, 0x1b, 0x81, 0xff, 0xf5, 0xca, 0x7d, 0x80, 0xc6, 0xb2, 0xdf, 0x5f, 0x5a, + 0xe5, 0x3e, 0x0a, 0xfc, 0xf0, 0x4e, 0xd6, 0x55, 0xb6, 0x23, 0x99, 0x18, 0x6c, 0xc7, 0xbc, 0xed, + 0x05, 0xd5, 0x7b, 0x70, 0x9c, 0x9b, 0xf0, 0x2f, 0xaf, 0xd7, 0xb3, 0xb7, 0x50, 0xcd, 0x04, 0xc6, + 0x3a, 0xd4, 0xce, 0xfa, 0x57, 0x03, 0xb3, 0x63, 0x59, 0xa7, 0xef, 0xba, 0x9d, 0xfa, 0x3d, 0xbe, + 0x08, 0x75, 0xd4, 0x5b, 0xc3, 0x14, 0x04, 0xb8, 0x6f, 0x9e, 0xf6, 0xce, 0xfb, 0x57, 0xf5, 0xbd, + 0xf6, 0x8f, 0x22, 0x54, 0x87, 0x5c, 0xdd, 0xe2, 0x4b, 0xb0, 0x27, 0x14, 0x5f, 0x41, 0x45, 0xfe, + 0x40, 0x84, 0x2d, 0x6c, 0xac, 0x4f, 0x97, 0x05, 0x2d, 0x0f, 0xc4, 0x0b, 0xa8, 0x8c, 0x5c, 0x12, + 0xc4, 0x6d, 0xc7, 0xeb, 0x8c, 0xb5, 0x1f, 0x87, 0xf6, 0x30, 0xbf, 0x98, 0x1c, 0x80, 0x03, 0x8d, + 0x9c, 0xf3, 0x41, 0x63, 0xa3, 0xe9, 0xc6, 0x4b, 0xa2, 0x3d, 0xdd, 0x81, 0x19, 0xcf, 0x7a, 0xa9, + 0xa0, 0x0d, 0xb8, 0xfd, 0x45, 0xe0, 0x93, 0x1b, 0x24, 0x36, 0xbf, 0x40, 0xcd, 0xf8, 0x33, 0x31, + 0x1e, 0x65, 0x88, 0x51, 0xea, 0x45, 0xe4, 0x38, 0xe7, 0x11, 0x4f, 0xfb, 0xf5, 0xbf, 0x65, 0x32, + 0x14, 0x99, 0x4a, 0x7d, 0x4f, 0x9c, 0xeb, 0x3b, 0x18, 0xf5, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x4c, + 0x41, 0xfe, 0xb6, 0x89, 0x06, 0x00, 0x00, +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/interop/server/server.go b/Godeps/_workspace/src/google.golang.org/grpc/interop/server/server.go index f781c9d537..36ebcb6418 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/interop/server/server.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/interop/server/server.go @@ -35,17 +35,13 @@ package main import ( "flag" - "fmt" - "io" "net" "strconv" - "time" - "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/interop" testpb "google.golang.org/grpc/interop/grpc_testing" ) @@ -56,138 +52,6 @@ var ( port = flag.Int("port", 10000, "The server port") ) -type testServer struct { -} - -func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { - return new(testpb.Empty), nil -} - -func newPayload(t testpb.PayloadType, size int32) (*testpb.Payload, error) { - if size < 0 { - return nil, fmt.Errorf("requested a response with invalid length %d", size) - } - body := make([]byte, size) - switch t { - case testpb.PayloadType_COMPRESSABLE: - case testpb.PayloadType_UNCOMPRESSABLE: - return nil, fmt.Errorf("payloadType UNCOMPRESSABLE is not supported") - default: - return nil, fmt.Errorf("unsupported payload type: %d", t) - } - return &testpb.Payload{ - Type: t.Enum(), - Body: body, - }, nil -} - -func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { - pl, err := newPayload(in.GetResponseType(), in.GetResponseSize()) - if err != nil { - return nil, err - } - return &testpb.SimpleResponse{ - Payload: pl, - }, nil -} - -func (s *testServer) StreamingOutputCall(args *testpb.StreamingOutputCallRequest, stream testpb.TestService_StreamingOutputCallServer) error { - cs := args.GetResponseParameters() - for _, c := range cs { - if us := c.GetIntervalUs(); us > 0 { - time.Sleep(time.Duration(us) * time.Microsecond) - } - pl, err := newPayload(args.GetResponseType(), c.GetSize()) - if err != nil { - return err - } - if err := stream.Send(&testpb.StreamingOutputCallResponse{ - Payload: pl, - }); err != nil { - return err - } - } - return nil -} - -func (s *testServer) StreamingInputCall(stream testpb.TestService_StreamingInputCallServer) error { - var sum int - for { - in, err := stream.Recv() - if err == io.EOF { - return stream.SendAndClose(&testpb.StreamingInputCallResponse{ - AggregatedPayloadSize: proto.Int32(int32(sum)), - }) - } - if err != nil { - return err - } - p := in.GetPayload().GetBody() - sum += len(p) - } -} - -func (s *testServer) FullDuplexCall(stream testpb.TestService_FullDuplexCallServer) error { - for { - in, err := stream.Recv() - if err == io.EOF { - // read done. - return nil - } - if err != nil { - return err - } - cs := in.GetResponseParameters() - for _, c := range cs { - if us := c.GetIntervalUs(); us > 0 { - time.Sleep(time.Duration(us) * time.Microsecond) - } - pl, err := newPayload(in.GetResponseType(), c.GetSize()) - if err != nil { - return err - } - if err := stream.Send(&testpb.StreamingOutputCallResponse{ - Payload: pl, - }); err != nil { - return err - } - } - } -} - -func (s *testServer) HalfDuplexCall(stream testpb.TestService_HalfDuplexCallServer) error { - var msgBuf []*testpb.StreamingOutputCallRequest - for { - in, err := stream.Recv() - if err == io.EOF { - // read done. - break - } - if err != nil { - return err - } - msgBuf = append(msgBuf, in) - } - for _, m := range msgBuf { - cs := m.GetResponseParameters() - for _, c := range cs { - if us := c.GetIntervalUs(); us > 0 { - time.Sleep(time.Duration(us) * time.Microsecond) - } - pl, err := newPayload(m.GetResponseType(), c.GetSize()) - if err != nil { - return err - } - if err := stream.Send(&testpb.StreamingOutputCallResponse{ - Payload: pl, - }); err != nil { - return err - } - } - } - return nil -} - func main() { flag.Parse() p := strconv.Itoa(*port) @@ -204,6 +68,6 @@ func main() { opts = []grpc.ServerOption{grpc.Creds(creds)} } server := grpc.NewServer(opts...) - testpb.RegisterTestServiceServer(server, &testServer{}) + testpb.RegisterTestServiceServer(server, interop.NewTestServer()) server.Serve(lis) } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/interop/test_utils.go b/Godeps/_workspace/src/google.golang.org/grpc/interop/test_utils.go new file mode 100644 index 0000000000..6a73d6f453 --- /dev/null +++ b/Godeps/_workspace/src/google.golang.org/grpc/interop/test_utils.go @@ -0,0 +1,607 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package interop + +import ( + "fmt" + "io" + "io/ioutil" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + testpb "google.golang.org/grpc/interop/grpc_testing" + "google.golang.org/grpc/metadata" +) + +var ( + reqSizes = []int{27182, 8, 1828, 45904} + respSizes = []int{31415, 9, 2653, 58979} + largeReqSize = 271828 + largeRespSize = 314159 +) + +func clientNewPayload(t testpb.PayloadType, size int) *testpb.Payload { + if size < 0 { + grpclog.Fatalf("Requested a response with invalid length %d", size) + } + body := make([]byte, size) + switch t { + case testpb.PayloadType_COMPRESSABLE: + case testpb.PayloadType_UNCOMPRESSABLE: + grpclog.Fatalf("PayloadType UNCOMPRESSABLE is not supported") + default: + grpclog.Fatalf("Unsupported payload type: %d", t) + } + return &testpb.Payload{ + Type: t.Enum(), + Body: body, + } +} + +// DoEmptyUnaryCall performs a unary RPC with empty request and response messages. +func DoEmptyUnaryCall(tc testpb.TestServiceClient) { + reply, err := tc.EmptyCall(context.Background(), &testpb.Empty{}) + if err != nil { + grpclog.Fatal("/TestService/EmptyCall RPC failed: ", err) + } + if !proto.Equal(&testpb.Empty{}, reply) { + grpclog.Fatalf("/TestService/EmptyCall receives %v, want %v", reply, testpb.Empty{}) + } + grpclog.Println("EmptyUnaryCall done") +} + +// DoLargeUnaryCall performs a unary RPC with large payload in the request and response. +func DoLargeUnaryCall(tc testpb.TestServiceClient) { + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) + req := &testpb.SimpleRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseSize: proto.Int32(int32(largeRespSize)), + Payload: pl, + } + reply, err := tc.UnaryCall(context.Background(), req) + if err != nil { + grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) + } + t := reply.GetPayload().GetType() + s := len(reply.GetPayload().GetBody()) + if t != testpb.PayloadType_COMPRESSABLE || s != largeRespSize { + grpclog.Fatalf("Got the reply with type %d len %d; want %d, %d", t, s, testpb.PayloadType_COMPRESSABLE, largeRespSize) + } + grpclog.Println("LargeUnaryCall done") +} + +// DoClientStreaming performs a client streaming RPC. +func DoClientStreaming(tc testpb.TestServiceClient) { + stream, err := tc.StreamingInputCall(context.Background()) + if err != nil { + grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err) + } + var sum int + for _, s := range reqSizes { + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, s) + req := &testpb.StreamingInputCallRequest{ + Payload: pl, + } + if err := stream.Send(req); err != nil { + grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) + } + sum += s + grpclog.Printf("Sent a request of size %d, aggregated size %d", s, sum) + + } + reply, err := stream.CloseAndRecv() + if err != nil { + grpclog.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) + } + if reply.GetAggregatedPayloadSize() != int32(sum) { + grpclog.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum) + } + grpclog.Println("ClientStreaming done") +} + +// DoServerStreaming performs a server streaming RPC. +func DoServerStreaming(tc testpb.TestServiceClient) { + respParam := make([]*testpb.ResponseParameters, len(respSizes)) + for i, s := range respSizes { + respParam[i] = &testpb.ResponseParameters{ + Size: proto.Int32(int32(s)), + } + } + req := &testpb.StreamingOutputCallRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseParameters: respParam, + } + stream, err := tc.StreamingOutputCall(context.Background(), req) + if err != nil { + grpclog.Fatalf("%v.StreamingOutputCall(_) = _, %v", tc, err) + } + var rpcStatus error + var respCnt int + var index int + for { + reply, err := stream.Recv() + if err != nil { + rpcStatus = err + break + } + t := reply.GetPayload().GetType() + if t != testpb.PayloadType_COMPRESSABLE { + grpclog.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE) + } + size := len(reply.GetPayload().GetBody()) + if size != int(respSizes[index]) { + grpclog.Fatalf("Got reply body of length %d, want %d", size, respSizes[index]) + } + index++ + respCnt++ + } + if rpcStatus != io.EOF { + grpclog.Fatalf("Failed to finish the server streaming rpc: %v", err) + } + if respCnt != len(respSizes) { + grpclog.Fatalf("Got %d reply, want %d", len(respSizes), respCnt) + } + grpclog.Println("ServerStreaming done") +} + +// DoPingPong performs ping-pong style bi-directional streaming RPC. +func DoPingPong(tc testpb.TestServiceClient) { + stream, err := tc.FullDuplexCall(context.Background()) + if err != nil { + grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) + } + var index int + for index < len(reqSizes) { + respParam := []*testpb.ResponseParameters{ + { + Size: proto.Int32(int32(respSizes[index])), + }, + } + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, reqSizes[index]) + req := &testpb.StreamingOutputCallRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseParameters: respParam, + Payload: pl, + } + if err := stream.Send(req); err != nil { + grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) + } + reply, err := stream.Recv() + if err != nil { + grpclog.Fatalf("%v.Recv() = %v", stream, err) + } + t := reply.GetPayload().GetType() + if t != testpb.PayloadType_COMPRESSABLE { + grpclog.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE) + } + size := len(reply.GetPayload().GetBody()) + if size != int(respSizes[index]) { + grpclog.Fatalf("Got reply body of length %d, want %d", size, respSizes[index]) + } + index++ + } + if err := stream.CloseSend(); err != nil { + grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil) + } + if _, err := stream.Recv(); err != io.EOF { + grpclog.Fatalf("%v failed to complele the ping pong test: %v", stream, err) + } + grpclog.Println("Pingpong done") +} + +// DoEmptyStream sets up a bi-directional streaming with zero message. +func DoEmptyStream(tc testpb.TestServiceClient) { + stream, err := tc.FullDuplexCall(context.Background()) + if err != nil { + grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) + } + if err := stream.CloseSend(); err != nil { + grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil) + } + if _, err := stream.Recv(); err != io.EOF { + grpclog.Fatalf("%v failed to complete the empty stream test: %v", stream, err) + } + grpclog.Println("Emptystream done") +} + +// DoTimeoutOnSleepingServer performs an RPC on a sleep server which causes RPC timeout. +func DoTimeoutOnSleepingServer(tc testpb.TestServiceClient) { + ctx, _ := context.WithTimeout(context.Background(), 1*time.Millisecond) + stream, err := tc.FullDuplexCall(ctx) + if err != nil { + if grpc.Code(err) == codes.DeadlineExceeded { + grpclog.Println("TimeoutOnSleepingServer done") + return + } + grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) + } + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, 27182) + req := &testpb.StreamingOutputCallRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + Payload: pl, + } + if err := stream.Send(req); err != nil { + grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) + } + if _, err := stream.Recv(); grpc.Code(err) != codes.DeadlineExceeded { + grpclog.Fatalf("%v.Recv() = _, %v, want error code %d", stream, err, codes.DeadlineExceeded) + } + grpclog.Println("TimeoutOnSleepingServer done") +} + +// DoComputeEngineCreds performs a unary RPC with compute engine auth. +func DoComputeEngineCreds(tc testpb.TestServiceClient, serviceAccount, oauthScope string) { + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) + req := &testpb.SimpleRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseSize: proto.Int32(int32(largeRespSize)), + Payload: pl, + FillUsername: proto.Bool(true), + FillOauthScope: proto.Bool(true), + } + reply, err := tc.UnaryCall(context.Background(), req) + if err != nil { + grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) + } + user := reply.GetUsername() + scope := reply.GetOauthScope() + if user != serviceAccount { + grpclog.Fatalf("Got user name %q, want %q.", user, serviceAccount) + } + if !strings.Contains(oauthScope, scope) { + grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope) + } + grpclog.Println("ComputeEngineCreds done") +} + +func getServiceAccountJSONKey(keyFile string) []byte { + jsonKey, err := ioutil.ReadFile(keyFile) + if err != nil { + grpclog.Fatalf("Failed to read the service account key file: %v", err) + } + return jsonKey +} + +// DoServiceAccountCreds performs a unary RPC with service account auth. +func DoServiceAccountCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScope string) { + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) + req := &testpb.SimpleRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseSize: proto.Int32(int32(largeRespSize)), + Payload: pl, + FillUsername: proto.Bool(true), + FillOauthScope: proto.Bool(true), + } + reply, err := tc.UnaryCall(context.Background(), req) + if err != nil { + grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) + } + jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile) + user := reply.GetUsername() + scope := reply.GetOauthScope() + if !strings.Contains(string(jsonKey), user) { + grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) + } + if !strings.Contains(oauthScope, scope) { + grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope) + } + grpclog.Println("ServiceAccountCreds done") +} + +// DoJWTTokenCreds performs a unary RPC with JWT token auth. +func DoJWTTokenCreds(tc testpb.TestServiceClient, serviceAccountKeyFile string) { + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) + req := &testpb.SimpleRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseSize: proto.Int32(int32(largeRespSize)), + Payload: pl, + FillUsername: proto.Bool(true), + } + reply, err := tc.UnaryCall(context.Background(), req) + if err != nil { + grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) + } + jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile) + user := reply.GetUsername() + if !strings.Contains(string(jsonKey), user) { + grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) + } + grpclog.Println("JWTtokenCreds done") +} + +// GetToken obtains an OAUTH token from the input. +func GetToken(serviceAccountKeyFile string, oauthScope string) *oauth2.Token { + jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile) + config, err := google.JWTConfigFromJSON(jsonKey, oauthScope) + if err != nil { + grpclog.Fatalf("Failed to get the config: %v", err) + } + token, err := config.TokenSource(context.Background()).Token() + if err != nil { + grpclog.Fatalf("Failed to get the token: %v", err) + } + return token +} + +// DoOauth2TokenCreds performs a unary RPC with OAUTH2 token auth. +func DoOauth2TokenCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScope string) { + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) + req := &testpb.SimpleRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseSize: proto.Int32(int32(largeRespSize)), + Payload: pl, + FillUsername: proto.Bool(true), + FillOauthScope: proto.Bool(true), + } + reply, err := tc.UnaryCall(context.Background(), req) + if err != nil { + grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) + } + jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile) + user := reply.GetUsername() + scope := reply.GetOauthScope() + if !strings.Contains(string(jsonKey), user) { + grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) + } + if !strings.Contains(oauthScope, scope) { + grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope) + } + grpclog.Println("Oauth2TokenCreds done") +} + +// DoPerRPCCreds performs a unary RPC with per RPC OAUTH2 token. +func DoPerRPCCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScope string) { + jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile) + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) + req := &testpb.SimpleRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseSize: proto.Int32(int32(largeRespSize)), + Payload: pl, + FillUsername: proto.Bool(true), + FillOauthScope: proto.Bool(true), + } + token := GetToken(serviceAccountKeyFile, oauthScope) + kv := map[string]string{"authorization": token.TokenType + " " + token.AccessToken} + ctx := metadata.NewContext(context.Background(), metadata.MD{"authorization": []string{kv["authorization"]}}) + reply, err := tc.UnaryCall(ctx, req) + if err != nil { + grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) + } + user := reply.GetUsername() + scope := reply.GetOauthScope() + if !strings.Contains(string(jsonKey), user) { + grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) + } + if !strings.Contains(oauthScope, scope) { + grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope) + } + grpclog.Println("PerRPCCreds done") +} + +var ( + testMetadata = metadata.MD{ + "key1": []string{"value1"}, + "key2": []string{"value2"}, + } +) + +// DoCancelAfterBegin cancels the RPC after metadata has been sent but before payloads are sent. +func DoCancelAfterBegin(tc testpb.TestServiceClient) { + ctx, cancel := context.WithCancel(metadata.NewContext(context.Background(), testMetadata)) + stream, err := tc.StreamingInputCall(ctx) + if err != nil { + grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err) + } + cancel() + _, err = stream.CloseAndRecv() + if grpc.Code(err) != codes.Canceled { + grpclog.Fatalf("%v.CloseAndRecv() got error code %d, want %d", stream, grpc.Code(err), codes.Canceled) + } + grpclog.Println("CancelAfterBegin done") +} + +// DoCancelAfterFirstResponse cancels the RPC after receiving the first message from the server. +func DoCancelAfterFirstResponse(tc testpb.TestServiceClient) { + ctx, cancel := context.WithCancel(context.Background()) + stream, err := tc.FullDuplexCall(ctx) + if err != nil { + grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) + } + respParam := []*testpb.ResponseParameters{ + { + Size: proto.Int32(31415), + }, + } + pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, 27182) + req := &testpb.StreamingOutputCallRequest{ + ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), + ResponseParameters: respParam, + Payload: pl, + } + if err := stream.Send(req); err != nil { + grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) + } + if _, err := stream.Recv(); err != nil { + grpclog.Fatalf("%v.Recv() = %v", stream, err) + } + cancel() + if _, err := stream.Recv(); grpc.Code(err) != codes.Canceled { + grpclog.Fatalf("%v compleled with error code %d, want %d", stream, grpc.Code(err), codes.Canceled) + } + grpclog.Println("CancelAfterFirstResponse done") +} + +type testServer struct { +} + +// NewTestServer creates a test server for test service. +func NewTestServer() testpb.TestServiceServer { + return &testServer{} +} + +func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { + return new(testpb.Empty), nil +} + +func serverNewPayload(t testpb.PayloadType, size int32) (*testpb.Payload, error) { + if size < 0 { + return nil, fmt.Errorf("requested a response with invalid length %d", size) + } + body := make([]byte, size) + switch t { + case testpb.PayloadType_COMPRESSABLE: + case testpb.PayloadType_UNCOMPRESSABLE: + return nil, fmt.Errorf("payloadType UNCOMPRESSABLE is not supported") + default: + return nil, fmt.Errorf("unsupported payload type: %d", t) + } + return &testpb.Payload{ + Type: t.Enum(), + Body: body, + }, nil +} + +func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { + pl, err := serverNewPayload(in.GetResponseType(), in.GetResponseSize()) + if err != nil { + return nil, err + } + return &testpb.SimpleResponse{ + Payload: pl, + }, nil +} + +func (s *testServer) StreamingOutputCall(args *testpb.StreamingOutputCallRequest, stream testpb.TestService_StreamingOutputCallServer) error { + cs := args.GetResponseParameters() + for _, c := range cs { + if us := c.GetIntervalUs(); us > 0 { + time.Sleep(time.Duration(us) * time.Microsecond) + } + pl, err := serverNewPayload(args.GetResponseType(), c.GetSize()) + if err != nil { + return err + } + if err := stream.Send(&testpb.StreamingOutputCallResponse{ + Payload: pl, + }); err != nil { + return err + } + } + return nil +} + +func (s *testServer) StreamingInputCall(stream testpb.TestService_StreamingInputCallServer) error { + var sum int + for { + in, err := stream.Recv() + if err == io.EOF { + return stream.SendAndClose(&testpb.StreamingInputCallResponse{ + AggregatedPayloadSize: proto.Int32(int32(sum)), + }) + } + if err != nil { + return err + } + p := in.GetPayload().GetBody() + sum += len(p) + } +} + +func (s *testServer) FullDuplexCall(stream testpb.TestService_FullDuplexCallServer) error { + for { + in, err := stream.Recv() + if err == io.EOF { + // read done. + return nil + } + if err != nil { + return err + } + cs := in.GetResponseParameters() + for _, c := range cs { + if us := c.GetIntervalUs(); us > 0 { + time.Sleep(time.Duration(us) * time.Microsecond) + } + pl, err := serverNewPayload(in.GetResponseType(), c.GetSize()) + if err != nil { + return err + } + if err := stream.Send(&testpb.StreamingOutputCallResponse{ + Payload: pl, + }); err != nil { + return err + } + } + } +} + +func (s *testServer) HalfDuplexCall(stream testpb.TestService_HalfDuplexCallServer) error { + var msgBuf []*testpb.StreamingOutputCallRequest + for { + in, err := stream.Recv() + if err == io.EOF { + // read done. + break + } + if err != nil { + return err + } + msgBuf = append(msgBuf, in) + } + for _, m := range msgBuf { + cs := m.GetResponseParameters() + for _, c := range cs { + if us := c.GetIntervalUs(); us > 0 { + time.Sleep(time.Duration(us) * time.Microsecond) + } + pl, err := serverNewPayload(m.GetResponseType(), c.GetSize()) + if err != nil { + return err + } + if err := stream.Send(&testpb.StreamingOutputCallResponse{ + Payload: pl, + }); err != nil { + return err + } + } + } + return nil +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/metadata/metadata.go b/Godeps/_workspace/src/google.golang.org/grpc/metadata/metadata.go index 5f26abaeac..58469ddd3f 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/metadata/metadata.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/metadata/metadata.go @@ -46,27 +46,16 @@ const ( binHdrSuffix = "-bin" ) -// grpc-http2 requires ASCII header key and value (more detail can be found in -// "Requests" subsection in go/grpc-http2). -func isASCII(s string) bool { - for _, c := range s { - if c > 127 { - return false - } - } - return true -} - // encodeKeyValue encodes key and value qualified for transmission via gRPC. // Transmitting binary headers violates HTTP/2 spec. // TODO(zhaoq): Maybe check if k is ASCII also. func encodeKeyValue(k, v string) (string, string) { - if isASCII(v) { - return k, v + k = strings.ToLower(k) + if strings.HasSuffix(k, binHdrSuffix) { + val := base64.StdEncoding.EncodeToString([]byte(v)) + v = string(val) } - key := strings.ToLower(k + binHdrSuffix) - val := base64.StdEncoding.EncodeToString([]byte(v)) - return key, string(val) + return k, v } // DecodeKeyValue returns the original key and value corresponding to the @@ -75,12 +64,11 @@ func DecodeKeyValue(k, v string) (string, string, error) { if !strings.HasSuffix(k, binHdrSuffix) { return k, v, nil } - key := k[:len(k)-len(binHdrSuffix)] val, err := base64.StdEncoding.DecodeString(v) if err != nil { return "", "", err } - return key, string(val), nil + return k, string(val), nil } // MD is a mapping from metadata keys to values. Users should use the following diff --git a/Godeps/_workspace/src/google.golang.org/grpc/naming/etcd/etcd.go b/Godeps/_workspace/src/google.golang.org/grpc/naming/etcd/etcd.go deleted file mode 100644 index 915e22717e..0000000000 --- a/Godeps/_workspace/src/google.golang.org/grpc/naming/etcd/etcd.go +++ /dev/null @@ -1,145 +0,0 @@ -package etcd - -import ( - "log" - "sync" - - etcdcl "github.com/coreos/etcd/client" - "golang.org/x/net/context" - "google.golang.org/grpc/naming" -) - -type kv struct { - key, value string -} - -// recvBuffer is an unbounded channel of *kv to record all the pending changes from etcd server. -type recvBuffer struct { - c chan *kv - mu sync.Mutex - stopping bool - backlog []*kv -} - -func newRecvBuffer() *recvBuffer { - b := &recvBuffer{ - c: make(chan *kv, 1), - } - return b -} - -func (b *recvBuffer) put(r *kv) { - b.mu.Lock() - defer b.mu.Unlock() - if b.stopping { - return - } - b.backlog = append(b.backlog, r) - select { - case b.c <- b.backlog[0]: - b.backlog = b.backlog[1:] - default: - } -} - -func (b *recvBuffer) load() { - b.mu.Lock() - defer b.mu.Unlock() - if b.stopping || len(b.backlog) == 0 { - return - } - select { - case b.c <- b.backlog[0]: - b.backlog = b.backlog[1:] - default: - } -} - -func (b *recvBuffer) get() <-chan *kv { - return b.c -} - -// stop terminates the recvBuffer. After it is called, the recvBuffer is not usable any more. -func (b *recvBuffer) stop() { - b.mu.Lock() - b.stopping = true - close(b.c) - b.mu.Unlock() -} - -type etcdNR struct { - kAPI etcdcl.KeysAPI - recv *recvBuffer - ctx context.Context - cancel context.CancelFunc -} - -// NewETCDNR creates an etcd NameResolver. -func NewETCDNR(cfg etcdcl.Config) (naming.Resolver, error) { - c, err := etcdcl.New(cfg) - if err != nil { - return nil, err - } - kAPI := etcdcl.NewKeysAPI(c) - ctx, cancel := context.WithCancel(context.Background()) - return &etcdNR{ - kAPI: kAPI, - recv: newRecvBuffer(), - ctx: ctx, - cancel: cancel, - }, nil -} - -// getNode builds the resulting key-value map starting from node recursively. -func getNode(node *etcdcl.Node, res map[string]string) { - if !node.Dir { - res[node.Key] = node.Value - return - } - for _, val := range node.Nodes { - getNode(val, res) - } -} - -func (nr *etcdNR) Get(target string) map[string]string { - resp, err := nr.kAPI.Get(nr.ctx, target, &etcdcl.GetOptions{Recursive: true, Sort: true}) - if err != nil { - log.Printf("etcdNR.Get(_) stopped: %v", err) - return nil - } - res := make(map[string]string) - getNode(resp.Node, res) - return res -} - -func (nr *etcdNR) Watch(target string) { - watcher := nr.kAPI.Watcher(target, &etcdcl.WatcherOptions{Recursive: true}) - for { - resp, err := watcher.Next(nr.ctx) - if err != nil { - log.Printf("etcdNR.Watch(_) stopped: %v", err) - break - } - if resp.Node.Dir { - continue - } - entry := &kv{key: resp.Node.Key, value: resp.Node.Value} - nr.recv.put(entry) - } -} - -func (nr *etcdNR) GetUpdate() (string, string) { - i := <-nr.recv.get() - nr.recv.load() - if i == nil { - return "", "" - } - // returns key and the corresponding value of the updated kv pair - return i.key, i.value - -} - -func (nr *etcdNR) Stop() { - nr.recv.stop() - nr.cancel() -} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/naming/naming.go b/Godeps/_workspace/src/google.golang.org/grpc/naming/naming.go index a6a319f750..06605607c3 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/naming/naming.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/naming/naming.go @@ -1,13 +1,73 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Package naming defines the naming API and related data structures for gRPC. +// The interface is EXPERIMENTAL and may be suject to change. package naming -// Resolver dose name resolution and watches for the resolution changes. -type Resolver interface { - // Get gets a snapshot of the current name resolution results for target. - Get(target string) map[string]string - // Watch watches for the name resolution changes on target. It blocks until Stop() is invoked. The watch results are obtained via GetUpdate(). - Watch(target string) - // GetUpdate returns a name resolution change when watch is triggered. It blocks until it observes a change. The caller needs to call it again to get the next change. - GetUpdate() (string, string) - // Stop shuts down the NameResolver. - Stop() +// Operation defines the corresponding operations for a name resolution change. +type Operation uint8 + +const ( + // Add indicates a new address is added. + Add Operation = iota + // Delete indicates an exisiting address is deleted. + Delete +) + +// Update defines a name resolution update. Notice that it is not valid having both +// empty string Addr and nil Metadata in an Update. +type Update struct { + // Op indicates the operation of the update. + Op Operation + // Addr is the updated address. It is empty string if there is no address update. + Addr string + // Metadata is the updated metadata. It is nil if there is no metadata update. + // Metadata is not required for a custom naming implementation. + Metadata interface{} +} + +// Resolver creates a Watcher for a target to track its resolution changes. +type Resolver interface { + // Resolve creates a Watcher for target. + Resolve(target string) (Watcher, error) +} + +// Watcher watches for the updates on the specified target. +type Watcher interface { + // Next blocks until an update or error happens. It may return one or more + // updates. The first call should get the full set of the results. + Next() ([]*Update, error) + // Close closes the Watcher. + Close() } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/peer/peer.go b/Godeps/_workspace/src/google.golang.org/grpc/peer/peer.go new file mode 100644 index 0000000000..bfa6205ba9 --- /dev/null +++ b/Godeps/_workspace/src/google.golang.org/grpc/peer/peer.go @@ -0,0 +1,65 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Package peer defines various peer information associated with RPCs and +// corresponding utils. +package peer + +import ( + "net" + + "golang.org/x/net/context" + "google.golang.org/grpc/credentials" +) + +// Peer contains the information of the peer for an RPC. +type Peer struct { + // Addr is the peer address. + Addr net.Addr + // AuthInfo is the authentication information of the transport. + // It is nil if there is no transport security being used. + AuthInfo credentials.AuthInfo +} + +type peerKey struct{} + +// NewContext creates a new context with peer information attached. +func NewContext(ctx context.Context, p *Peer) context.Context { + return context.WithValue(ctx, peerKey{}, p) +} + +// FromContext returns the peer information in ctx if it exists. +func FromContext(ctx context.Context) (p *Peer, ok bool) { + p, ok = ctx.Value(peerKey{}).(*Peer) + return +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/picker.go b/Godeps/_workspace/src/google.golang.org/grpc/picker.go new file mode 100644 index 0000000000..50f315b44f --- /dev/null +++ b/Godeps/_workspace/src/google.golang.org/grpc/picker.go @@ -0,0 +1,243 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package grpc + +import ( + "container/list" + "fmt" + "sync" + + "golang.org/x/net/context" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/naming" + "google.golang.org/grpc/transport" +) + +// Picker picks a Conn for RPC requests. +// This is EXPERIMENTAL and please do not implement your own Picker for now. +type Picker interface { + // Init does initial processing for the Picker, e.g., initiate some connections. + Init(cc *ClientConn) error + // Pick blocks until either a transport.ClientTransport is ready for the upcoming RPC + // or some error happens. + Pick(ctx context.Context) (transport.ClientTransport, error) + // PickAddr picks a peer address for connecting. This will be called repeated for + // connecting/reconnecting. + PickAddr() (string, error) + // State returns the connectivity state of the underlying connections. + State() (ConnectivityState, error) + // WaitForStateChange blocks until the state changes to something other than + // the sourceState. It returns the new state or error. + WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) + // Close closes all the Conn's owned by this Picker. + Close() error +} + +// unicastPicker is the default Picker which is used when there is no custom Picker +// specified by users. It always picks the same Conn. +type unicastPicker struct { + target string + conn *Conn +} + +func (p *unicastPicker) Init(cc *ClientConn) error { + c, err := NewConn(cc) + if err != nil { + return err + } + p.conn = c + return nil +} + +func (p *unicastPicker) Pick(ctx context.Context) (transport.ClientTransport, error) { + return p.conn.Wait(ctx) +} + +func (p *unicastPicker) PickAddr() (string, error) { + return p.target, nil +} + +func (p *unicastPicker) State() (ConnectivityState, error) { + return p.conn.State(), nil +} + +func (p *unicastPicker) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { + return p.conn.WaitForStateChange(ctx, sourceState) +} + +func (p *unicastPicker) Close() error { + if p.conn != nil { + return p.conn.Close() + } + return nil +} + +// unicastNamingPicker picks an address from a name resolver to set up the connection. +type unicastNamingPicker struct { + cc *ClientConn + resolver naming.Resolver + watcher naming.Watcher + mu sync.Mutex + // The list of the addresses are obtained from watcher. + addrs *list.List + // It tracks the current picked addr by PickAddr(). The next PickAddr may + // push it forward on addrs. + pickedAddr *list.Element + conn *Conn +} + +// NewUnicastNamingPicker creates a Picker to pick addresses from a name resolver +// to connect. +func NewUnicastNamingPicker(r naming.Resolver) Picker { + return &unicastNamingPicker{ + resolver: r, + addrs: list.New(), + } +} + +type addrInfo struct { + addr string + // Set to true if this addrInfo needs to be deleted in the next PickAddrr() call. + deleting bool +} + +// processUpdates calls Watcher.Next() once and processes the obtained updates. +func (p *unicastNamingPicker) processUpdates() error { + updates, err := p.watcher.Next() + if err != nil { + return err + } + for _, update := range updates { + switch update.Op { + case naming.Add: + p.mu.Lock() + p.addrs.PushBack(&addrInfo{ + addr: update.Addr, + }) + p.mu.Unlock() + // Initial connection setup + if p.conn == nil { + conn, err := NewConn(p.cc) + if err != nil { + return err + } + p.conn = conn + } + case naming.Delete: + p.mu.Lock() + for e := p.addrs.Front(); e != nil; e = e.Next() { + if update.Addr == e.Value.(*addrInfo).addr { + if e == p.pickedAddr { + // Do not remove the element now if it is the current picked + // one. We leave the deletion to the next PickAddr() call. + e.Value.(*addrInfo).deleting = true + // Notify Conn to close it. All the live RPCs on this connection + // will be aborted. + p.conn.NotifyReset() + } else { + p.addrs.Remove(e) + } + } + } + p.mu.Unlock() + default: + grpclog.Println("Unknown update.Op ", update.Op) + } + } + return nil +} + +// monitor runs in a standalone goroutine to keep watching name resolution updates until the watcher +// is closed. +func (p *unicastNamingPicker) monitor() { + for { + if err := p.processUpdates(); err != nil { + return + } + } +} + +func (p *unicastNamingPicker) Init(cc *ClientConn) error { + w, err := p.resolver.Resolve(cc.target) + if err != nil { + return err + } + p.watcher = w + p.cc = cc + // Get the initial name resolution. + if err := p.processUpdates(); err != nil { + return err + } + go p.monitor() + return nil +} + +func (p *unicastNamingPicker) Pick(ctx context.Context) (transport.ClientTransport, error) { + return p.conn.Wait(ctx) +} + +func (p *unicastNamingPicker) PickAddr() (string, error) { + p.mu.Lock() + defer p.mu.Unlock() + if p.pickedAddr == nil { + p.pickedAddr = p.addrs.Front() + } else { + pa := p.pickedAddr + p.pickedAddr = pa.Next() + if pa.Value.(*addrInfo).deleting { + p.addrs.Remove(pa) + } + if p.pickedAddr == nil { + p.pickedAddr = p.addrs.Front() + } + } + if p.pickedAddr == nil { + return "", fmt.Errorf("there is no address available to pick") + } + return p.pickedAddr.Value.(*addrInfo).addr, nil +} + +func (p *unicastNamingPicker) State() (ConnectivityState, error) { + return 0, fmt.Errorf("State() is not supported for unicastNamingPicker") +} + +func (p *unicastNamingPicker) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { + return 0, fmt.Errorf("WaitForStateChange is not supported for unicastNamingPciker") +} + +func (p *unicastNamingPicker) Close() error { + p.watcher.Close() + p.conn.Close() + return nil +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/rpc_util.go b/Godeps/_workspace/src/google.golang.org/grpc/rpc_util.go index a0f0b48bb4..e98ddbcdc5 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/rpc_util.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/rpc_util.go @@ -35,9 +35,12 @@ package grpc import ( "bytes" + "compress/gzip" "encoding/binary" "fmt" "io" + "io/ioutil" + "math" "math/rand" "os" "time" @@ -75,6 +78,71 @@ func (protoCodec) String() string { return "proto" } +// Compressor defines the interface gRPC uses to compress a message. +type Compressor interface { + // Do compresses p into w. + Do(w io.Writer, p []byte) error + // Type returns the compression algorithm the Compressor uses. + Type() string +} + +// NewGZIPCompressor creates a Compressor based on GZIP. +func NewGZIPCompressor() Compressor { + return &gzipCompressor{} +} + +type gzipCompressor struct { +} + +func (c *gzipCompressor) Do(w io.Writer, p []byte) error { + z := gzip.NewWriter(w) + if _, err := z.Write(p); err != nil { + return err + } + return z.Close() +} + +func (c *gzipCompressor) Type() string { + return "gzip" +} + +// Decompressor defines the interface gRPC uses to decompress a message. +type Decompressor interface { + // Do reads the data from r and uncompress them. + Do(r io.Reader) ([]byte, error) + // Type returns the compression algorithm the Decompressor uses. + Type() string +} + +type gzipDecompressor struct { +} + +// NewGZIPDecompressor creates a Decompressor based on GZIP. +func NewGZIPDecompressor() Decompressor { + return &gzipDecompressor{} +} + +func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) { + z, err := gzip.NewReader(r) + if err != nil { + return nil, err + } + defer z.Close() + return ioutil.ReadAll(z) +} + +func (d *gzipDecompressor) Type() string { + return "gzip" +} + +// callInfo contains all related configuration and information about an RPC. +type callInfo struct { + failFast bool + headerMD metadata.MD + trailerMD metadata.MD + traceInfo traceInfo // in trace.go +} + // CallOption configures a Call before it starts or extracts information from // a Call after it completes. type CallOption interface { @@ -118,8 +186,7 @@ type payloadFormat uint8 const ( compressionNone payloadFormat = iota // no compression - compressionFlate - // More formats + compressionMade ) // parser reads complelete gRPC messages from the underlying reader. @@ -127,42 +194,40 @@ type parser struct { s io.Reader } -// msgFixedHeader defines the header of a gRPC message (go/grpc-wirefmt). -type msgFixedHeader struct { - T payloadFormat - Length uint32 -} - // recvMsg is to read a complete gRPC message from the stream. It is blocking if // the message has not been complete yet. It returns the message and its type, // EOF is returned with nil msg and 0 pf if the entire stream is done. Other // non-nil error is returned if something is wrong on reading. func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) { - var hdr msgFixedHeader - if err := binary.Read(p.s, binary.BigEndian, &hdr); err != nil { + // The header of a gRPC message. Find more detail + // at http://www.grpc.io/docs/guides/wire.html. + var buf [5]byte + + if _, err := io.ReadFull(p.s, buf[:]); err != nil { return 0, nil, err } - if hdr.Length == 0 { - return hdr.T, nil, nil + + pf = payloadFormat(buf[0]) + length := binary.BigEndian.Uint32(buf[1:]) + + if length == 0 { + return pf, nil, nil } - msg = make([]byte, int(hdr.Length)) + msg = make([]byte, int(length)) if _, err := io.ReadFull(p.s, msg); err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF } return 0, nil, err } - return hdr.T, msg, nil + return pf, msg, nil } // encode serializes msg and prepends the message header. If msg is nil, it // generates the message header of 0 message length. -func encode(c Codec, msg interface{}, pf payloadFormat) ([]byte, error) { - var buf bytes.Buffer - // Write message fixed header. - buf.WriteByte(uint8(pf)) +func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte, error) { var b []byte - var length uint32 + var length uint if msg != nil { var err error // TODO(zhaoq): optimize to reduce memory alloc and copying. @@ -170,27 +235,71 @@ func encode(c Codec, msg interface{}, pf payloadFormat) ([]byte, error) { if err != nil { return nil, err } - length = uint32(len(b)) + if cp != nil { + if err := cp.Do(cbuf, b); err != nil { + return nil, err + } + b = cbuf.Bytes() + } + length = uint(len(b)) } - var szHdr [4]byte - binary.BigEndian.PutUint32(szHdr[:], length) - buf.Write(szHdr[:]) - buf.Write(b) - return buf.Bytes(), nil + if length > math.MaxUint32 { + return nil, Errorf(codes.InvalidArgument, "grpc: message too large (%d bytes)", length) + } + + const ( + payloadLen = 1 + sizeLen = 4 + ) + + var buf = make([]byte, payloadLen+sizeLen+len(b)) + + // Write payload format + if cp == nil { + buf[0] = byte(compressionNone) + } else { + buf[0] = byte(compressionMade) + } + // Write length of b into buf + binary.BigEndian.PutUint32(buf[1:], uint32(length)) + // Copy encoded msg to buf + copy(buf[5:], b) + + return buf, nil } -func recv(p *parser, c Codec, m interface{}) error { +func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) error { + switch pf { + case compressionNone: + case compressionMade: + if recvCompress == "" { + return transport.StreamErrorf(codes.InvalidArgument, "grpc: received unexpected payload format %d", pf) + } + if dc == nil || recvCompress != dc.Type() { + return transport.StreamErrorf(codes.InvalidArgument, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) + } + default: + return transport.StreamErrorf(codes.InvalidArgument, "grpc: received unexpected payload format %d", pf) + } + return nil +} + +func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}) error { pf, d, err := p.recvMsg() if err != nil { return err } - switch pf { - case compressionNone: - if err := c.Unmarshal(d, m); err != nil { - return Errorf(codes.Internal, "grpc: %v", err) + if err := checkRecvPayload(pf, s.RecvCompress(), dc); err != nil { + return err + } + if pf == compressionMade { + d, err = dc.Do(bytes.NewReader(d)) + if err != nil { + return transport.StreamErrorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } - default: - return Errorf(codes.Internal, "gprc: compression is not supported yet.") + } + if err := c.Unmarshal(d, m); err != nil { + return transport.StreamErrorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err) } return nil } @@ -217,6 +326,18 @@ func Code(err error) codes.Code { return codes.Unknown } +// ErrorDesc returns the error description of err if it was produced by the rpc system. +// Otherwise, it returns err.Error() or empty string when err is nil. +func ErrorDesc(err error) string { + if err == nil { + return "" + } + if e, ok := err.(rpcError); ok { + return e.desc + } + return err.Error() +} + // Errorf returns an error containing an error code and a description; // Errorf returns nil if c is OK. func Errorf(c codes.Code, format string, a ...interface{}) error { @@ -232,6 +353,8 @@ func Errorf(c codes.Code, format string, a ...interface{}) error { // toRPCErr converts an error into a rpcError. func toRPCErr(err error) error { switch e := err.(type) { + case rpcError: + return err case transport.StreamError: return rpcError{ code: e.Code, diff --git a/Godeps/_workspace/src/google.golang.org/grpc/server.go b/Godeps/_workspace/src/google.golang.org/grpc/server.go index feb2988751..1c42b6eff2 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/server.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/server.go @@ -34,13 +34,16 @@ package grpc import ( + "bytes" "errors" "fmt" "io" "net" "reflect" + "runtime" "strings" "sync" + "time" "golang.org/x/net/context" "golang.org/x/net/trace" @@ -51,7 +54,7 @@ import ( "google.golang.org/grpc/transport" ) -type methodHandler func(srv interface{}, ctx context.Context, codec Codec, buf []byte) (interface{}, error) +type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) // MethodDesc represents an RPC service's method specification. type MethodDesc struct { @@ -79,16 +82,19 @@ type service struct { // Server is a gRPC server to serve RPC requests. type Server struct { - opts options - mu sync.Mutex - lis map[net.Listener]bool - conns map[transport.ServerTransport]bool - m map[string]*service // service name -> service info + opts options + mu sync.Mutex + lis map[net.Listener]bool + conns map[transport.ServerTransport]bool + m map[string]*service // service name -> service info + events trace.EventLog } type options struct { creds credentials.Credentials codec Codec + cp Compressor + dc Decompressor maxConcurrentStreams uint32 } @@ -102,6 +108,18 @@ func CustomCodec(codec Codec) ServerOption { } } +func RPCCompressor(cp Compressor) ServerOption { + return func(o *options) { + o.cp = cp + } +} + +func RPCDecompressor(dc Decompressor) ServerOption { + return func(o *options) { + o.dc = dc + } +} + // MaxConcurrentStreams returns a ServerOption that will apply a limit on the number // of concurrent streams to each ServerTransport. func MaxConcurrentStreams(n uint32) ServerOption { @@ -128,12 +146,33 @@ func NewServer(opt ...ServerOption) *Server { // Set the default codec. opts.codec = protoCodec{} } - return &Server{ + s := &Server{ lis: make(map[net.Listener]bool), opts: opts, conns: make(map[transport.ServerTransport]bool), m: make(map[string]*service), } + if EnableTracing { + _, file, line, _ := runtime.Caller(1) + s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) + } + return s +} + +// printf records an event in s's event log, unless s has been stopped. +// REQUIRES s.mu is held. +func (s *Server) printf(format string, a ...interface{}) { + if s.events != nil { + s.events.Printf(format, a...) + } +} + +// errorf records an error in s's event log, unless s has been stopped. +// REQUIRES s.mu is held. +func (s *Server) errorf(format string, a ...interface{}) { + if s.events != nil { + s.events.Errorf(format, a...) + } } // RegisterService register a service and its implementation to the gRPC @@ -151,6 +190,7 @@ func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { func (s *Server) register(sd *ServiceDesc, ss interface{}) { s.mu.Lock() defer s.mu.Unlock() + s.printf("RegisterService(%q)", sd.ServiceName) if _, ok := s.m[sd.ServiceName]; ok { grpclog.Fatalf("grpc: Server.RegisterService found duplicate service registration for %q", sd.ServiceName) } @@ -182,6 +222,7 @@ var ( // Service returns when lis.Accept fails. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() + s.printf("serving") if s.lis == nil { s.mu.Unlock() return ErrServerStopped @@ -197,15 +238,23 @@ func (s *Server) Serve(lis net.Listener) error { for { c, err := lis.Accept() if err != nil { + s.mu.Lock() + s.printf("done serving; Accept = %v", err) + s.mu.Unlock() return err } var authInfo credentials.AuthInfo if creds, ok := s.opts.creds.(credentials.TransportAuthenticator); ok { - c, authInfo, err = creds.ServerHandshake(c) + var conn net.Conn + conn, authInfo, err = creds.ServerHandshake(c) if err != nil { + s.mu.Lock() + s.errorf("ServerHandshake(%q) failed: %v", c.RemoteAddr(), err) + s.mu.Unlock() grpclog.Println("grpc: Server.Serve failed to complete security handshake.") continue } + c = conn } s.mu.Lock() if s.conns == nil { @@ -213,29 +262,85 @@ func (s *Server) Serve(lis net.Listener) error { c.Close() return nil } - st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) - if err != nil { - s.mu.Unlock() - c.Close() - grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err) - continue - } - s.conns[st] = true s.mu.Unlock() - go func() { - st.HandleStreams(func(stream *transport.Stream) { - s.handleStream(st, stream) - }) - s.mu.Lock() - delete(s.conns, st) - s.mu.Unlock() - }() + go s.serveNewHTTP2Transport(c, authInfo) } } -func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, pf payloadFormat, opts *transport.Options) error { - p, err := encode(s.opts.codec, msg, pf) +func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { + st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) + if err != nil { + s.mu.Lock() + s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) + s.mu.Unlock() + c.Close() + grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err) + return + } + if !s.addConn(st) { + c.Close() + return + } + s.serveStreams(st) +} + +func (s *Server) serveStreams(st transport.ServerTransport) { + defer s.removeConn(st) + defer st.Close() + var wg sync.WaitGroup + st.HandleStreams(func(stream *transport.Stream) { + wg.Add(1) + go func() { + defer wg.Done() + s.handleStream(st, stream, s.traceInfo(st, stream)) + }() + }) + wg.Wait() +} + +// traceInfo returns a traceInfo and associates it with stream, if tracing is enabled. +// If tracing is not enabled, it returns nil. +func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) { + if !EnableTracing { + return nil + } + trInfo = &traceInfo{ + tr: trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()), + } + trInfo.firstLine.client = false + trInfo.firstLine.remoteAddr = st.RemoteAddr() + stream.TraceContext(trInfo.tr) + if dl, ok := stream.Context().Deadline(); ok { + trInfo.firstLine.deadline = dl.Sub(time.Now()) + } + return trInfo +} + +func (s *Server) addConn(st transport.ServerTransport) bool { + s.mu.Lock() + defer s.mu.Unlock() + if s.conns == nil { + return false + } + s.conns[st] = true + return true +} + +func (s *Server) removeConn(st transport.ServerTransport) { + s.mu.Lock() + defer s.mu.Unlock() + if s.conns != nil { + delete(s.conns, st) + } +} + +func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options) error { + var cbuf *bytes.Buffer + if cp != nil { + cbuf = new(bytes.Buffer) + } + p, err := encode(s.opts.codec, msg, cp, cbuf) if err != nil { // This typically indicates a fatal issue (e.g., memory // corruption or hardware faults) the application program @@ -249,17 +354,15 @@ func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Str return t.Write(stream, p, opts) } -func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc) (err error) { - var traceInfo traceInfo - if EnableTracing { - traceInfo.tr = trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) - defer traceInfo.tr.Finish() - traceInfo.firstLine.client = false - traceInfo.tr.LazyLog(&traceInfo.firstLine, false) +func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc, trInfo *traceInfo) (err error) { + if trInfo != nil { + defer trInfo.tr.Finish() + trInfo.firstLine.client = false + trInfo.tr.LazyLog(&trInfo.firstLine, false) defer func() { if err != nil && err != io.EOF { - traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - traceInfo.tr.SetError() + trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.SetError() } }() } @@ -276,82 +379,124 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. // Nothing to do here. case transport.StreamError: if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) } default: panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", err, err)) } return err } - if traceInfo.tr != nil { - traceInfo.tr.LazyLog(&payload{sent: false, msg: req}, true) - } - switch pf { - case compressionNone: - statusCode := codes.OK - statusDesc := "" - reply, appErr := md.Handler(srv.server, stream.Context(), s.opts.codec, req) - if appErr != nil { - if err, ok := appErr.(rpcError); ok { - statusCode = err.code - statusDesc = err.desc - } else { - statusCode = convertCode(appErr) - statusDesc = appErr.Error() + + if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil { + switch err := err.(type) { + case transport.StreamError: + if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) } - if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) + default: + if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + } + + } + return err + } + statusCode := codes.OK + statusDesc := "" + df := func(v interface{}) error { + if pf == compressionMade { + var err error + req, err = s.opts.dc.Do(bytes.NewReader(req)) + if err != nil { + if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + } return err } - return nil } - opts := &transport.Options{ - Last: true, - Delay: false, - } - if err := s.sendResponse(t, stream, reply, compressionNone, opts); err != nil { - switch err := err.(type) { - case transport.ConnectionError: - // Nothing to do here. - case transport.StreamError: - statusCode = err.Code - statusDesc = err.Desc - default: - statusCode = codes.Unknown - statusDesc = err.Error() - } + if err := s.opts.codec.Unmarshal(req, v); err != nil { return err } - if traceInfo.tr != nil { - traceInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) + if trInfo != nil { + trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) } - return t.WriteStatus(stream, statusCode, statusDesc) - default: - panic(fmt.Sprintf("payload format to be supported: %d", pf)) + return nil } + reply, appErr := md.Handler(srv.server, stream.Context(), df) + if appErr != nil { + if err, ok := appErr.(rpcError); ok { + statusCode = err.code + statusDesc = err.desc + } else { + statusCode = convertCode(appErr) + statusDesc = appErr.Error() + } + if trInfo != nil && statusCode != codes.OK { + trInfo.tr.LazyLog(stringer(statusDesc), true) + trInfo.tr.SetError() + } + if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) + return err + } + return nil + } + if trInfo != nil { + trInfo.tr.LazyLog(stringer("OK"), false) + } + opts := &transport.Options{ + Last: true, + Delay: false, + } + if s.opts.cp != nil { + stream.SetSendCompress(s.opts.cp.Type()) + } + if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil { + switch err := err.(type) { + case transport.ConnectionError: + // Nothing to do here. + case transport.StreamError: + statusCode = err.Code + statusDesc = err.Desc + default: + statusCode = codes.Unknown + statusDesc = err.Error() + } + return err + } + if trInfo != nil { + trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) + } + return t.WriteStatus(stream, statusCode, statusDesc) } } -func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc) (err error) { - ss := &serverStream{ - t: t, - s: stream, - p: &parser{s: stream}, - codec: s.opts.codec, - tracing: EnableTracing, +func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) { + if s.opts.cp != nil { + stream.SetSendCompress(s.opts.cp.Type()) } - if ss.tracing { - ss.traceInfo.tr = trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) - ss.traceInfo.firstLine.client = false - ss.traceInfo.tr.LazyLog(&ss.traceInfo.firstLine, false) + ss := &serverStream{ + t: t, + s: stream, + p: &parser{s: stream}, + codec: s.opts.codec, + cp: s.opts.cp, + dc: s.opts.dc, + trInfo: trInfo, + } + if ss.cp != nil { + ss.cbuf = new(bytes.Buffer) + } + if trInfo != nil { + trInfo.tr.LazyLog(&trInfo.firstLine, false) defer func() { ss.mu.Lock() if err != nil && err != io.EOF { - ss.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - ss.traceInfo.tr.SetError() + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.SetError() } - ss.traceInfo.tr.Finish() - ss.traceInfo.tr = nil + ss.trInfo.tr.Finish() + ss.trInfo.tr = nil ss.mu.Unlock() }() } @@ -359,48 +504,94 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp if err, ok := appErr.(rpcError); ok { ss.statusCode = err.code ss.statusDesc = err.desc + } else if err, ok := appErr.(transport.StreamError); ok { + ss.statusCode = err.Code + ss.statusDesc = err.Desc } else { ss.statusCode = convertCode(appErr) ss.statusDesc = appErr.Error() } } + if trInfo != nil { + ss.mu.Lock() + if ss.statusCode != codes.OK { + ss.trInfo.tr.LazyLog(stringer(ss.statusDesc), true) + ss.trInfo.tr.SetError() + } else { + ss.trInfo.tr.LazyLog(stringer("OK"), false) + } + ss.mu.Unlock() + } return t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc) } -func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream) { +func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) { sm := stream.Method() if sm != "" && sm[0] == '/' { sm = sm[1:] } pos := strings.LastIndex(sm, "/") if pos == -1 { + if trInfo != nil { + trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true) + trInfo.tr.SetError() + } if err := t.WriteStatus(stream, codes.InvalidArgument, fmt.Sprintf("malformed method name: %q", stream.Method())); err != nil { + if trInfo != nil { + trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.SetError() + } grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err) } + if trInfo != nil { + trInfo.tr.Finish() + } return } service := sm[:pos] method := sm[pos+1:] srv, ok := s.m[service] if !ok { + if trInfo != nil { + trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true) + trInfo.tr.SetError() + } if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown service %v", service)); err != nil { + if trInfo != nil { + trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.SetError() + } grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err) } + if trInfo != nil { + trInfo.tr.Finish() + } return } // Unary RPC or Streaming RPC? if md, ok := srv.md[method]; ok { - s.processUnaryRPC(t, stream, srv, md) + s.processUnaryRPC(t, stream, srv, md, trInfo) return } if sd, ok := srv.sd[method]; ok { - s.processStreamingRPC(t, stream, srv, sd) + s.processStreamingRPC(t, stream, srv, sd, trInfo) return } + if trInfo != nil { + trInfo.tr.LazyLog(&fmtStringer{"Unknown method %v", []interface{}{method}}, true) + trInfo.tr.SetError() + } if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown method %v", method)); err != nil { + if trInfo != nil { + trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.SetError() + } grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err) } + if trInfo != nil { + trInfo.tr.Finish() + } } // Stop stops the gRPC server. Once Stop returns, the server stops accepting @@ -418,6 +609,12 @@ func (s *Server) Stop() { for c := range cs { c.Close() } + s.mu.Lock() + if s.events != nil { + s.events.Finish() + s.events = nil + } + s.mu.Unlock() } // TestingCloseConns closes all exiting transports but keeps s.lis accepting new diff --git a/Godeps/_workspace/src/google.golang.org/grpc/stream.go b/Godeps/_workspace/src/google.golang.org/grpc/stream.go index 5c99bffc63..4974d8a82a 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/stream.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/stream.go @@ -34,6 +34,7 @@ package grpc import ( + "bytes" "errors" "io" "sync" @@ -96,35 +97,63 @@ type ClientStream interface { // NewClientStream creates a new Stream for the client side. This is called // by generated code. func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) { + var ( + t transport.ClientTransport + err error + ) + t, err = cc.dopts.picker.Pick(ctx) + if err != nil { + return nil, toRPCErr(err) + } // TODO(zhaoq): CallOption is omitted. Add support when it is needed. callHdr := &transport.CallHdr{ Host: cc.authority, Method: method, + Flush: desc.ServerStreams&&desc.ClientStreams, + } + if cc.dopts.cp != nil { + callHdr.SendCompress = cc.dopts.cp.Type() } cs := &clientStream{ desc: desc, codec: cc.dopts.codec, + cp: cc.dopts.cp, + dc: cc.dopts.dc, tracing: EnableTracing, } - if cs.tracing { - cs.traceInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method) - cs.traceInfo.firstLine.client = true - if deadline, ok := ctx.Deadline(); ok { - cs.traceInfo.firstLine.deadline = deadline.Sub(time.Now()) - } - cs.traceInfo.tr.LazyLog(&cs.traceInfo.firstLine, false) + if cc.dopts.cp != nil { + callHdr.SendCompress = cc.dopts.cp.Type() + cs.cbuf = new(bytes.Buffer) } - t, _, err := cc.wait(ctx, 0) - if err != nil { - return nil, toRPCErr(err) + if cs.tracing { + cs.trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method) + cs.trInfo.firstLine.client = true + if deadline, ok := ctx.Deadline(); ok { + cs.trInfo.firstLine.deadline = deadline.Sub(time.Now()) + } + cs.trInfo.tr.LazyLog(&cs.trInfo.firstLine, false) + ctx = trace.NewContext(ctx, cs.trInfo.tr) } s, err := t.NewStream(ctx, callHdr) if err != nil { + cs.finish(err) return nil, toRPCErr(err) } cs.t = t cs.s = s cs.p = &parser{s: s} + // Listen on ctx.Done() to detect cancellation when there is no pending + // I/O operations on this stream. + go func() { + select { + case <-t.Error(): + // Incur transport error, simply exit. + case <-s.Context().Done(): + err := s.Context().Err() + cs.finish(err) + cs.closeTransportStream(transport.ContextErr(err)) + } + }() return cs, nil } @@ -135,13 +164,17 @@ type clientStream struct { p *parser desc *StreamDesc codec Codec + cp Compressor + cbuf *bytes.Buffer + dc Decompressor tracing bool // set to EnableTracing when the clientStream is created. - mu sync.Mutex // protects traceInfo - // traceInfo.tr is set when the clientStream is created (if EnableTracing is true), + mu sync.Mutex + closed bool + // trInfo.tr is set when the clientStream is created (if EnableTracing is true), // and is set to nil when the clientStream's finish method is called. - traceInfo traceInfo + trInfo traceInfo } func (cs *clientStream) Context() context.Context { @@ -152,7 +185,7 @@ func (cs *clientStream) Header() (metadata.MD, error) { m, err := cs.s.Header() if err != nil { if _, ok := err.(transport.ConnectionError); !ok { - cs.t.CloseStream(cs.s, err) + cs.closeTransportStream(err) } } return m, err @@ -165,8 +198,8 @@ func (cs *clientStream) Trailer() metadata.MD { func (cs *clientStream) SendMsg(m interface{}) (err error) { if cs.tracing { cs.mu.Lock() - if cs.traceInfo.tr != nil { - cs.traceInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) + if cs.trInfo.tr != nil { + cs.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) } cs.mu.Unlock() } @@ -175,11 +208,16 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { return } if _, ok := err.(transport.ConnectionError); !ok { - cs.t.CloseStream(cs.s, err) + cs.closeTransportStream(err) } err = toRPCErr(err) }() - out, err := encode(cs.codec, m, compressionNone) + out, err := encode(cs.codec, m, cs.cp, cs.cbuf) + defer func() { + if cs.cbuf != nil { + cs.cbuf.Reset() + } + }() if err != nil { return transport.StreamErrorf(codes.Internal, "grpc: %v", err) } @@ -187,7 +225,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } func (cs *clientStream) RecvMsg(m interface{}) (err error) { - err = recv(cs.p, cs.codec, m) + err = recv(cs.p, cs.codec, cs.s, cs.dc, m) defer func() { // err != nil indicates the termination of the stream. if err != nil { @@ -197,8 +235,8 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { if err == nil { if cs.tracing { cs.mu.Lock() - if cs.traceInfo.tr != nil { - cs.traceInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) + if cs.trInfo.tr != nil { + cs.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) } cs.mu.Unlock() } @@ -206,8 +244,8 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { return } // Special handling for client streaming rpc. - err = recv(cs.p, cs.codec, m) - cs.t.CloseStream(cs.s, err) + err = recv(cs.p, cs.codec, cs.s, cs.dc, m) + cs.closeTransportStream(err) if err == nil { return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) } @@ -220,7 +258,7 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { return toRPCErr(err) } if _, ok := err.(transport.ConnectionError); !ok { - cs.t.CloseStream(cs.s, err) + cs.closeTransportStream(err) } if err == io.EOF { if cs.s.StatusCode() == codes.OK { @@ -238,27 +276,38 @@ func (cs *clientStream) CloseSend() (err error) { return } if _, ok := err.(transport.ConnectionError); !ok { - cs.t.CloseStream(cs.s, err) + cs.closeTransportStream(err) } err = toRPCErr(err) return } +func (cs *clientStream) closeTransportStream(err error) { + cs.mu.Lock() + if cs.closed { + cs.mu.Unlock() + return + } + cs.closed = true + cs.mu.Unlock() + cs.t.CloseStream(cs.s, err) +} + func (cs *clientStream) finish(err error) { if !cs.tracing { return } cs.mu.Lock() defer cs.mu.Unlock() - if cs.traceInfo.tr != nil { + if cs.trInfo.tr != nil { if err == nil || err == io.EOF { - cs.traceInfo.tr.LazyPrintf("RPC: [OK]") + cs.trInfo.tr.LazyPrintf("RPC: [OK]") } else { - cs.traceInfo.tr.LazyPrintf("RPC: [%v]", err) - cs.traceInfo.tr.SetError() + cs.trInfo.tr.LazyPrintf("RPC: [%v]", err) + cs.trInfo.tr.SetError() } - cs.traceInfo.tr.Finish() - cs.traceInfo.tr = nil + cs.trInfo.tr.Finish() + cs.trInfo.tr = nil } } @@ -280,15 +329,14 @@ type serverStream struct { s *transport.Stream p *parser codec Codec + cp Compressor + dc Decompressor + cbuf *bytes.Buffer statusCode codes.Code statusDesc string + trInfo *traceInfo - tracing bool // set to EnableTracing when the serverStream is created. - - mu sync.Mutex // protects traceInfo - // traceInfo.tr is set when the serverStream is created (if EnableTracing is true), - // and is set to nil when the serverStream's finish method is called. - traceInfo traceInfo + mu sync.Mutex // protects trInfo.tr after the service handler runs. } func (ss *serverStream) Context() context.Context { @@ -309,19 +357,25 @@ func (ss *serverStream) SetTrailer(md metadata.MD) { func (ss *serverStream) SendMsg(m interface{}) (err error) { defer func() { - if ss.tracing { + if ss.trInfo != nil { ss.mu.Lock() - if err == nil { - ss.traceInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) - } else { - ss.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - ss.traceInfo.tr.SetError() + if ss.trInfo.tr != nil { + if err == nil { + ss.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) + } else { + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.SetError() + } } - ss.mu.Unlock() } }() - out, err := encode(ss.codec, m, compressionNone) + out, err := encode(ss.codec, m, ss.cp, ss.cbuf) + defer func() { + if ss.cbuf != nil { + ss.cbuf.Reset() + } + }() if err != nil { err = transport.StreamErrorf(codes.Internal, "grpc: %v", err) return err @@ -331,16 +385,18 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { func (ss *serverStream) RecvMsg(m interface{}) (err error) { defer func() { - if ss.tracing { + if ss.trInfo != nil { ss.mu.Lock() - if err == nil { - ss.traceInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) - } else if err != io.EOF { - ss.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - ss.traceInfo.tr.SetError() + if ss.trInfo.tr != nil { + if err == nil { + ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) + } else if err != io.EOF { + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.SetError() + } } ss.mu.Unlock() } }() - return recv(ss.p, ss.codec, m) + return recv(ss.p, ss.codec, ss.s, ss.dc, m) } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/test/codec_perf/perf.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/test/codec_perf/perf.pb.go index 5f72c5570e..14fae12b81 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/test/codec_perf/perf.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/test/codec_perf/perf.pb.go @@ -14,12 +14,18 @@ It has these top-level messages: package codec_perf 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. +const _ = proto.ProtoPackageIsVersion1 + // Buffer is a message that contains a body of bytes that is used to exercise // encoding and decoding overheads. type Buffer struct { @@ -27,9 +33,10 @@ type Buffer struct { XXX_unrecognized []byte `json:"-"` } -func (m *Buffer) Reset() { *m = Buffer{} } -func (m *Buffer) String() string { return proto.CompactTextString(m) } -func (*Buffer) ProtoMessage() {} +func (m *Buffer) Reset() { *m = Buffer{} } +func (m *Buffer) String() string { return proto.CompactTextString(m) } +func (*Buffer) ProtoMessage() {} +func (*Buffer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (m *Buffer) GetBody() []byte { if m != nil { @@ -39,4 +46,14 @@ func (m *Buffer) GetBody() []byte { } func init() { + proto.RegisterType((*Buffer)(nil), "codec.perf.Buffer") +} + +var fileDescriptor0 = []byte{ + // 73 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x48, 0x2d, 0x4a, + 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4a, 0xce, 0x4f, 0x49, 0x4d, 0xd6, 0x03, 0x89, + 0x28, 0xc9, 0x70, 0xb1, 0x39, 0x95, 0xa6, 0xa5, 0xa5, 0x16, 0x09, 0x09, 0x71, 0xb1, 0x24, 0xe5, + 0xa7, 0x54, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x81, 0xd9, 0x80, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x3a, 0x58, 0x92, 0x53, 0x36, 0x00, 0x00, 0x00, } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/test/grpc_testing/test.pb.go b/Godeps/_workspace/src/google.golang.org/grpc/test/grpc_testing/test.pb.go index b25e98b8e4..7b0803f552 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/test/grpc_testing/test.pb.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/test/grpc_testing/test.pb.go @@ -22,6 +22,7 @@ It has these top-level messages: package grpc_testing import proto "github.com/golang/protobuf/proto" +import fmt "fmt" import math "math" import ( @@ -29,14 +30,15 @@ import ( grpc "google.golang.org/grpc" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - // 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. +const _ = proto.ProtoPackageIsVersion1 + // The type of payload that should be returned. type PayloadType int32 @@ -76,14 +78,16 @@ func (x *PayloadType) UnmarshalJSON(data []byte) error { *x = PayloadType(value) return nil } +func (PayloadType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } type Empty struct { XXX_unrecognized []byte `json:"-"` } -func (m *Empty) Reset() { *m = Empty{} } -func (m *Empty) String() string { return proto.CompactTextString(m) } -func (*Empty) ProtoMessage() {} +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } // A block of data, to simply increase gRPC message size. type Payload struct { @@ -94,9 +98,10 @@ type Payload struct { XXX_unrecognized []byte `json:"-"` } -func (m *Payload) Reset() { *m = Payload{} } -func (m *Payload) String() string { return proto.CompactTextString(m) } -func (*Payload) ProtoMessage() {} +func (m *Payload) Reset() { *m = Payload{} } +func (m *Payload) String() string { return proto.CompactTextString(m) } +func (*Payload) ProtoMessage() {} +func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *Payload) GetType() PayloadType { if m != nil && m.Type != nil { @@ -129,9 +134,10 @@ type SimpleRequest struct { XXX_unrecognized []byte `json:"-"` } -func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } -func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } -func (*SimpleRequest) ProtoMessage() {} +func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } +func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } +func (*SimpleRequest) ProtoMessage() {} +func (*SimpleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (m *SimpleRequest) GetResponseType() PayloadType { if m != nil && m.ResponseType != nil { @@ -180,9 +186,10 @@ type SimpleResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } -func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } -func (*SimpleResponse) ProtoMessage() {} +func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } +func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } +func (*SimpleResponse) ProtoMessage() {} +func (*SimpleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (m *SimpleResponse) GetPayload() *Payload { if m != nil { @@ -212,9 +219,10 @@ type StreamingInputCallRequest struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingInputCallRequest) Reset() { *m = StreamingInputCallRequest{} } -func (m *StreamingInputCallRequest) String() string { return proto.CompactTextString(m) } -func (*StreamingInputCallRequest) ProtoMessage() {} +func (m *StreamingInputCallRequest) Reset() { *m = StreamingInputCallRequest{} } +func (m *StreamingInputCallRequest) String() string { return proto.CompactTextString(m) } +func (*StreamingInputCallRequest) ProtoMessage() {} +func (*StreamingInputCallRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (m *StreamingInputCallRequest) GetPayload() *Payload { if m != nil { @@ -230,9 +238,10 @@ type StreamingInputCallResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingInputCallResponse) Reset() { *m = StreamingInputCallResponse{} } -func (m *StreamingInputCallResponse) String() string { return proto.CompactTextString(m) } -func (*StreamingInputCallResponse) ProtoMessage() {} +func (m *StreamingInputCallResponse) Reset() { *m = StreamingInputCallResponse{} } +func (m *StreamingInputCallResponse) String() string { return proto.CompactTextString(m) } +func (*StreamingInputCallResponse) ProtoMessage() {} +func (*StreamingInputCallResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } func (m *StreamingInputCallResponse) GetAggregatedPayloadSize() int32 { if m != nil && m.AggregatedPayloadSize != nil { @@ -252,9 +261,10 @@ type ResponseParameters struct { XXX_unrecognized []byte `json:"-"` } -func (m *ResponseParameters) Reset() { *m = ResponseParameters{} } -func (m *ResponseParameters) String() string { return proto.CompactTextString(m) } -func (*ResponseParameters) ProtoMessage() {} +func (m *ResponseParameters) Reset() { *m = ResponseParameters{} } +func (m *ResponseParameters) String() string { return proto.CompactTextString(m) } +func (*ResponseParameters) ProtoMessage() {} +func (*ResponseParameters) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (m *ResponseParameters) GetSize() int32 { if m != nil && m.Size != nil { @@ -284,9 +294,10 @@ type StreamingOutputCallRequest struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingOutputCallRequest) Reset() { *m = StreamingOutputCallRequest{} } -func (m *StreamingOutputCallRequest) String() string { return proto.CompactTextString(m) } -func (*StreamingOutputCallRequest) ProtoMessage() {} +func (m *StreamingOutputCallRequest) Reset() { *m = StreamingOutputCallRequest{} } +func (m *StreamingOutputCallRequest) String() string { return proto.CompactTextString(m) } +func (*StreamingOutputCallRequest) ProtoMessage() {} +func (*StreamingOutputCallRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (m *StreamingOutputCallRequest) GetResponseType() PayloadType { if m != nil && m.ResponseType != nil { @@ -316,9 +327,10 @@ type StreamingOutputCallResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *StreamingOutputCallResponse) Reset() { *m = StreamingOutputCallResponse{} } -func (m *StreamingOutputCallResponse) String() string { return proto.CompactTextString(m) } -func (*StreamingOutputCallResponse) ProtoMessage() {} +func (m *StreamingOutputCallResponse) Reset() { *m = StreamingOutputCallResponse{} } +func (m *StreamingOutputCallResponse) String() string { return proto.CompactTextString(m) } +func (*StreamingOutputCallResponse) ProtoMessage() {} +func (*StreamingOutputCallResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (m *StreamingOutputCallResponse) GetPayload() *Payload { if m != nil { @@ -328,9 +340,22 @@ func (m *StreamingOutputCallResponse) GetPayload() *Payload { } func init() { + proto.RegisterType((*Empty)(nil), "grpc.testing.Empty") + proto.RegisterType((*Payload)(nil), "grpc.testing.Payload") + proto.RegisterType((*SimpleRequest)(nil), "grpc.testing.SimpleRequest") + proto.RegisterType((*SimpleResponse)(nil), "grpc.testing.SimpleResponse") + proto.RegisterType((*StreamingInputCallRequest)(nil), "grpc.testing.StreamingInputCallRequest") + proto.RegisterType((*StreamingInputCallResponse)(nil), "grpc.testing.StreamingInputCallResponse") + proto.RegisterType((*ResponseParameters)(nil), "grpc.testing.ResponseParameters") + proto.RegisterType((*StreamingOutputCallRequest)(nil), "grpc.testing.StreamingOutputCallRequest") + proto.RegisterType((*StreamingOutputCallResponse)(nil), "grpc.testing.StreamingOutputCallResponse") proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value) } +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + // Client API for TestService service type TestServiceClient interface { @@ -539,9 +564,9 @@ func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { s.RegisterService(&_TestService_serviceDesc, srv) } -func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(Empty) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(TestServiceServer).EmptyCall(ctx, in) @@ -551,9 +576,9 @@ func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, codec return out, nil } -func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { +func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(SimpleRequest) - if err := codec.Unmarshal(buf, in); err != nil { + if err := dec(in); err != nil { return nil, err } out, err := srv.(TestServiceServer).UnaryCall(ctx, in) @@ -700,3 +725,43 @@ var _TestService_serviceDesc = grpc.ServiceDesc{ }, }, } + +var fileDescriptor0 = []byte{ + // 567 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x54, 0x51, 0x6f, 0xd2, 0x50, + 0x14, 0xb6, 0x03, 0x64, 0x1c, 0x58, 0x43, 0x0e, 0x59, 0x64, 0x9d, 0x89, 0x4b, 0x7d, 0xb0, 0x9a, + 0x88, 0x86, 0x44, 0x1f, 0x35, 0x73, 0x63, 0x71, 0x09, 0x03, 0x6c, 0xe1, 0x99, 0x5c, 0xe1, 0x0e, + 0x9b, 0x94, 0xb6, 0xb6, 0xb7, 0x46, 0x7c, 0xf0, 0x8f, 0xf9, 0x67, 0xfc, 0x11, 0xfe, 0x00, 0xef, + 0xbd, 0x6d, 0xa1, 0x40, 0x17, 0x99, 0xc6, 0xbd, 0xb5, 0xdf, 0xf9, 0xce, 0x77, 0xbe, 0xef, 0x9e, + 0xdb, 0x02, 0x30, 0x1a, 0xb2, 0x96, 0x1f, 0x78, 0xcc, 0xc3, 0xda, 0x2c, 0xf0, 0x27, 0x2d, 0x01, + 0xd8, 0xee, 0x4c, 0x2f, 0x43, 0xa9, 0x33, 0xf7, 0xd9, 0x42, 0xef, 0x42, 0x79, 0x40, 0x16, 0x8e, + 0x47, 0xa6, 0xf8, 0x1c, 0x8a, 0x6c, 0xe1, 0xd3, 0xa6, 0x72, 0xa2, 0x18, 0x6a, 0xfb, 0xa8, 0x95, + 0x6d, 0x68, 0x25, 0xa4, 0x21, 0x27, 0x98, 0x92, 0x86, 0x08, 0xc5, 0x8f, 0xde, 0x74, 0xd1, 0xdc, + 0xe3, 0xf4, 0x9a, 0x29, 0x9f, 0xf5, 0x5f, 0x0a, 0x1c, 0x58, 0xf6, 0xdc, 0x77, 0xa8, 0x49, 0x3f, + 0x47, 0xbc, 0x15, 0xdf, 0xc0, 0x41, 0x40, 0x43, 0xdf, 0x73, 0x43, 0x3a, 0xde, 0x4d, 0xbd, 0x96, + 0xf2, 0xc5, 0x1b, 0x3e, 0xce, 0xf4, 0x87, 0xf6, 0x37, 0x2a, 0xc7, 0x95, 0x56, 0x24, 0x8b, 0x63, + 0xf8, 0x02, 0xca, 0x7e, 0xac, 0xd0, 0x2c, 0xf0, 0x72, 0xb5, 0x7d, 0x98, 0x2b, 0x6f, 0xa6, 0x2c, + 0xa1, 0x7a, 0x6d, 0x3b, 0xce, 0x38, 0x0a, 0x69, 0xe0, 0x92, 0x39, 0x6d, 0x16, 0x79, 0xdb, 0xbe, + 0x59, 0x13, 0xe0, 0x28, 0xc1, 0xd0, 0x80, 0xba, 0x24, 0x79, 0x24, 0x62, 0x9f, 0xc6, 0xe1, 0xc4, + 0xe3, 0xee, 0x4b, 0x92, 0xa7, 0x0a, 0xbc, 0x2f, 0x60, 0x4b, 0xa0, 0xfa, 0x77, 0x50, 0xd3, 0xd4, + 0xb1, 0xab, 0xac, 0x23, 0x65, 0x27, 0x47, 0x1a, 0xec, 0x2f, 0xcd, 0x88, 0x88, 0x15, 0x73, 0xf9, + 0x8e, 0x8f, 0xa0, 0x9a, 0xf5, 0x50, 0x90, 0x65, 0xf0, 0x56, 0xf3, 0xbb, 0x70, 0x64, 0xb1, 0x80, + 0x92, 0x39, 0x97, 0xbe, 0x74, 0xfd, 0x88, 0x9d, 0x11, 0xc7, 0x49, 0x37, 0x70, 0x5b, 0x2b, 0xfa, + 0x10, 0xb4, 0x3c, 0xb5, 0x24, 0xd9, 0x6b, 0x78, 0x40, 0x66, 0xb3, 0x80, 0xce, 0x08, 0xa3, 0xd3, + 0x71, 0xd2, 0x13, 0xaf, 0x46, 0x91, 0xab, 0x39, 0x5c, 0x95, 0x13, 0x69, 0xb1, 0x23, 0xfd, 0x12, + 0x30, 0xd5, 0x18, 0x90, 0x80, 0xc7, 0x62, 0x34, 0x08, 0xc5, 0x25, 0xca, 0xb4, 0xca, 0x67, 0x11, + 0xd7, 0x76, 0x79, 0xf5, 0x0b, 0x11, 0x0b, 0x4a, 0x16, 0x0e, 0x29, 0x34, 0x0a, 0xf5, 0x9f, 0x4a, + 0xc6, 0x61, 0x3f, 0x62, 0x1b, 0x81, 0xff, 0xf5, 0xca, 0x7d, 0x80, 0xc6, 0xb2, 0xdf, 0x5f, 0x5a, + 0xe5, 0x3e, 0x0a, 0xfc, 0xf0, 0x4e, 0xd6, 0x55, 0xb6, 0x23, 0x99, 0x18, 0x6c, 0xc7, 0xbc, 0xed, + 0x05, 0xd5, 0x7b, 0x70, 0x9c, 0x9b, 0xf0, 0x2f, 0xaf, 0xd7, 0xb3, 0xb7, 0x50, 0xcd, 0x04, 0xc6, + 0x3a, 0xd4, 0xce, 0xfa, 0x57, 0x03, 0xb3, 0x63, 0x59, 0xa7, 0xef, 0xba, 0x9d, 0xfa, 0x3d, 0xbe, + 0x08, 0x75, 0xd4, 0x5b, 0xc3, 0x14, 0x04, 0xb8, 0x6f, 0x9e, 0xf6, 0xce, 0xfb, 0x57, 0xf5, 0xbd, + 0xf6, 0x8f, 0x22, 0x54, 0x87, 0x5c, 0xdd, 0xe2, 0x4b, 0xb0, 0x27, 0x14, 0x5f, 0x41, 0x45, 0xfe, + 0x40, 0x84, 0x2d, 0x6c, 0xac, 0x4f, 0x97, 0x05, 0x2d, 0x0f, 0xc4, 0x0b, 0xa8, 0x8c, 0x5c, 0x12, + 0xc4, 0x6d, 0xc7, 0xeb, 0x8c, 0xb5, 0x1f, 0x87, 0xf6, 0x30, 0xbf, 0x98, 0x1c, 0x80, 0x03, 0x8d, + 0x9c, 0xf3, 0x41, 0x63, 0xa3, 0xe9, 0xc6, 0x4b, 0xa2, 0x3d, 0xdd, 0x81, 0x19, 0xcf, 0x7a, 0xa9, + 0xa0, 0x0d, 0xb8, 0xfd, 0x45, 0xe0, 0x93, 0x1b, 0x24, 0x36, 0xbf, 0x40, 0xcd, 0xf8, 0x33, 0x31, + 0x1e, 0x65, 0x88, 0x51, 0xea, 0x45, 0xe4, 0x38, 0xe7, 0x11, 0x4f, 0xfb, 0xf5, 0xbf, 0x65, 0x32, + 0x14, 0x99, 0x4a, 0x7d, 0x4f, 0x9c, 0xeb, 0x3b, 0x18, 0xf5, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x4c, + 0x41, 0xfe, 0xb6, 0x89, 0x06, 0x00, 0x00, +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/trace.go b/Godeps/_workspace/src/google.golang.org/grpc/trace.go index 246357406a..cde04fbfc9 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/trace.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/trace.go @@ -114,3 +114,7 @@ type fmtStringer struct { func (f *fmtStringer) String() string { return fmt.Sprintf(f.format, f.a...) } + +type stringer string + +func (s stringer) String() string { return string(s) } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/transport/control.go b/Godeps/_workspace/src/google.golang.org/grpc/transport/control.go index 464bf10a36..f6b38a5a6d 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/transport/control.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/transport/control.go @@ -37,7 +37,7 @@ import ( "fmt" "sync" - "github.com/bradfitz/http2" + "golang.org/x/net/http2" ) const ( @@ -86,7 +86,8 @@ func (flushIO) isItem() bool { } type ping struct { - ack bool + ack bool + data [8]byte } func (ping) isItem() bool { diff --git a/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_client.go b/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_client.go index 40b7640821..7cf700fe3e 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_client.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_client.go @@ -43,13 +43,14 @@ import ( "sync" "time" - "github.com/bradfitz/http2" - "github.com/bradfitz/http2/hpack" "golang.org/x/net/context" + "golang.org/x/net/http2" + "golang.org/x/net/http2/hpack" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" ) // http2Client implements the ClientTransport interface with HTTP2. @@ -209,6 +210,7 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { s := &Stream{ id: t.nextID, method: callHdr.Method, + sendCompress: callHdr.SendCompress, buf: newRecvBuffer(), fc: fc, sendQuotaPool: newQuotaPool(int(t.streamSendQuota)), @@ -238,10 +240,14 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return nil, ContextErr(context.DeadlineExceeded) } } + pr := &peer.Peer{ + Addr: t.conn.RemoteAddr(), + } // Attach Auth info if there is any. if t.authInfo != nil { - ctx = credentials.NewContext(ctx, t.authInfo) + pr.AuthInfo = t.authInfo } + ctx = peer.NewContext(ctx, pr) authData := make(map[string]string) for _, c := range t.authCreds { // Construct URI required to get auth request metadata. @@ -293,7 +299,18 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } s := t.newStream(ctx, callHdr) t.activeStreams[s.id] = s + + // This stream is not counted when applySetings(...) initialize t.streamsQuota. + // Reset t.streamsQuota to the right value. + var reset bool + if !checkStreamsQuota && t.streamsQuota != nil { + reset = true + } t.mu.Unlock() + if reset { + t.streamsQuota.reset(-1) + } + // HPACK encodes various headers. Note that once WriteField(...) is // called, the corresponding headers/continuation frame has to be sent // because hpack.Encoder is stateful. @@ -306,6 +323,9 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea t.hEnc.WriteField(hpack.HeaderField{Name: "user-agent", Value: t.userAgent}) t.hEnc.WriteField(hpack.HeaderField{Name: "te", Value: "trailers"}) + if callHdr.SendCompress != "" { + t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress}) + } if timeout > 0 { t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)}) } @@ -333,6 +353,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } else { endHeaders = true } + var flush bool + if endHeaders && (hasMD || callHdr.Flush) { + flush = true + } if first { // Sends a HeadersFrame to server to start a new stream. p := http2.HeadersFrameParam{ @@ -344,11 +368,11 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea // Do a force flush for the buffered frames iff it is the last headers frame // and there is header metadata to be sent. Otherwise, there is flushing until // the corresponding data frame is written. - err = t.framer.writeHeaders(hasMD && endHeaders, p) + err = t.framer.writeHeaders(flush, p) first = false } else { // Sends Continuation frames for the leftover headers. - err = t.framer.writeContinuation(hasMD && endHeaders, s.id, endHeaders, t.hBuf.Next(size)) + err = t.framer.writeContinuation(flush, s.id, endHeaders, t.hBuf.Next(size)) } if err != nil { t.notifyError(err) @@ -372,6 +396,11 @@ func (t *http2Client) CloseStream(s *Stream, err error) { if updateStreams { t.streamsQuota.add(1) } + // In case stream sending and receiving are invoked in separate + // goroutines (e.g., bi-directional streaming), the caller needs + // to call cancel on the stream to interrupt the blocking on + // other goroutines. + s.cancel() s.mu.Lock() if q := s.fc.restoreConn(); q > 0 { t.controlBuf.put(&windowUpdate{0, q}) @@ -386,11 +415,6 @@ func (t *http2Client) CloseStream(s *Stream, err error) { } s.state = streamDone s.mu.Unlock() - // In case stream sending and receiving are invoked in separate - // goroutines (e.g., bi-directional streaming), the caller needs - // to call cancel on the stream to interrupt the blocking on - // other goroutines. - s.cancel() if _, ok := err.(StreamError); ok { t.controlBuf.put(&resetStream{s.id, http2.ErrCodeCancel}) } @@ -635,7 +659,9 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame) { } func (t *http2Client) handlePing(f *http2.PingFrame) { - t.controlBuf.put(&ping{true}) + pingAck := &ping{ack: true} + copy(pingAck.data[:], f.Data[:]) + t.controlBuf.put(pingAck) } func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { @@ -676,8 +702,10 @@ func (t *http2Client) operateHeaders(hDec *hpackDecoder, s *Stream, frame header if !endHeaders { return s } - s.mu.Lock() + if !endStream { + s.recvCompress = hDec.state.encoding + } if !s.headerDone { if !endStream && len(hDec.state.mdata) > 0 { s.header = hDec.state.mdata @@ -740,7 +768,7 @@ func (t *http2Client) reader() { endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream) curStream = t.operateHeaders(hDec, curStream, frame, endStream) case *http2.ContinuationFrame: - curStream = t.operateHeaders(hDec, curStream, frame, false) + curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded()) case *http2.DataFrame: t.handleData(frame) case *http2.RSTStreamFrame: @@ -816,9 +844,7 @@ func (t *http2Client) controller() { case *flushIO: t.framer.flushWrite() case *ping: - // TODO(zhaoq): Ack with all-0 data now. will change to some - // meaningful content when this is actually in use. - t.framer.writePing(true, i.ack, [8]byte{}) + t.framer.writePing(true, i.ack, i.data) default: grpclog.Printf("transport: http2Client.controller got unexpected item type %v\n", i) } diff --git a/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_server.go b/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_server.go index 8856d7f4c1..cce2e12d91 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_server.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/transport/http2_server.go @@ -42,13 +42,14 @@ import ( "strconv" "sync" - "github.com/bradfitz/http2" - "github.com/bradfitz/http2/hpack" "golang.org/x/net/context" + "golang.org/x/net/http2" + "golang.org/x/net/http2/hpack" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" ) // ErrIllegalHeaderWrite indicates that setting header is illegal because of @@ -138,7 +139,7 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI // operateHeader takes action on the decoded headers. It returns the current // stream if there are remaining headers on the wire (in the following // Continuation frame). -func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool, handle func(*Stream), wg *sync.WaitGroup) (pendingStream *Stream) { +func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool, handle func(*Stream)) (pendingStream *Stream) { defer func() { if pendingStream == nil { hDec.state = decodeState{} @@ -163,6 +164,35 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header if !endHeaders { return s } + s.recvCompress = hDec.state.encoding + if hDec.state.timeoutSet { + s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout) + } else { + s.ctx, s.cancel = context.WithCancel(context.TODO()) + } + pr := &peer.Peer{ + Addr: t.conn.RemoteAddr(), + } + // Attach Auth info if there is any. + if t.authInfo != nil { + pr.AuthInfo = t.authInfo + } + s.ctx = peer.NewContext(s.ctx, pr) + // Cache the current stream to the context so that the server application + // can find out. Required when the server wants to send some metadata + // back to the client (unary call only). + s.ctx = newContextWithStream(s.ctx, s) + // Attach the received metadata to the context. + if len(hDec.state.mdata) > 0 { + s.ctx = metadata.NewContext(s.ctx, hDec.state.mdata) + } + + s.dec = &recvBufferReader{ + ctx: s.ctx, + recv: s.buf, + } + s.recvCompress = hDec.state.encoding + s.method = hDec.state.method t.mu.Lock() if t.state != reachable { t.mu.Unlock() @@ -179,35 +209,7 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header s.windowHandler = func(n int) { t.updateWindow(s, uint32(n)) } - if hDec.state.timeoutSet { - s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout) - } else { - s.ctx, s.cancel = context.WithCancel(context.TODO()) - } - // Attach Auth info if there is any. - if t.authInfo != nil { - s.ctx = credentials.NewContext(s.ctx, t.authInfo) - } - // Cache the current stream to the context so that the server application - // can find out. Required when the server wants to send some metadata - // back to the client (unary call only). - s.ctx = newContextWithStream(s.ctx, s) - // Attach the received metadata to the context. - if len(hDec.state.mdata) > 0 { - s.ctx = metadata.NewContext(s.ctx, hDec.state.mdata) - } - - s.dec = &recvBufferReader{ - ctx: s.ctx, - recv: s.buf, - } - s.method = hDec.state.method - - wg.Add(1) - go func() { - handle(s) - wg.Done() - }() + handle(s) return nil } @@ -243,8 +245,6 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { hDec := newHPACKDecoder() var curStream *Stream - var wg sync.WaitGroup - defer wg.Wait() for { frame, err := t.framer.readFrame() if err != nil { @@ -273,9 +273,9 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { fc: fc, } endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream) - curStream = t.operateHeaders(hDec, curStream, frame, endStream, handle, &wg) + curStream = t.operateHeaders(hDec, curStream, frame, endStream, handle) case *http2.ContinuationFrame: - curStream = t.operateHeaders(hDec, curStream, frame, false, handle, &wg) + curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded(), handle) case *http2.DataFrame: t.handleData(frame) case *http2.RSTStreamFrame: @@ -384,7 +384,9 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } func (t *http2Server) handlePing(f *http2.PingFrame) { - t.controlBuf.put(&ping{true}) + pingAck := &ping{ack: true} + copy(pingAck.data[:], f.Data[:]) + t.controlBuf.put(pingAck) } func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) { @@ -446,6 +448,9 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { t.hBuf.Reset() t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"}) + if s.sendCompress != "" { + t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) + } for k, v := range md { for _, entry := range v { t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) @@ -463,17 +468,24 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { // TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early // OK is adopted. func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error { - s.mu.RLock() + var headersSent bool + s.mu.Lock() if s.state == streamDone { - s.mu.RUnlock() + s.mu.Unlock() return nil } - s.mu.RUnlock() + if s.headerOk { + headersSent = true + } + s.mu.Unlock() if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil { return err } t.hBuf.Reset() - t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) + if !headersSent { + t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) + t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"}) + } t.hEnc.WriteField( hpack.HeaderField{ Name: "grpc-status", @@ -513,6 +525,9 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { t.hBuf.Reset() t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"}) + if s.sendCompress != "" { + t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) + } p := http2.HeadersFrameParam{ StreamID: s.id, BlockFragment: t.hBuf.Bytes(), @@ -628,9 +643,7 @@ func (t *http2Server) controller() { case *flushIO: t.framer.flushWrite() case *ping: - // TODO(zhaoq): Ack with all-0 data now. will change to some - // meaningful content when this is actually in use. - t.framer.writePing(true, i.ack, [8]byte{}) + t.framer.writePing(true, i.ack, i.data) default: grpclog.Printf("transport: http2Server.controller got unexpected item type %v\n", i) } @@ -660,9 +673,9 @@ func (t *http2Server) Close() (err error) { t.mu.Unlock() close(t.shutdownChan) err = t.conn.Close() - // Notify all active streams. + // Cancel all active streams. for _, s := range streams { - s.write(recvMsg{err: ErrConnClosing}) + s.cancel() } return } @@ -684,8 +697,11 @@ func (t *http2Server) closeStream(s *Stream) { s.state = streamDone s.mu.Unlock() // In case stream sending and receiving are invoked in separate - // goroutines (e.g., bi-directional streaming), the caller needs - // to call cancel on the stream to interrupt the blocking on - // other goroutines. + // goroutines (e.g., bi-directional streaming), cancel needs to be + // called to interrupt the potential blocking on other goroutines. s.cancel() } + +func (t *http2Server) RemoteAddr() net.Addr { + return t.conn.RemoteAddr() +} diff --git a/Godeps/_workspace/src/google.golang.org/grpc/transport/http_util.go b/Godeps/_workspace/src/google.golang.org/grpc/transport/http_util.go index ac3c47551a..f9d9fdf0af 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/transport/http_util.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/transport/http_util.go @@ -43,8 +43,8 @@ import ( "sync/atomic" "time" - "github.com/bradfitz/http2" - "github.com/bradfitz/http2/hpack" + "golang.org/x/net/http2" + "golang.org/x/net/http2/hpack" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" @@ -52,7 +52,7 @@ import ( const ( // The primary user agent - primaryUA = "grpc-go/0.7" + primaryUA = "grpc-go/0.11" // http2MaxFrameLen specifies the max length of a HTTP2 frame. http2MaxFrameLen = 16384 // 16KB frame // http://http2.github.io/http2-spec/#SettingValues @@ -89,6 +89,7 @@ var ( // Records the states during HPACK decoding. Must be reset once the // decoding of the entire headers are finished. type decodeState struct { + encoding string // statusCode caches the stream status received from the trailer // the server sent. Client side only. statusCode codes.Code @@ -140,6 +141,13 @@ func newHPACKDecoder() *hpackDecoder { d := &hpackDecoder{} d.h = hpack.NewDecoder(http2InitHeaderTableSize, func(f hpack.HeaderField) { switch f.Name { + case "content-type": + if !strings.Contains(f.Value, "application/grpc") { + d.err = StreamErrorf(codes.FailedPrecondition, "transport: received the unexpected header") + return + } + case "grpc-encoding": + d.state.encoding = f.Value case "grpc-status": code, err := strconv.Atoi(f.Value) if err != nil { diff --git a/Godeps/_workspace/src/google.golang.org/grpc/transport/transport.go b/Godeps/_workspace/src/google.golang.org/grpc/transport/transport.go index e20a6d9923..d99233d2ea 100644 --- a/Godeps/_workspace/src/google.golang.org/grpc/transport/transport.go +++ b/Godeps/_workspace/src/google.golang.org/grpc/transport/transport.go @@ -47,6 +47,7 @@ import ( "time" "golang.org/x/net/context" + "golang.org/x/net/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" @@ -169,11 +170,13 @@ type Stream struct { ctx context.Context cancel context.CancelFunc // method records the associated RPC method of the stream. - method string - buf *recvBuffer - dec io.Reader - fc *inFlow - recvQuota uint32 + method string + recvCompress string + sendCompress string + buf *recvBuffer + dec io.Reader + fc *inFlow + recvQuota uint32 // The accumulated inbound quota pending for window update. updateQuota uint32 // The handler to control the window update procedure for both this @@ -200,6 +203,17 @@ type Stream struct { statusDesc string } +// RecvCompress returns the compression algorithm applied to the inbound +// message. It is empty string if there is no compression applied. +func (s *Stream) RecvCompress() string { + return s.recvCompress +} + +// SetSendCompress sets the compression algorithm to the stream. +func (s *Stream) SetSendCompress(str string) { + s.sendCompress = str +} + // Header acquires the key-value pairs of header metadata once it // is available. It blocks until i) the metadata is ready or ii) there is no // header metadata or iii) the stream is cancelled/expired. @@ -232,6 +246,11 @@ func (s *Stream) Context() context.Context { return s.ctx } +// TraceContext recreates the context of s with a trace.Trace. +func (s *Stream) TraceContext(tr trace.Trace) { + s.ctx = trace.NewContext(s.ctx, tr) +} + // Method returns the method for the stream. func (s *Stream) Method() string { return s.method @@ -342,8 +361,18 @@ type Options struct { // CallHdr carries the information of a particular RPC. type CallHdr struct { - Host string // peer host - Method string // the operation to perform on the specified host + // Host specifies peer host. + Host string + // Method specifies the operation to perform. + Method string + // RecvCompress specifies the compression algorithm applied on inbound messages. + RecvCompress string + // SendCompress specifies the compression algorithm applied on outbound message. + SendCompress string + // Flush indicates if new stream command should be sent to the peer without + // waiting for the first data. This is a hint though. The transport may modify + // the flush decision for performance purpose. + Flush bool } // ClientTransport is the common interface for all gRPC client side transport @@ -390,6 +419,8 @@ type ServerTransport interface { // should not be accessed any more. All the pending streams and their // handlers will be terminated asynchronously. Close() error + // RemoteAddr returns the remote network address. + RemoteAddr() net.Addr } // StreamErrorf creates an StreamError with the specified error code and description.