aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/client.go57
-rw-r--r--cmd/cashier/main.go10
-rw-r--r--cmd/cashierd/main.go14
-rw-r--r--cmd/cashierd/rpc.go68
-rw-r--r--lib/util.go4
-rw-r--r--lib/util_test.go3
-rw-r--r--proto/signer.pb.go172
-rw-r--r--proto/signer.proto17
-rwxr-xr-xregen.sh (renamed from genstatic.sh)3
-rwxr-xr-xrun_tests.sh2
-rw-r--r--server/signer/signer.go15
-rw-r--r--server/store/store.go2
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/any.go136
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/any/any.pb.go155
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/any/any.proto140
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/doc.go35
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/duration.go102
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go114
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/duration/duration.proto98
-rwxr-xr-xvendor/github.com/golang/protobuf/ptypes/regen.sh66
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/timestamp.go125
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go127
-rw-r--r--vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto111
-rw-r--r--vendor/github.com/soheilhy/cmux/CONTRIBUTORS12
-rw-r--r--vendor/github.com/soheilhy/cmux/LICENSE202
-rw-r--r--vendor/github.com/soheilhy/cmux/README.md83
-rw-r--r--vendor/github.com/soheilhy/cmux/buffer.go67
-rw-r--r--vendor/github.com/soheilhy/cmux/cmux.go269
-rw-r--r--vendor/github.com/soheilhy/cmux/doc.go18
-rw-r--r--vendor/github.com/soheilhy/cmux/matchers.go184
-rw-r--r--vendor/github.com/soheilhy/cmux/patricia.go179
-rw-r--r--vendor/vendor.json50
32 files changed, 2619 insertions, 21 deletions
diff --git a/client/client.go b/client/client.go
index e1fb98c..246415e 100644
--- a/client/client.go
+++ b/client/client.go
@@ -10,12 +10,19 @@ import (
"net/http"
"net/url"
"path"
+ "strings"
"time"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/metadata"
+
+ "github.com/golang/protobuf/ptypes"
"github.com/nsheridan/cashier/lib"
+ "github.com/nsheridan/cashier/proto"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
+ "golang.org/x/net/context"
)
// SavePublicFiles installs the public part of the cert and key.
@@ -99,7 +106,7 @@ func Sign(pub ssh.PublicKey, token string, conf *Config) (*ssh.Certificate, erro
return nil, err
}
s, err := json.Marshal(&lib.SignRequest{
- Key: lib.GetPublicKey(pub),
+ Key: string(lib.GetPublicKey(pub)),
ValidUntil: time.Now().Add(validity),
})
if err != nil {
@@ -122,3 +129,51 @@ func Sign(pub ssh.PublicKey, token string, conf *Config) (*ssh.Certificate, erro
}
return cert, nil
}
+
+// RPCSign sends the public key to the CA to be signed.
+func RPCSign(pub ssh.PublicKey, token string, conf *Config) (*ssh.Certificate, error) {
+ var opts []grpc.DialOption
+ var srv string
+ if strings.HasPrefix(conf.CA, "https://") {
+ srv = strings.TrimPrefix(conf.CA, "https://")
+ } else {
+ srv = strings.TrimPrefix(conf.CA, "http://")
+ opts = append(opts, grpc.WithInsecure())
+ }
+ conn, err := grpc.Dial(srv, opts...)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+ stub := proto.NewSignerClient(conn)
+ lifetime, err := time.ParseDuration(conf.Validity)
+ if err != nil {
+ return nil, err
+ }
+ deadline := time.Now().Add(lifetime)
+ ts, err := ptypes.TimestampProto(deadline)
+ if err != nil {
+ return nil, err
+ }
+ req := &proto.SignRequest{
+ Key: lib.GetPublicKey(pub),
+ ValidUntil: ts,
+ }
+ md := metadata.New(map[string]string{
+ "security": "authorization",
+ "payload": token,
+ })
+ r, err := stub.Sign(metadata.NewContext(context.TODO(), md), req)
+ if err != nil {
+ return nil, err
+ }
+ k, _, _, _, err := ssh.ParseAuthorizedKey(r.Cert)
+ if err != nil {
+ return nil, err
+ }
+ cert, ok := k.(*ssh.Certificate)
+ if !ok {
+ return nil, errors.New("did not receive a valid certificate from server")
+ }
+ return cert, nil
+}
diff --git a/cmd/cashier/main.go b/cmd/cashier/main.go
index 77a0b4b..97747f3 100644
--- a/cmd/cashier/main.go
+++ b/cmd/cashier/main.go
@@ -12,6 +12,7 @@ import (
"github.com/nsheridan/cashier/client"
"github.com/pkg/browser"
"github.com/spf13/pflag"
+ "golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
@@ -23,10 +24,12 @@ var (
validity = pflag.Duration("validity", time.Hour*24, "Key lifetime. May be overridden by the CA at signing time")
keytype = pflag.String("key_type", "", "Type of private key to generate - rsa, ecdsa or ed25519. (default \"rsa\")")
publicFilePrefix = pflag.String("public_file_prefix", "", "Prefix for filename for public key and cert (optional, no default)")
+ useGRPC = pflag.Bool("use_grpc", false, "Use grpc (experimental)")
)
func main() {
pflag.Parse()
+ var err error
c, err := client.ReadConfig(*cfg)
if err != nil {
@@ -46,7 +49,12 @@ func main() {
var token string
fmt.Scanln(&token)
- cert, err := client.Sign(pub, token, c)
+ var cert *ssh.Certificate
+ if *useGRPC {
+ cert, err = client.RPCSign(pub, token, c)
+ } else {
+ cert, err = client.Sign(pub, token, c)
+ }
if err != nil {
log.Fatalln(err)
}
diff --git a/cmd/cashierd/main.go b/cmd/cashierd/main.go
index 8164cf7..d355604 100644
--- a/cmd/cashierd/main.go
+++ b/cmd/cashierd/main.go
@@ -17,6 +17,7 @@ import (
"strings"
"github.com/pkg/errors"
+ "github.com/soheilhy/cmux"
"go4.org/wkfs"
"golang.org/x/crypto/acme/autocert"
@@ -153,8 +154,7 @@ func signHandler(a *appContext, w http.ResponseWriter, r *http.Request) (int, er
token := &oauth2.Token{
AccessToken: t,
}
- ok := authprovider.Valid(token)
- if !ok {
+ if !authprovider.Valid(token) {
return http.StatusUnauthorized, errors.New(http.StatusText(http.StatusUnauthorized))
}
@@ -174,7 +174,7 @@ func signHandler(a *appContext, w http.ResponseWriter, r *http.Request) (int, er
}
if err := json.NewEncoder(w).Encode(&lib.SignResponse{
Status: "ok",
- Response: lib.GetPublicKey(cert),
+ Response: string(lib.GetPublicKey(cert)),
}); err != nil {
return http.StatusInternalServerError, errors.Wrap(err, "error encoding response")
}
@@ -425,5 +425,11 @@ func main() {
s := &http.Server{
Handler: h,
}
- log.Fatal(s.Serve(l))
+
+ cm := cmux.New(l)
+ httpl := cm.Match(cmux.HTTP1Fast())
+ grpcl := cm.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
+ go s.Serve(httpl)
+ go newGrpcServer(grpcl)
+ log.Fatal(cm.Serve())
}
diff --git a/cmd/cashierd/rpc.go b/cmd/cashierd/rpc.go
new file mode 100644
index 0000000..ad8aa5d
--- /dev/null
+++ b/cmd/cashierd/rpc.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "log"
+ "net"
+
+ "golang.org/x/net/context"
+
+ "golang.org/x/oauth2"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/metadata"
+
+ "github.com/nsheridan/cashier/lib"
+ "github.com/nsheridan/cashier/proto"
+)
+
+type rpcServer struct{}
+
+type key int
+
+const usernameKey key = 0
+
+func (s *rpcServer) Sign(ctx context.Context, req *proto.SignRequest) (*proto.SignResponse, error) {
+ username, ok := ctx.Value(usernameKey).(string)
+ if !ok {
+ return nil, grpc.Errorf(codes.InvalidArgument, "Error reading username")
+ }
+ cert, err := keysigner.SignUserKeyFromRPC(req, username)
+ if err != nil {
+ return nil, grpc.Errorf(codes.InvalidArgument, err.Error())
+ }
+ if err := certstore.SetCert(cert); err != nil {
+ log.Printf("Error recording cert: %v", err)
+ }
+ resp := &proto.SignResponse{
+ Cert: lib.GetPublicKey(cert),
+ }
+ return resp, nil
+}
+
+func authInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
+ md, ok := metadata.FromContext(ctx)
+ if !ok {
+ return nil, grpc.Errorf(codes.Unauthenticated, "request not authenticated")
+ }
+ switch md["security"][0] {
+ case "authorization":
+ token := &oauth2.Token{
+ AccessToken: md["payload"][0],
+ }
+ if !authprovider.Valid(token) {
+ return nil, grpc.Errorf(codes.PermissionDenied, "access denied")
+ }
+ authprovider.Revoke(token)
+ ctx = context.WithValue(ctx, usernameKey, authprovider.Username(token))
+ default:
+ return nil, grpc.Errorf(codes.InvalidArgument, "unknown argument")
+ }
+ return handler(ctx, req)
+}
+
+func newGrpcServer(l net.Listener) {
+ serv := grpc.NewServer(grpc.UnaryInterceptor(authInterceptor))
+ proto.RegisterSignerServer(serv, &rpcServer{})
+ serv.Serve(l)
+}
diff --git a/lib/util.go b/lib/util.go
index b1c7b87..ca88f3f 100644
--- a/lib/util.go
+++ b/lib/util.go
@@ -3,8 +3,8 @@ package lib
import "golang.org/x/crypto/ssh"
// GetPublicKey marshals a ssh certificate to a string.
-func GetPublicKey(pub ssh.PublicKey) string {
+func GetPublicKey(pub ssh.PublicKey) []byte {
marshaled := ssh.MarshalAuthorizedKey(pub)
// Strip trailing newline
- return string(marshaled[:len(marshaled)-1])
+ return marshaled[:len(marshaled)-1]
}
diff --git a/lib/util_test.go b/lib/util_test.go
index 9e89297..b1f18a8 100644
--- a/lib/util_test.go
+++ b/lib/util_test.go
@@ -1,6 +1,7 @@
package lib
import (
+ "reflect"
"testing"
"github.com/nsheridan/cashier/testdata"
@@ -10,7 +11,7 @@ import (
func TestGetPublicKey(t *testing.T) {
t.Parallel()
c, _, _, _, _ := ssh.ParseAuthorizedKey(testdata.Cert)
- if GetPublicKey(c.(*ssh.Certificate)) != string(testdata.Cert) {
+ if !reflect.DeepEqual(GetPublicKey(c.(*ssh.Certificate)), testdata.Cert) {
t.Fail()
}
}
diff --git a/proto/signer.pb.go b/proto/signer.pb.go
new file mode 100644
index 0000000..f3a0eb2
--- /dev/null
+++ b/proto/signer.pb.go
@@ -0,0 +1,172 @@
+// Code generated by protoc-gen-go.
+// source: proto/signer.proto
+// DO NOT EDIT!
+
+/*
+Package proto is a generated protocol buffer package.
+
+It is generated from these files:
+ proto/signer.proto
+
+It has these top-level messages:
+ SignRequest
+ SignResponse
+*/
+package proto
+
+import proto1 "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto1.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto1.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type SignRequest struct {
+ Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+ ValidUntil *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=valid_until,json=validUntil" json:"valid_until,omitempty"`
+}
+
+func (m *SignRequest) Reset() { *m = SignRequest{} }
+func (m *SignRequest) String() string { return proto1.CompactTextString(m) }
+func (*SignRequest) ProtoMessage() {}
+func (*SignRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *SignRequest) GetKey() []byte {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *SignRequest) GetValidUntil() *google_protobuf.Timestamp {
+ if m != nil {
+ return m.ValidUntil
+ }
+ return nil
+}
+
+type SignResponse struct {
+ Cert []byte `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"`
+}
+
+func (m *SignResponse) Reset() { *m = SignResponse{} }
+func (m *SignResponse) String() string { return proto1.CompactTextString(m) }
+func (*SignResponse) ProtoMessage() {}
+func (*SignResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+func (m *SignResponse) GetCert() []byte {
+ if m != nil {
+ return m.Cert
+ }
+ return nil
+}
+
+func init() {
+ proto1.RegisterType((*SignRequest)(nil), "proto.SignRequest")
+ proto1.RegisterType((*SignResponse)(nil), "proto.SignResponse")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for Signer service
+
+type SignerClient interface {
+ Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
+}
+
+type signerClient struct {
+ cc *grpc.ClientConn
+}
+
+func NewSignerClient(cc *grpc.ClientConn) SignerClient {
+ return &signerClient{cc}
+}
+
+func (c *signerClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) {
+ out := new(SignResponse)
+ err := grpc.Invoke(ctx, "/proto.Signer/Sign", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// Server API for Signer service
+
+type SignerServer interface {
+ Sign(context.Context, *SignRequest) (*SignResponse, error)
+}
+
+func RegisterSignerServer(s *grpc.Server, srv SignerServer) {
+ s.RegisterService(&_Signer_serviceDesc, srv)
+}
+
+func _Signer_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SignRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SignerServer).Sign(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/proto.Signer/Sign",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SignerServer).Sign(ctx, req.(*SignRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _Signer_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "proto.Signer",
+ HandlerType: (*SignerServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "Sign",
+ Handler: _Signer_Sign_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "proto/signer.proto",
+}
+
+func init() { proto1.RegisterFile("proto/signer.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+ // 197 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0xce, 0xb1, 0x6e, 0x83, 0x30,
+ 0x10, 0x06, 0xe0, 0xd2, 0x52, 0x86, 0x83, 0xa1, 0xba, 0x2e, 0x88, 0xa5, 0xc8, 0x13, 0x93, 0x51,
+ 0xe9, 0xc8, 0x5b, 0x40, 0xbb, 0x55, 0x8a, 0x20, 0xb9, 0x58, 0x56, 0xc0, 0x26, 0xd8, 0x44, 0xca,
+ 0xdb, 0x47, 0xd8, 0x41, 0x4a, 0xa6, 0xfb, 0xef, 0xf4, 0xeb, 0xd3, 0x01, 0x4e, 0xb3, 0xb6, 0xba,
+ 0x34, 0x52, 0x28, 0x9a, 0xb9, 0x5b, 0xf0, 0xdd, 0x8d, 0xec, 0x4b, 0x68, 0x2d, 0x06, 0x2a, 0xdd,
+ 0xd6, 0x2f, 0xc7, 0xd2, 0xca, 0x91, 0x8c, 0xed, 0xc6, 0xc9, 0xf7, 0xd8, 0x3f, 0xc4, 0xad, 0x14,
+ 0xaa, 0xa1, 0xf3, 0x42, 0xc6, 0xe2, 0x07, 0xbc, 0x9d, 0xe8, 0x9a, 0x06, 0x79, 0x50, 0x24, 0xcd,
+ 0x1a, 0xb1, 0x86, 0xf8, 0xd2, 0x0d, 0xf2, 0xb0, 0x5b, 0x94, 0x95, 0x43, 0xfa, 0x9a, 0x07, 0x45,
+ 0x5c, 0x65, 0xdc, 0xbb, 0x7c, 0x73, 0xf9, 0xef, 0xe6, 0x36, 0xe0, 0xea, 0x7f, 0x6b, 0x9b, 0x31,
+ 0x48, 0xbc, 0x6e, 0x26, 0xad, 0x0c, 0x21, 0x42, 0xb8, 0xa7, 0xd9, 0xde, 0x7d, 0x97, 0xab, 0x1a,
+ 0xa2, 0xd6, 0x7d, 0x8e, 0xdf, 0x10, 0xae, 0x09, 0xd1, 0xb3, 0xfc, 0xe1, 0xb1, 0xec, 0xf3, 0xe9,
+ 0xe6, 0x39, 0xf6, 0xd2, 0x47, 0xee, 0xfa, 0x73, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x30, 0x72,
+ 0x63, 0x03, 0x01, 0x00, 0x00,
+}
diff --git a/proto/signer.proto b/proto/signer.proto
new file mode 100644
index 0000000..83f180d
--- /dev/null
+++ b/proto/signer.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+package proto;
+
+import "google/protobuf/timestamp.proto";
+
+message SignRequest {
+ bytes key = 1;
+ google.protobuf.Timestamp valid_until = 2;
+}
+
+message SignResponse {
+ bytes cert = 1;
+}
+
+service Signer {
+ rpc Sign(SignRequest) returns (SignResponse) {}
+}
diff --git a/genstatic.sh b/regen.sh
index c05d644..f525b15 100755
--- a/genstatic.sh
+++ b/regen.sh
@@ -6,3 +6,6 @@ set -xue
go get -u github.com/mjibson/esc
${GOPATH}/bin/esc -ignore '\.go' -prefix 'server' \
-o 'server/static/static.go' -pkg 'static' 'server/static'
+
+go get -u github.com/golang/protobuf/protoc-gen-go
+protoc --go_out=plugins=grpc:. proto/signer.proto
diff --git a/run_tests.sh b/run_tests.sh
index 87d5cbd..b506438 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -13,4 +13,4 @@ go list ./... |grep -v vendor/ |xargs go vet
if ! type -f golint > /dev/null; then
go get -u github.com/golang/lint/golint
fi
-go list ./... |grep -v vendor/ |xargs -L1 golint -set_exit_status
+go list ./... |egrep -v 'vendor/|proto$' |xargs -L1 golint -set_exit_status
diff --git a/server/signer/signer.go b/server/signer/signer.go
index 2a15849..2a8fc98 100644
--- a/server/signer/signer.go
+++ b/server/signer/signer.go
@@ -10,7 +10,9 @@ import (
"go4.org/wkfs"
_ "go4.org/wkfs/gcs" // Register "/gcs/" as a wkfs.
+ "github.com/golang/protobuf/ptypes"
"github.com/nsheridan/cashier/lib"
+ "github.com/nsheridan/cashier/proto"
"github.com/nsheridan/cashier/server/config"
"github.com/nsheridan/cashier/server/store"
"github.com/stripe/krl"
@@ -51,6 +53,19 @@ func (s *KeySigner) setPermissions(cert *ssh.Certificate) {
}
}
+// SignUserKeyFromRPC returns a signed ssh certificate.
+func (s *KeySigner) SignUserKeyFromRPC(req *proto.SignRequest, username string) (*ssh.Certificate, error) {
+ valid, err := ptypes.Timestamp(req.GetValidUntil())
+ if err != nil {
+ return nil, err
+ }
+ r := &lib.SignRequest{
+ Key: string(req.GetKey()),
+ ValidUntil: valid,
+ }
+ return s.SignUserKey(r, username)
+}
+
// SignUserKey returns a signed ssh certificate.
func (s *KeySigner) SignUserKey(req *lib.SignRequest, username string) (*ssh.Certificate, error) {
pubkey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(req.Key))
diff --git a/server/store/store.go b/server/store/store.go
index d157fd1..cf69225 100644
--- a/server/store/store.go
+++ b/server/store/store.go
@@ -53,6 +53,6 @@ func parseCertificate(cert *ssh.Certificate) *CertRecord {
Principals: types.StringSlice(cert.ValidPrincipals),
CreatedAt: parseTime(cert.ValidAfter),
Expires: parseTime(cert.ValidBefore),
- Raw: lib.GetPublicKey(cert),
+ Raw: string(lib.GetPublicKey(cert)),
}
}
diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go
new file mode 100644
index 0000000..89e07ae
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/any.go
@@ -0,0 +1,136 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package ptypes
+
+// This file implements functions to marshal proto.Message to/from
+// google.protobuf.Any message.
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/ptypes/any"
+)
+
+const googleApis = "type.googleapis.com/"
+
+// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
+//
+// Note that regular type assertions should be done using the Is
+// function. AnyMessageName is provided for less common use cases like filtering a
+// sequence of Any messages based on a set of allowed message type names.
+func AnyMessageName(any *any.Any) (string, error) {
+ slash := strings.LastIndex(any.TypeUrl, "/")
+ if slash < 0 {
+ return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
+ }
+ return any.TypeUrl[slash+1:], nil
+}
+
+// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
+func MarshalAny(pb proto.Message) (*any.Any, error) {
+ value, err := proto.Marshal(pb)
+ if err != nil {
+ return nil, err
+ }
+ return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
+}
+
+// DynamicAny is a value that can be passed to UnmarshalAny to automatically
+// allocate a proto.Message for the type specified in a google.protobuf.Any
+// message. The allocated message is stored in the embedded proto.Message.
+//
+// Example:
+//
+// var x ptypes.DynamicAny
+// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
+// fmt.Printf("unmarshaled message: %v", x.Message)
+type DynamicAny struct {
+ proto.Message
+}
+
+// Empty returns a new proto.Message of the type specified in a
+// google.protobuf.Any message. It returns an error if corresponding message
+// type isn't linked in.
+func Empty(any *any.Any) (proto.Message, error) {
+ aname, err := AnyMessageName(any)
+ if err != nil {
+ return nil, err
+ }
+
+ t := proto.MessageType(aname)
+ if t == nil {
+ return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
+ }
+ return reflect.New(t.Elem()).Interface().(proto.Message), nil
+}
+
+// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
+// message and places the decoded result in pb. It returns an error if type of
+// contents of Any message does not match type of pb message.
+//
+// pb can be a proto.Message, or a *DynamicAny.
+func UnmarshalAny(any *any.Any, pb proto.Message) error {
+ if d, ok := pb.(*DynamicAny); ok {
+ if d.Message == nil {
+ var err error
+ d.Message, err = Empty(any)
+ if err != nil {
+ return err
+ }
+ }
+ return UnmarshalAny(any, d.Message)
+ }
+
+ aname, err := AnyMessageName(any)
+ if err != nil {
+ return err
+ }
+
+ mname := proto.MessageName(pb)
+ if aname != mname {
+ return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
+ }
+ return proto.Unmarshal(any.Value, pb)
+}
+
+// Is returns true if any value contains a given message type.
+func Is(any *any.Any, pb proto.Message) bool {
+ aname, err := AnyMessageName(any)
+ if err != nil {
+ return false
+ }
+
+ return aname == proto.MessageName(pb)
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
new file mode 100644
index 0000000..f2c6906
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
@@ -0,0 +1,155 @@
+// Code generated by protoc-gen-go.
+// source: github.com/golang/protobuf/ptypes/any/any.proto
+// DO NOT EDIT!
+
+/*
+Package any is a generated protocol buffer package.
+
+It is generated from these files:
+ github.com/golang/protobuf/ptypes/any/any.proto
+
+It has these top-level messages:
+ Any
+*/
+package any
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+// `Any` contains an arbitrary serialized protocol buffer message along with a
+// URL that describes the type of the serialized message.
+//
+// Protobuf library provides support to pack/unpack Any values in the form
+// of utility functions or additional generated methods of the Any type.
+//
+// Example 1: Pack and unpack a message in C++.
+//
+// Foo foo = ...;
+// Any any;
+// any.PackFrom(foo);
+// ...
+// if (any.UnpackTo(&foo)) {
+// ...
+// }
+//
+// Example 2: Pack and unpack a message in Java.
+//
+// Foo foo = ...;
+// Any any = Any.pack(foo);
+// ...
+// if (any.is(Foo.class)) {
+// foo = any.unpack(Foo.class);
+// }
+//
+// Example 3: Pack and unpack a message in Python.
+//
+// foo = Foo(...)
+// any = Any()
+// any.Pack(foo)
+// ...
+// if any.Is(Foo.DESCRIPTOR):
+// any.Unpack(foo)
+// ...
+//
+// The pack methods provided by protobuf library will by default use
+// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+// methods only use the fully qualified type name after the last '/'
+// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+// name "y.z".
+//
+//
+// JSON
+// ====
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+// package google.profile;
+// message Person {
+// string first_name = 1;
+// string last_name = 2;
+// }
+//
+// {
+// "@type": "type.googleapis.com/google.profile.Person",
+// "firstName": <string>,
+// "lastName": <string>
+// }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the `@type`
+// field. Example (for message [google.protobuf.Duration][]):
+//
+// {
+// "@type": "type.googleapis.com/google.protobuf.Duration",
+// "value": "1.212s"
+// }
+//
+type Any struct {
+ // A URL/resource name whose content describes the type of the
+ // serialized protocol buffer message.
+ //
+ // For URLs which use the scheme `http`, `https`, or no scheme, the
+ // following restrictions and interpretations apply:
+ //
+ // * If no scheme is provided, `https` is assumed.
+ // * The last segment of the URL's path must represent the fully
+ // qualified name of the type (as in `path/google.protobuf.Duration`).
+ // The name should be in a canonical form (e.g., leading "." is
+ // not accepted).
+ // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+ // value in binary format, or produce an error.
+ // * Applications are allowed to cache lookup results based on the
+ // URL, or have them precompiled into a binary to avoid any
+ // lookup. Therefore, binary compatibility needs to be preserved
+ // on changes to types. (Use versioned type names to manage
+ // breaking changes.)
+ //
+ // Schemes other than `http`, `https` (or the empty scheme) might be
+ // used with implementation specific semantics.
+ //
+ TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"`
+ // Must be a valid serialized protocol buffer of the above specified type.
+ Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *Any) Reset() { *m = Any{} }
+func (m *Any) String() string { return proto.CompactTextString(m) }
+func (*Any) ProtoMessage() {}
+func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+func (*Any) XXX_WellKnownType() string { return "Any" }
+
+func init() {
+ proto.RegisterType((*Any)(nil), "google.protobuf.Any")
+}
+
+func init() { proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+ // 187 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9,
+ 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
+ 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcc,
+ 0xab, 0x04, 0x61, 0x3d, 0xb0, 0xb8, 0x10, 0x7f, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x1e, 0x4c,
+ 0x95, 0x92, 0x19, 0x17, 0xb3, 0x63, 0x5e, 0xa5, 0x90, 0x24, 0x17, 0x07, 0x48, 0x79, 0x7c, 0x69,
+ 0x51, 0x8e, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24,
+ 0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13, 0x04, 0xe1,
+ 0x38, 0x15, 0x71, 0x09, 0x27, 0xe7, 0xe7, 0xea, 0xa1, 0x19, 0xe7, 0xc4, 0xe1, 0x98, 0x57, 0x19,
+ 0x00, 0xe2, 0x04, 0x30, 0x46, 0xa9, 0x12, 0xe5, 0xb8, 0x05, 0x8c, 0x8c, 0x8b, 0x98, 0x98, 0xdd,
+ 0x03, 0x9c, 0x56, 0x31, 0xc9, 0xb9, 0x43, 0x4c, 0x0b, 0x80, 0xaa, 0xd2, 0x0b, 0x4f, 0xcd, 0xc9,
+ 0xf1, 0xce, 0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0xa9, 0x4e, 0x62, 0x03, 0x6b, 0x37, 0x06, 0x04, 0x00,
+ 0x00, 0xff, 0xff, 0xc6, 0x4d, 0x03, 0x23, 0xf6, 0x00, 0x00, 0x00,
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.proto b/vendor/github.com/golang/protobuf/ptypes/any/any.proto
new file mode 100644
index 0000000..81dcf46
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/any/any.proto
@@ -0,0 +1,140 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/any";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "AnyProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
+option objc_class_prefix = "GPB";
+
+// `Any` contains an arbitrary serialized protocol buffer message along with a
+// URL that describes the type of the serialized message.
+//
+// Protobuf library provides support to pack/unpack Any values in the form
+// of utility functions or additional generated methods of the Any type.
+//
+// Example 1: Pack and unpack a message in C++.
+//
+// Foo foo = ...;
+// Any any;
+// any.PackFrom(foo);
+// ...
+// if (any.UnpackTo(&foo)) {
+// ...
+// }
+//
+// Example 2: Pack and unpack a message in Java.
+//
+// Foo foo = ...;
+// Any any = Any.pack(foo);
+// ...
+// if (any.is(Foo.class)) {
+// foo = any.unpack(Foo.class);
+// }
+//
+// Example 3: Pack and unpack a message in Python.
+//
+// foo = Foo(...)
+// any = Any()
+// any.Pack(foo)
+// ...
+// if any.Is(Foo.DESCRIPTOR):
+// any.Unpack(foo)
+// ...
+//
+// The pack methods provided by protobuf library will by default use
+// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+// methods only use the fully qualified type name after the last '/'
+// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+// name "y.z".
+//
+//
+// JSON
+// ====
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+// package google.profile;
+// message Person {
+// string first_name = 1;
+// string last_name = 2;
+// }
+//
+// {
+// "@type": "type.googleapis.com/google.profile.Person",
+// "firstName": <string>,
+// "lastName": <string>
+// }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the `@type`
+// field. Example (for message [google.protobuf.Duration][]):
+//
+// {
+// "@type": "type.googleapis.com/google.protobuf.Duration",
+// "value": "1.212s"
+// }
+//
+message Any {
+ // A URL/resource name whose content describes the type of the
+ // serialized protocol buffer message.
+ //
+ // For URLs which use the scheme `http`, `https`, or no scheme, the
+ // following restrictions and interpretations apply:
+ //
+ // * If no scheme is provided, `https` is assumed.
+ // * The last segment of the URL's path must represent the fully
+ // qualified name of the type (as in `path/google.protobuf.Duration`).
+ // The name should be in a canonical form (e.g., leading "." is
+ // not accepted).
+ // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+ // value in binary format, or produce an error.
+ // * Applications are allowed to cache lookup results based on the
+ // URL, or have them precompiled into a binary to avoid any
+ // lookup. Therefore, binary compatibility needs to be preserved
+ // on changes to types. (Use versioned type names to manage
+ // breaking changes.)
+ //
+ // Schemes other than `http`, `https` (or the empty scheme) might be
+ // used with implementation specific semantics.
+ //
+ string type_url = 1;
+
+ // Must be a valid serialized protocol buffer of the above specified type.
+ bytes value = 2;
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/doc.go b/vendor/github.com/golang/protobuf/ptypes/doc.go
new file mode 100644
index 0000000..c0d595d
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/doc.go
@@ -0,0 +1,35 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Package ptypes contains code for interacting with well-known types.
+*/
+package ptypes
diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go
new file mode 100644
index 0000000..65cb0f8
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/duration.go
@@ -0,0 +1,102 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package ptypes
+
+// This file implements conversions between google.protobuf.Duration
+// and time.Duration.
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ durpb "github.com/golang/protobuf/ptypes/duration"
+)
+
+const (
+ // Range of a durpb.Duration in seconds, as specified in
+ // google/protobuf/duration.proto. This is about 10,000 years in seconds.
+ maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
+ minSeconds = -maxSeconds
+)
+
+// validateDuration determines whether the durpb.Duration is valid according to the
+// definition in google/protobuf/duration.proto. A valid durpb.Duration
+// may still be too large to fit into a time.Duration (the range of durpb.Duration
+// is about 10,000 years, and the range of time.Duration is about 290).
+func validateDuration(d *durpb.Duration) error {
+ if d == nil {
+ return errors.New("duration: nil Duration")
+ }
+ if d.Seconds < minSeconds || d.Seconds > maxSeconds {
+ return fmt.Errorf("duration: %v: seconds out of range", d)
+ }
+ if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
+ return fmt.Errorf("duration: %v: nanos out of range", d)
+ }
+ // Seconds and Nanos must have the same sign, unless d.Nanos is zero.
+ if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
+ return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
+ }
+ return nil
+}
+
+// Duration converts a durpb.Duration to a time.Duration. Duration
+// returns an error if the durpb.Duration is invalid or is too large to be
+// represented in a time.Duration.
+func Duration(p *durpb.Duration) (time.Duration, error) {
+ if err := validateDuration(p); err != nil {
+ return 0, err
+ }
+ d := time.Duration(p.Seconds) * time.Second
+ if int64(d/time.Second) != p.Seconds {
+ return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
+ }
+ if p.Nanos != 0 {
+ d += time.Duration(p.Nanos)
+ if (d < 0) != (p.Nanos < 0) {
+ return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
+ }
+ }
+ return d, nil
+}
+
+// DurationProto converts a time.Duration to a durpb.Duration.
+func DurationProto(d time.Duration) *durpb.Duration {
+ nanos := d.Nanoseconds()
+ secs := nanos / 1e9
+ nanos -= secs * 1e9
+ return &durpb.Duration{
+ Seconds: secs,
+ Nanos: int32(nanos),
+ }
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
new file mode 100644
index 0000000..5697483
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
@@ -0,0 +1,114 @@
+// Code generated by protoc-gen-go.
+// source: github.com/golang/protobuf/ptypes/duration/duration.proto
+// DO NOT EDIT!
+
+/*
+Package duration is a generated protocol buffer package.
+
+It is generated from these files:
+ github.com/golang/protobuf/ptypes/duration/duration.proto
+
+It has these top-level messages:
+ Duration
+*/
+package duration
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+// A Duration represents a signed, fixed-length span of time represented
+// as a count of seconds and fractions of seconds at nanosecond
+// resolution. It is independent of any calendar and concepts like "day"
+// or "month". It is related to Timestamp in that the difference between
+// two Timestamp values is a Duration and it can be added or subtracted
+// from a Timestamp. Range is approximately +-10,000 years.
+//
+// Example 1: Compute Duration from two Timestamps in pseudo code.
+//
+// Timestamp start = ...;
+// Timestamp end = ...;
+// Duration duration = ...;
+//
+// duration.seconds = end.seconds - start.seconds;
+// duration.nanos = end.nanos - start.nanos;
+//
+// if (duration.seconds < 0 && duration.nanos > 0) {
+// duration.seconds += 1;
+// duration.nanos -= 1000000000;
+// } else if (durations.seconds > 0 && duration.nanos < 0) {
+// duration.seconds -= 1;
+// duration.nanos += 1000000000;
+// }
+//
+// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+//
+// Timestamp start = ...;
+// Duration duration = ...;
+// Timestamp end = ...;
+//
+// end.seconds = start.seconds + duration.seconds;
+// end.nanos = start.nanos + duration.nanos;
+//
+// if (end.nanos < 0) {
+// end.seconds -= 1;
+// end.nanos += 1000000000;
+// } else if (end.nanos >= 1000000000) {
+// end.seconds += 1;
+// end.nanos -= 1000000000;
+// }
+//
+//
+type Duration struct {
+ // Signed seconds of the span of time. Must be from -315,576,000,000
+ // to +315,576,000,000 inclusive.
+ Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
+ // Signed fractions of a second at nanosecond resolution of the span
+ // of time. Durations less than one second are represented with a 0
+ // `seconds` field and a positive or negative `nanos` field. For durations
+ // of one second or more, a non-zero value for the `nanos` field must be
+ // of the same sign as the `seconds` field. Must be from -999,999,999
+ // to +999,999,999 inclusive.
+ Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
+}
+
+func (m *Duration) Reset() { *m = Duration{} }
+func (m *Duration) String() string { return proto.CompactTextString(m) }
+func (*Duration) ProtoMessage() {}
+func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+func (*Duration) XXX_WellKnownType() string { return "Duration" }
+
+func init() {
+ proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
+}
+
+func init() {
+ proto.RegisterFile("github.com/golang/protobuf/ptypes/duration/duration.proto", fileDescriptor0)
+}
+
+var fileDescriptor0 = []byte{
+ // 189 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x4c, 0xcf, 0x2c, 0xc9,
+ 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
+ 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0x29,
+ 0x2d, 0x4a, 0x2c, 0xc9, 0xcc, 0xcf, 0x83, 0x33, 0xf4, 0xc0, 0x2a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3,
+ 0xd3, 0x73, 0x52, 0xf5, 0x60, 0xea, 0x95, 0xac, 0xb8, 0x38, 0x5c, 0xa0, 0x4a, 0x84, 0x24, 0xb8,
+ 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60,
+ 0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d, 0xd6,
+ 0x20, 0x08, 0xc7, 0xa9, 0x86, 0x4b, 0x38, 0x39, 0x3f, 0x57, 0x0f, 0xcd, 0x48, 0x27, 0x5e, 0x98,
+ 0x81, 0x01, 0x20, 0x91, 0x00, 0xc6, 0x28, 0x2d, 0xe2, 0xdd, 0xbb, 0x80, 0x91, 0x71, 0x11, 0x13,
+ 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xb9, 0x01, 0x50, 0xa5, 0x7a, 0xe1, 0xa9,
+ 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x2d, 0x49, 0x6c, 0x60, 0x33, 0x8c, 0x01,
+ 0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0xfb, 0xb1, 0x51, 0x0e, 0x01, 0x00, 0x00,
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto b/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto
new file mode 100644
index 0000000..96c1796
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/duration";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DurationProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
+option objc_class_prefix = "GPB";
+
+// A Duration represents a signed, fixed-length span of time represented
+// as a count of seconds and fractions of seconds at nanosecond
+// resolution. It is independent of any calendar and concepts like "day"
+// or "month". It is related to Timestamp in that the difference between
+// two Timestamp values is a Duration and it can be added or subtracted
+// from a Timestamp. Range is approximately +-10,000 years.
+//
+// Example 1: Compute Duration from two Timestamps in pseudo code.
+//
+// Timestamp start = ...;
+// Timestamp end = ...;
+// Duration duration = ...;
+//
+// duration.seconds = end.seconds - start.seconds;
+// duration.nanos = end.nanos - start.nanos;
+//
+// if (duration.seconds < 0 && duration.nanos > 0) {
+// duration.seconds += 1;
+// duration.nanos -= 1000000000;
+// } else if (durations.seconds > 0 && duration.nanos < 0) {
+// duration.seconds -= 1;
+// duration.nanos += 1000000000;
+// }
+//
+// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+//
+// Timestamp start = ...;
+// Duration duration = ...;
+// Timestamp end = ...;
+//
+// end.seconds = start.seconds + duration.seconds;
+// end.nanos = start.nanos + duration.nanos;
+//
+// if (end.nanos < 0) {
+// end.seconds -= 1;
+// end.nanos += 1000000000;
+// } else if (end.nanos >= 1000000000) {
+// end.seconds += 1;
+// end.nanos -= 1000000000;
+// }
+//
+//
+message Duration {
+
+ // Signed seconds of the span of time. Must be from -315,576,000,000
+ // to +315,576,000,000 inclusive.
+ int64 seconds = 1;
+
+ // Signed fractions of a second at nanosecond resolution of the span
+ // of time. Durations less than one second are represented with a 0
+ // `seconds` field and a positive or negative `nanos` field. For durations
+ // of one second or more, a non-zero value for the `nanos` field must be
+ // of the same sign as the `seconds` field. Must be from -999,999,999
+ // to +999,999,999 inclusive.
+ int32 nanos = 2;
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/regen.sh b/vendor/github.com/golang/protobuf/ptypes/regen.sh
new file mode 100755
index 0000000..2a5b4e8
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/regen.sh
@@ -0,0 +1,66 @@
+#!/bin/bash -e
+#
+# This script fetches and rebuilds the "well-known types" protocol buffers.
+# To run this you will need protoc and goprotobuf installed;
+# see https://github.com/golang/protobuf for instructions.
+# You also need Go and Git installed.
+
+PKG=github.com/golang/protobuf/ptypes
+UPSTREAM=https://github.com/google/protobuf
+UPSTREAM_SUBDIR=src/google/protobuf
+PROTO_FILES='
+ any.proto
+ duration.proto
+ empty.proto
+ struct.proto
+ timestamp.proto
+ wrappers.proto
+'
+
+function die() {
+ echo 1>&2 $*
+ exit 1
+}
+
+# Sanity check that the right tools are accessible.
+for tool in go git protoc protoc-gen-go; do
+ q=$(which $tool) || die "didn't find $tool"
+ echo 1>&2 "$tool: $q"
+done
+
+tmpdir=$(mktemp -d -t regen-wkt.XXXXXX)
+trap 'rm -rf $tmpdir' EXIT
+
+echo -n 1>&2 "finding package dir... "
+pkgdir=$(go list -f '{{.Dir}}' $PKG)
+echo 1>&2 $pkgdir
+base=$(echo $pkgdir | sed "s,/$PKG\$,,")
+echo 1>&2 "base: $base"
+cd $base
+
+echo 1>&2 "fetching latest protos... "
+git clone -q $UPSTREAM $tmpdir
+# Pass 1: build mapping from upstream filename to our filename.
+declare -A filename_map
+for f in $(cd $PKG && find * -name '*.proto'); do
+ echo -n 1>&2 "looking for latest version of $f... "
+ up=$(cd $tmpdir/$UPSTREAM_SUBDIR && find * -name $(basename $f) | grep -v /testdata/)
+ echo 1>&2 $up
+ if [ $(echo $up | wc -w) != "1" ]; then
+ die "not exactly one match"
+ fi
+ filename_map[$up]=$f
+done
+# Pass 2: copy files
+for up in "${!filename_map[@]}"; do
+ f=${filename_map[$up]}
+ shortname=$(basename $f | sed 's,\.proto$,,')
+ cp $tmpdir/$UPSTREAM_SUBDIR/$up $PKG/$f
+done
+
+# Run protoc once per package.
+for dir in $(find $PKG -name '*.proto' | xargs dirname | sort | uniq); do
+ echo 1>&2 "* $dir"
+ protoc --go_out=. $dir/*.proto
+done
+echo 1>&2 "All OK"
diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go
new file mode 100644
index 0000000..1b36576
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/timestamp.go
@@ -0,0 +1,125 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package ptypes
+
+// This file implements operations on google.protobuf.Timestamp.
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ tspb "github.com/golang/protobuf/ptypes/timestamp"
+)
+
+const (
+ // Seconds field of the earliest valid Timestamp.
+ // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
+ minValidSeconds = -62135596800
+ // Seconds field just after the latest valid Timestamp.
+ // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
+ maxValidSeconds = 253402300800
+)
+
+// validateTimestamp determines whether a Timestamp is valid.
+// A valid timestamp represents a time in the range
+// [0001-01-01, 10000-01-01) and has a Nanos field
+// in the range [0, 1e9).
+//
+// If the Timestamp is valid, validateTimestamp returns nil.
+// Otherwise, it returns an error that describes
+// the problem.
+//
+// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
+func validateTimestamp(ts *tspb.Timestamp) error {
+ if ts == nil {
+ return errors.New("timestamp: nil Timestamp")
+ }
+ if ts.Seconds < minValidSeconds {
+ return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
+ }
+ if ts.Seconds >= maxValidSeconds {
+ return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
+ }
+ if ts.Nanos < 0 || ts.Nanos >= 1e9 {
+ return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
+ }
+ return nil
+}
+
+// Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
+// It returns an error if the argument is invalid.
+//
+// Unlike most Go functions, if Timestamp returns an error, the first return value
+// is not the zero time.Time. Instead, it is the value obtained from the
+// time.Unix function when passed the contents of the Timestamp, in the UTC
+// locale. This may or may not be a meaningful time; many invalid Timestamps
+// do map to valid time.Times.
+//
+// A nil Timestamp returns an error. The first return value in that case is
+// undefined.
+func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
+ // Don't return the zero value on error, because corresponds to a valid
+ // timestamp. Instead return whatever time.Unix gives us.
+ var t time.Time
+ if ts == nil {
+ t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
+ } else {
+ t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
+ }
+ return t, validateTimestamp(ts)
+}
+
+// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
+// It returns an error if the resulting Timestamp is invalid.
+func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
+ seconds := t.Unix()
+ nanos := int32(t.Sub(time.Unix(seconds, 0)))
+ ts := &tspb.Timestamp{
+ Seconds: seconds,
+ Nanos: nanos,
+ }
+ if err := validateTimestamp(ts); err != nil {
+ return nil, err
+ }
+ return ts, nil
+}
+
+// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
+// Timestamps, it returns an error message in parentheses.
+func TimestampString(ts *tspb.Timestamp) string {
+ t, err := Timestamp(ts)
+ if err != nil {
+ return fmt.Sprintf("(%v)", err)
+ }
+ return t.Format(time.RFC3339Nano)
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go
new file mode 100644
index 0000000..ffcc515
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go
@@ -0,0 +1,127 @@
+// Code generated by protoc-gen-go.
+// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
+// DO NOT EDIT!
+
+/*
+Package timestamp is a generated protocol buffer package.
+
+It is generated from these files:
+ github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
+
+It has these top-level messages:
+ Timestamp
+*/
+package timestamp
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+// A Timestamp represents a point in time independent of any time zone
+// or calendar, represented as seconds and fractions of seconds at
+// nanosecond resolution in UTC Epoch time. It is encoded using the
+// Proleptic Gregorian Calendar which extends the Gregorian calendar
+// backwards to year one. It is encoded assuming all minutes are 60
+// seconds long, i.e. leap seconds are "smeared" so that no leap second
+// table is needed for interpretation. Range is from
+// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+// By restricting to that range, we ensure that we can convert to
+// and from RFC 3339 date strings.
+// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
+//
+// Example 1: Compute Timestamp from POSIX `time()`.
+//
+// Timestamp timestamp;
+// timestamp.set_seconds(time(NULL));
+// timestamp.set_nanos(0);
+//
+// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+//
+// struct timeval tv;
+// gettimeofday(&tv, NULL);
+//
+// Timestamp timestamp;
+// timestamp.set_seconds(tv.tv_sec);
+// timestamp.set_nanos(tv.tv_usec * 1000);
+//
+// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+//
+// FILETIME ft;
+// GetSystemTimeAsFileTime(&ft);
+// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+//
+// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+// Timestamp timestamp;
+// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+//
+// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+//
+// long millis = System.currentTimeMillis();
+//
+// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+// .setNanos((int) ((millis % 1000) * 1000000)).build();
+//
+//
+// Example 5: Compute Timestamp from current time in Python.
+//
+// now = time.time()
+// seconds = int(now)
+// nanos = int((now - seconds) * 10**9)
+// timestamp = Timestamp(seconds=seconds, nanos=nanos)
+//
+//
+type Timestamp struct {
+ // Represents seconds of UTC time since Unix epoch
+ // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+ // 9999-12-31T23:59:59Z inclusive.
+ Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
+ // Non-negative fractions of a second at nanosecond resolution. Negative
+ // second values with fractions must still have non-negative nanos values
+ // that count forward in time. Must be from 0 to 999,999,999
+ // inclusive.
+ Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
+}
+
+func (m *Timestamp) Reset() { *m = Timestamp{} }
+func (m *Timestamp) String() string { return proto.CompactTextString(m) }
+func (*Timestamp) ProtoMessage() {}
+func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" }
+
+func init() {
+ proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
+}
+
+func init() {
+ proto.RegisterFile("github.com/golang/protobuf/ptypes/timestamp/timestamp.proto", fileDescriptor0)
+}
+
+var fileDescriptor0 = []byte{
+ // 194 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x4e, 0xcf, 0x2c, 0xc9,
+ 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
+ 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0xc9,
+ 0xcc, 0x4d, 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0x40, 0xb0, 0xf4, 0xc0, 0x6a, 0x84, 0xf8, 0xd3, 0xf3,
+ 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x60, 0x3a, 0x94, 0xac, 0xb9, 0x38, 0x43, 0x60, 0x6a, 0x84, 0x24,
+ 0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83,
+ 0x60, 0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d,
+ 0xd6, 0x20, 0x08, 0xc7, 0xa9, 0x91, 0x91, 0x4b, 0x38, 0x39, 0x3f, 0x57, 0x0f, 0xcd, 0x50, 0x27,
+ 0x3e, 0xb8, 0x91, 0x01, 0x20, 0xa1, 0x00, 0xc6, 0x28, 0x6d, 0x12, 0x1c, 0xbd, 0x80, 0x91, 0xf1,
+ 0x07, 0x23, 0xe3, 0x22, 0x26, 0x66, 0xf7, 0x00, 0xa7, 0x55, 0x4c, 0x72, 0xee, 0x10, 0xc3, 0x03,
+ 0xa0, 0xca, 0xf5, 0xc2, 0x53, 0x73, 0x72, 0xbc, 0xf3, 0xf2, 0xcb, 0xf3, 0x42, 0x40, 0xda, 0x92,
+ 0xd8, 0xc0, 0xe6, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x17, 0x5f, 0xb7, 0xdc, 0x17, 0x01,
+ 0x00, 0x00,
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
new file mode 100644
index 0000000..7992a85
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
@@ -0,0 +1,111 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option cc_enable_arenas = true;
+option go_package = "github.com/golang/protobuf/ptypes/timestamp";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "TimestampProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
+option objc_class_prefix = "GPB";
+
+// A Timestamp represents a point in time independent of any time zone
+// or calendar, represented as seconds and fractions of seconds at
+// nanosecond resolution in UTC Epoch time. It is encoded using the
+// Proleptic Gregorian Calendar which extends the Gregorian calendar
+// backwards to year one. It is encoded assuming all minutes are 60
+// seconds long, i.e. leap seconds are "smeared" so that no leap second
+// table is needed for interpretation. Range is from
+// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+// By restricting to that range, we ensure that we can convert to
+// and from RFC 3339 date strings.
+// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
+//
+// Example 1: Compute Timestamp from POSIX `time()`.
+//
+// Timestamp timestamp;
+// timestamp.set_seconds(time(NULL));
+// timestamp.set_nanos(0);
+//
+// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+//
+// struct timeval tv;
+// gettimeofday(&tv, NULL);
+//
+// Timestamp timestamp;
+// timestamp.set_seconds(tv.tv_sec);
+// timestamp.set_nanos(tv.tv_usec * 1000);
+//
+// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+//
+// FILETIME ft;
+// GetSystemTimeAsFileTime(&ft);
+// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+//
+// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+// Timestamp timestamp;
+// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+//
+// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+//
+// long millis = System.currentTimeMillis();
+//
+// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+// .setNanos((int) ((millis % 1000) * 1000000)).build();
+//
+//
+// Example 5: Compute Timestamp from current time in Python.
+//
+// now = time.time()
+// seconds = int(now)
+// nanos = int((now - seconds) * 10**9)
+// timestamp = Timestamp(seconds=seconds, nanos=nanos)
+//
+//
+message Timestamp {
+
+ // Represents seconds of UTC time since Unix epoch
+ // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+ // 9999-12-31T23:59:59Z inclusive.
+ int64 seconds = 1;
+
+ // Non-negative fractions of a second at nanosecond resolution. Negative
+ // second values with fractions must still have non-negative nanos values
+ // that count forward in time. Must be from 0 to 999,999,999
+ // inclusive.
+ int32 nanos = 2;
+}
diff --git a/vendor/github.com/soheilhy/cmux/CONTRIBUTORS b/vendor/github.com/soheilhy/cmux/CONTRIBUTORS
new file mode 100644
index 0000000..49878f2
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/CONTRIBUTORS
@@ -0,0 +1,12 @@
+# The list of people who have contributed code to the cmux repository.
+#
+# Auto-generated with:
+# git log --oneline --pretty=format:'%an <%aE>' | sort -u
+#
+Andreas Jaekle <andreas@jaekle.net>
+Dmitri Shuralyov <shurcooL@gmail.com>
+Ethan Mosbaugh <emosbaugh@gmail.com>
+Soheil Hassas Yeganeh <soheil.h.y@gmail.com>
+Soheil Hassas Yeganeh <soheil@cs.toronto.edu>
+Tamir Duberstein <tamir@cockroachlabs.com>
+Tamir Duberstein <tamird@gmail.com>
diff --git a/vendor/github.com/soheilhy/cmux/LICENSE b/vendor/github.com/soheilhy/cmux/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/soheilhy/cmux/README.md b/vendor/github.com/soheilhy/cmux/README.md
new file mode 100644
index 0000000..b1c75a7
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/README.md
@@ -0,0 +1,83 @@
+# cmux: Connection Mux ![Travis Build Status](https://api.travis-ci.org/soheilhy/args.svg?branch=master "Travis Build Status") [![GoDoc](https://godoc.org/github.com/soheilhy/cmux?status.svg)](http://godoc.org/github.com/soheilhy/cmux)
+
+cmux is a generic Go library to multiplex connections based on
+their payload. Using cmux, you can serve gRPC, SSH, HTTPS, HTTP,
+Go RPC, and pretty much any other protocol on the same TCP listener.
+
+## How-To
+Simply create your main listener, create a cmux for that listener,
+and then match connections:
+```go
+// Create the main listener.
+l, err := net.Listen("tcp", ":23456")
+if err != nil {
+ log.Fatal(err)
+}
+
+// Create a cmux.
+m := cmux.New(l)
+
+// Match connections in order:
+// First grpc, then HTTP, and otherwise Go RPC/TCP.
+grpcL := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
+httpL := m.Match(cmux.HTTP1Fast())
+trpcL := m.Match(cmux.Any()) // Any means anything that is not yet matched.
+
+// Create your protocol servers.
+grpcS := grpc.NewServer()
+grpchello.RegisterGreeterServer(grpcs, &server{})
+
+httpS := &http.Server{
+ Handler: &helloHTTP1Handler{},
+}
+
+trpcS := rpc.NewServer()
+s.Register(&ExampleRPCRcvr{})
+
+// Use the muxed listeners for your servers.
+go grpcS.Serve(grpcL)
+go httpS.Serve(httpL)
+go trpcS.Accept(trpcL)
+
+// Start serving!
+m.Serve()
+```
+
+Take a look at [other examples in the GoDoc](http://godoc.org/github.com/soheilhy/cmux/#pkg-examples).
+
+## Docs
+* [GoDocs](https://godoc.org/github.com/soheilhy/cmux)
+
+## Performance
+There is room for improvment but, since we are only matching
+the very first bytes of a connection, the performance overheads on
+long-lived connections (i.e., RPCs and pipelined HTTP streams)
+is negligible.
+
+*TODO(soheil)*: Add benchmarks.
+
+## Limitations
+* *TLS*: `net/http` uses a type assertion to identify TLS connections; since
+cmux's lookahead-implementing connection wraps the underlying TLS connection,
+this type assertion fails.
+Because of that, you can serve HTTPS using cmux but `http.Request.TLS`
+would not be set in your handlers.
+
+* *Different Protocols on The Same Connection*: `cmux` matches the connection
+when it's accepted. For example, one connection can be either gRPC or REST, but
+not both. That is, we assume that a client connection is either used for gRPC
+or REST.
+
+* *Java gRPC Clients*: Java gRPC client blocks until it receives a SETTINGS
+frame from the server. If you are using the Java client to connect to a cmux'ed
+gRPC server please match with writers:
+```go
+grpcl := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"))
+```
+
+# Copyright and License
+Copyright 2016 The CMux Authors. All rights reserved.
+
+See [CONTRIBUTORS](https://github.com/soheilhy/cmux/blob/master/CONTRIBUTORS)
+for the CMux Authors. Code is released under
+[the Apache 2 license](https://github.com/soheilhy/cmux/blob/master/LICENSE).
diff --git a/vendor/github.com/soheilhy/cmux/buffer.go b/vendor/github.com/soheilhy/cmux/buffer.go
new file mode 100644
index 0000000..f8cf30a
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/buffer.go
@@ -0,0 +1,67 @@
+// Copyright 2016 The CMux Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied. See the License for the specific language governing
+// permissions and limitations under the License.
+
+package cmux
+
+import (
+ "bytes"
+ "io"
+)
+
+// bufferedReader is an optimized implementation of io.Reader that behaves like
+// ```
+// io.MultiReader(bytes.NewReader(buffer.Bytes()), io.TeeReader(source, buffer))
+// ```
+// without allocating.
+type bufferedReader struct {
+ source io.Reader
+ buffer bytes.Buffer
+ bufferRead int
+ bufferSize int
+ sniffing bool
+ lastErr error
+}
+
+func (s *bufferedReader) Read(p []byte) (int, error) {
+ if s.bufferSize > s.bufferRead {
+ // If we have already read something from the buffer before, we return the
+ // same data and the last error if any. We need to immediately return,
+ // otherwise we may block for ever, if we try to be smart and call
+ // source.Read() seeking a little bit of more data.
+ bn := copy(p, s.buffer.Bytes()[s.bufferRead:s.bufferSize])
+ s.bufferRead += bn
+ return bn, s.lastErr
+ } else if !s.sniffing && s.buffer.Cap() != 0 {
+ // We don't need the buffer anymore.
+ // Reset it to release the internal slice.
+ s.buffer = bytes.Buffer{}
+ }
+
+ // If there is nothing more to return in the sniffed buffer, read from the
+ // source.
+ sn, sErr := s.source.Read(p)
+ if sn > 0 && s.sniffing {
+ s.lastErr = sErr
+ if wn, wErr := s.buffer.Write(p[:sn]); wErr != nil {
+ return wn, wErr
+ }
+ }
+ return sn, sErr
+}
+
+func (s *bufferedReader) reset(snif bool) {
+ s.sniffing = snif
+ s.bufferRead = 0
+ s.bufferSize = s.buffer.Len()
+}
diff --git a/vendor/github.com/soheilhy/cmux/cmux.go b/vendor/github.com/soheilhy/cmux/cmux.go
new file mode 100644
index 0000000..9de6b0a
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/cmux.go
@@ -0,0 +1,269 @@
+// Copyright 2016 The CMux Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied. See the License for the specific language governing
+// permissions and limitations under the License.
+
+package cmux
+
+import (
+ "fmt"
+ "io"
+ "net"
+ "sync"
+ "time"
+)
+
+// Matcher matches a connection based on its content.
+type Matcher func(io.Reader) bool
+
+// MatchWriter is a match that can also write response (say to do handshake).
+type MatchWriter func(io.Writer, io.Reader) bool
+
+// ErrorHandler handles an error and returns whether
+// the mux should continue serving the listener.
+type ErrorHandler func(error) bool
+
+var _ net.Error = ErrNotMatched{}
+
+// ErrNotMatched is returned whenever a connection is not matched by any of
+// the matchers registered in the multiplexer.
+type ErrNotMatched struct {
+ c net.Conn
+}
+
+func (e ErrNotMatched) Error() string {
+ return fmt.Sprintf("mux: connection %v not matched by an matcher",
+ e.c.RemoteAddr())
+}
+
+// Temporary implements the net.Error interface.
+func (e ErrNotMatched) Temporary() bool { return true }
+
+// Timeout implements the net.Error interface.
+func (e ErrNotMatched) Timeout() bool { return false }
+
+type errListenerClosed string
+
+func (e errListenerClosed) Error() string { return string(e) }
+func (e errListenerClosed) Temporary() bool { return false }
+func (e errListenerClosed) Timeout() bool { return false }
+
+// ErrListenerClosed is returned from muxListener.Accept when the underlying
+// listener is closed.
+var ErrListenerClosed = errListenerClosed("mux: listener closed")
+
+// for readability of readTimeout
+var noTimeout time.Duration
+
+// New instantiates a new connection multiplexer.
+func New(l net.Listener) CMux {
+ return &cMux{
+ root: l,
+ bufLen: 1024,
+ errh: func(_ error) bool { return true },
+ donec: make(chan struct{}),
+ readTimeout: noTimeout,
+ }
+}
+
+// CMux is a multiplexer for network connections.
+type CMux interface {
+ // Match returns a net.Listener that sees (i.e., accepts) only
+ // the connections matched by at least one of the matcher.
+ //
+ // The order used to call Match determines the priority of matchers.
+ Match(...Matcher) net.Listener
+ // MatchWithWriters returns a net.Listener that accepts only the
+ // connections that matched by at least of the matcher writers.
+ //
+ // Prefer Matchers over MatchWriters, since the latter can write on the
+ // connection before the actual handler.
+ //
+ // The order used to call Match determines the priority of matchers.
+ MatchWithWriters(...MatchWriter) net.Listener
+ // Serve starts multiplexing the listener. Serve blocks and perhaps
+ // should be invoked concurrently within a go routine.
+ Serve() error
+ // HandleError registers an error handler that handles listener errors.
+ HandleError(ErrorHandler)
+ // sets a timeout for the read of matchers
+ SetReadTimeout(time.Duration)
+}
+
+type matchersListener struct {
+ ss []MatchWriter
+ l muxListener
+}
+
+type cMux struct {
+ root net.Listener
+ bufLen int
+ errh ErrorHandler
+ donec chan struct{}
+ sls []matchersListener
+ readTimeout time.Duration
+}
+
+func matchersToMatchWriters(matchers []Matcher) []MatchWriter {
+ mws := make([]MatchWriter, 0, len(matchers))
+ for _, m := range matchers {
+ mws = append(mws, func(w io.Writer, r io.Reader) bool {
+ return m(r)
+ })
+ }
+ return mws
+}
+
+func (m *cMux) Match(matchers ...Matcher) net.Listener {
+ mws := matchersToMatchWriters(matchers)
+ return m.MatchWithWriters(mws...)
+}
+
+func (m *cMux) MatchWithWriters(matchers ...MatchWriter) net.Listener {
+ ml := muxListener{
+ Listener: m.root,
+ connc: make(chan net.Conn, m.bufLen),
+ }
+ m.sls = append(m.sls, matchersListener{ss: matchers, l: ml})
+ return ml
+}
+
+func (m *cMux) SetReadTimeout(t time.Duration) {
+ m.readTimeout = t
+}
+
+func (m *cMux) Serve() error {
+ var wg sync.WaitGroup
+
+ defer func() {
+ close(m.donec)
+ wg.Wait()
+
+ for _, sl := range m.sls {
+ close(sl.l.connc)
+ // Drain the connections enqueued for the listener.
+ for c := range sl.l.connc {
+ _ = c.Close()
+ }
+ }
+ }()
+
+ for {
+ c, err := m.root.Accept()
+ if err != nil {
+ if !m.handleErr(err) {
+ return err
+ }
+ continue
+ }
+
+ wg.Add(1)
+ go m.serve(c, m.donec, &wg)
+ }
+}
+
+func (m *cMux) serve(c net.Conn, donec <-chan struct{}, wg *sync.WaitGroup) {
+ defer wg.Done()
+
+ muc := newMuxConn(c)
+ if m.readTimeout > noTimeout {
+ _ = c.SetReadDeadline(time.Now().Add(m.readTimeout))
+ }
+ for _, sl := range m.sls {
+ for _, s := range sl.ss {
+ matched := s(muc.Conn, muc.startSniffing())
+ if matched {
+ muc.doneSniffing()
+ if m.readTimeout > noTimeout {
+ _ = c.SetReadDeadline(time.Time{})
+ }
+ select {
+ case sl.l.connc <- muc:
+ case <-donec:
+ _ = c.Close()
+ }
+ return
+ }
+ }
+ }
+
+ _ = c.Close()
+ err := ErrNotMatched{c: c}
+ if !m.handleErr(err) {
+ _ = m.root.Close()
+ }
+}
+
+func (m *cMux) HandleError(h ErrorHandler) {
+ m.errh = h
+}
+
+func (m *cMux) handleErr(err error) bool {
+ if !m.errh(err) {
+ return false
+ }
+
+ if ne, ok := err.(net.Error); ok {
+ return ne.Temporary()
+ }
+
+ return false
+}
+
+type muxListener struct {
+ net.Listener
+ connc chan net.Conn
+}
+
+func (l muxListener) Accept() (net.Conn, error) {
+ c, ok := <-l.connc
+ if !ok {
+ return nil, ErrListenerClosed
+ }
+ return c, nil
+}
+
+// MuxConn wraps a net.Conn and provides transparent sniffing of connection data.
+type MuxConn struct {
+ net.Conn
+ buf bufferedReader
+}
+
+func newMuxConn(c net.Conn) *MuxConn {
+ return &MuxConn{
+ Conn: c,
+ buf: bufferedReader{source: c},
+ }
+}
+
+// From the io.Reader documentation:
+//
+// When Read encounters an error or end-of-file condition after
+// successfully reading n > 0 bytes, it returns the number of
+// bytes read. It may return the (non-nil) error from the same call
+// or return the error (and n == 0) from a subsequent call.
+// An instance of this general case is that a Reader returning
+// a non-zero number of bytes at the end of the input stream may
+// return either err == EOF or err == nil. The next Read should
+// return 0, EOF.
+func (m *MuxConn) Read(p []byte) (int, error) {
+ return m.buf.Read(p)
+}
+
+func (m *MuxConn) startSniffing() io.Reader {
+ m.buf.reset(true)
+ return &m.buf
+}
+
+func (m *MuxConn) doneSniffing() {
+ m.buf.reset(false)
+}
diff --git a/vendor/github.com/soheilhy/cmux/doc.go b/vendor/github.com/soheilhy/cmux/doc.go
new file mode 100644
index 0000000..aaa8f31
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/doc.go
@@ -0,0 +1,18 @@
+// Copyright 2016 The CMux Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied. See the License for the specific language governing
+// permissions and limitations under the License.
+
+// Package cmux is a library to multiplex network connections based on
+// their payload. Using cmux, you can serve different protocols from the
+// same listener.
+package cmux
diff --git a/vendor/github.com/soheilhy/cmux/matchers.go b/vendor/github.com/soheilhy/cmux/matchers.go
new file mode 100644
index 0000000..485ede8
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/matchers.go
@@ -0,0 +1,184 @@
+// Copyright 2016 The CMux Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied. See the License for the specific language governing
+// permissions and limitations under the License.
+
+package cmux
+
+import (
+ "bufio"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strings"
+
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/hpack"
+)
+
+// Any is a Matcher that matches any connection.
+func Any() Matcher {
+ return func(r io.Reader) bool { return true }
+}
+
+// PrefixMatcher returns a matcher that matches a connection if it
+// starts with any of the strings in strs.
+func PrefixMatcher(strs ...string) Matcher {
+ pt := newPatriciaTreeString(strs...)
+ return pt.matchPrefix
+}
+
+var defaultHTTPMethods = []string{
+ "OPTIONS",
+ "GET",
+ "HEAD",
+ "POST",
+ "PUT",
+ "DELETE",
+ "TRACE",
+ "CONNECT",
+}
+
+// HTTP1Fast only matches the methods in the HTTP request.
+//
+// This matcher is very optimistic: if it returns true, it does not mean that
+// the request is a valid HTTP response. If you want a correct but slower HTTP1
+// matcher, use HTTP1 instead.
+func HTTP1Fast(extMethods ...string) Matcher {
+ return PrefixMatcher(append(defaultHTTPMethods, extMethods...)...)
+}
+
+const maxHTTPRead = 4096
+
+// HTTP1 parses the first line or upto 4096 bytes of the request to see if
+// the conection contains an HTTP request.
+func HTTP1() Matcher {
+ return func(r io.Reader) bool {
+ br := bufio.NewReader(&io.LimitedReader{R: r, N: maxHTTPRead})
+ l, part, err := br.ReadLine()
+ if err != nil || part {
+ return false
+ }
+
+ _, _, proto, ok := parseRequestLine(string(l))
+ if !ok {
+ return false
+ }
+
+ v, _, ok := http.ParseHTTPVersion(proto)
+ return ok && v == 1
+ }
+}
+
+// grabbed from net/http.
+func parseRequestLine(line string) (method, uri, proto string, ok bool) {
+ s1 := strings.Index(line, " ")
+ s2 := strings.Index(line[s1+1:], " ")
+ if s1 < 0 || s2 < 0 {
+ return
+ }
+ s2 += s1 + 1
+ return line[:s1], line[s1+1 : s2], line[s2+1:], true
+}
+
+// HTTP2 parses the frame header of the first frame to detect whether the
+// connection is an HTTP2 connection.
+func HTTP2() Matcher {
+ return hasHTTP2Preface
+}
+
+// HTTP1HeaderField returns a matcher matching the header fields of the first
+// request of an HTTP 1 connection.
+func HTTP1HeaderField(name, value string) Matcher {
+ return func(r io.Reader) bool {
+ return matchHTTP1Field(r, name, value)
+ }
+}
+
+// HTTP2HeaderField resturns a matcher matching the header fields of the first
+// headers frame.
+func HTTP2HeaderField(name, value string) Matcher {
+ return func(r io.Reader) bool {
+ return matchHTTP2Field(ioutil.Discard, r, name, value)
+ }
+}
+
+// HTTP2MatchHeaderFieldSendSettings matches the header field and writes the
+// settings to the server. Prefer HTTP2HeaderField over this one, if the client
+// does not block on receiving a SETTING frame.
+func HTTP2MatchHeaderFieldSendSettings(name, value string) MatchWriter {
+ return func(w io.Writer, r io.Reader) bool {
+ return matchHTTP2Field(w, r, name, value)
+ }
+}
+
+func hasHTTP2Preface(r io.Reader) bool {
+ var b [len(http2.ClientPreface)]byte
+ if _, err := io.ReadFull(r, b[:]); err != nil {
+ return false
+ }
+
+ return string(b[:]) == http2.ClientPreface
+}
+
+func matchHTTP1Field(r io.Reader, name, value string) (matched bool) {
+ req, err := http.ReadRequest(bufio.NewReader(r))
+ if err != nil {
+ return false
+ }
+
+ return req.Header.Get(name) == value
+}
+
+func matchHTTP2Field(w io.Writer, r io.Reader, name, value string) (matched bool) {
+ if !hasHTTP2Preface(r) {
+ return false
+ }
+
+ done := false
+ framer := http2.NewFramer(w, r)
+ hdec := hpack.NewDecoder(uint32(4<<10), func(hf hpack.HeaderField) {
+ if hf.Name == name {
+ done = true
+ if hf.Value == value {
+ matched = true
+ }
+ }
+ })
+ for {
+ f, err := framer.ReadFrame()
+ if err != nil {
+ return false
+ }
+
+ switch f := f.(type) {
+ case *http2.SettingsFrame:
+ if err := framer.WriteSettings(); err != nil {
+ return false
+ }
+ case *http2.ContinuationFrame:
+ if _, err := hdec.Write(f.HeaderBlockFragment()); err != nil {
+ return false
+ }
+ done = done || f.FrameHeader.Flags&http2.FlagHeadersEndHeaders != 0
+ case *http2.HeadersFrame:
+ if _, err := hdec.Write(f.HeaderBlockFragment()); err != nil {
+ return false
+ }
+ done = done || f.FrameHeader.Flags&http2.FlagHeadersEndHeaders != 0
+ }
+
+ if done {
+ return matched
+ }
+ }
+}
diff --git a/vendor/github.com/soheilhy/cmux/patricia.go b/vendor/github.com/soheilhy/cmux/patricia.go
new file mode 100644
index 0000000..c3e3d85
--- /dev/null
+++ b/vendor/github.com/soheilhy/cmux/patricia.go
@@ -0,0 +1,179 @@
+// Copyright 2016 The CMux Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied. See the License for the specific language governing
+// permissions and limitations under the License.
+
+package cmux
+
+import (
+ "bytes"
+ "io"
+)
+
+// patriciaTree is a simple patricia tree that handles []byte instead of string
+// and cannot be changed after instantiation.
+type patriciaTree struct {
+ root *ptNode
+ maxDepth int // max depth of the tree.
+}
+
+func newPatriciaTree(bs ...[]byte) *patriciaTree {
+ max := 0
+ for _, b := range bs {
+ if max < len(b) {
+ max = len(b)
+ }
+ }
+ return &patriciaTree{
+ root: newNode(bs),
+ maxDepth: max + 1,
+ }
+}
+
+func newPatriciaTreeString(strs ...string) *patriciaTree {
+ b := make([][]byte, len(strs))
+ for i, s := range strs {
+ b[i] = []byte(s)
+ }
+ return newPatriciaTree(b...)
+}
+
+func (t *patriciaTree) matchPrefix(r io.Reader) bool {
+ buf := make([]byte, t.maxDepth)
+ n, _ := io.ReadFull(r, buf)
+ return t.root.match(buf[:n], true)
+}
+
+func (t *patriciaTree) match(r io.Reader) bool {
+ buf := make([]byte, t.maxDepth)
+ n, _ := io.ReadFull(r, buf)
+ return t.root.match(buf[:n], false)
+}
+
+type ptNode struct {
+ prefix []byte
+ next map[byte]*ptNode
+ terminal bool
+}
+
+func newNode(strs [][]byte) *ptNode {
+ if len(strs) == 0 {
+ return &ptNode{
+ prefix: []byte{},
+ terminal: true,
+ }
+ }
+
+ if len(strs) == 1 {
+ return &ptNode{
+ prefix: strs[0],
+ terminal: true,
+ }
+ }
+
+ p, strs := splitPrefix(strs)
+ n := &ptNode{
+ prefix: p,
+ }
+
+ nexts := make(map[byte][][]byte)
+ for _, s := range strs {
+ if len(s) == 0 {
+ n.terminal = true
+ continue
+ }
+ nexts[s[0]] = append(nexts[s[0]], s[1:])
+ }
+
+ n.next = make(map[byte]*ptNode)
+ for first, rests := range nexts {
+ n.next[first] = newNode(rests)
+ }
+
+ return n
+}
+
+func splitPrefix(bss [][]byte) (prefix []byte, rest [][]byte) {
+ if len(bss) == 0 || len(bss[0]) == 0 {
+ return prefix, bss
+ }
+
+ if len(bss) == 1 {
+ return bss[0], [][]byte{{}}
+ }
+
+ for i := 0; ; i++ {
+ var cur byte
+ eq := true
+ for j, b := range bss {
+ if len(b) <= i {
+ eq = false
+ break
+ }
+
+ if j == 0 {
+ cur = b[i]
+ continue
+ }
+
+ if cur != b[i] {
+ eq = false
+ break
+ }
+ }
+
+ if !eq {
+ break
+ }
+
+ prefix = append(prefix, cur)
+ }
+
+ rest = make([][]byte, 0, len(bss))
+ for _, b := range bss {
+ rest = append(rest, b[len(prefix):])
+ }
+
+ return prefix, rest
+}
+
+func (n *ptNode) match(b []byte, prefix bool) bool {
+ l := len(n.prefix)
+ if l > 0 {
+ if l > len(b) {
+ l = len(b)
+ }
+ if !bytes.Equal(b[:l], n.prefix) {
+ return false
+ }
+ }
+
+ if n.terminal && (prefix || len(n.prefix) == len(b)) {
+ return true
+ }
+
+ if l >= len(b) {
+ return false
+ }
+
+ nextN, ok := n.next[b[l]]
+ if !ok {
+ return false
+ }
+
+ if l == len(b) {
+ b = b[l:l]
+ } else {
+ b = b[l+1:]
+ }
+ return nextN.match(b, prefix)
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index ebeced8..32ee9ed 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -215,8 +215,32 @@
{
"checksumSHA1": "q3Bc7JpLWBqhZ4M7oreGo34RSkc=",
"path": "github.com/golang/protobuf/proto",
- "revision": "8ee79997227bf9b34611aee7946ae64735e6fd93",
- "revisionTime": "2016-11-17T03:31:26Z"
+ "revision": "69b215d01a5606c843240eab4937eab3acee6530",
+ "revisionTime": "2017-02-17T23:44:32Z"
+ },
+ {
+ "checksumSHA1": "+hy2B6e5WWFIm6ch03jMFmrELhc=",
+ "path": "github.com/golang/protobuf/ptypes",
+ "revision": "69b215d01a5606c843240eab4937eab3acee6530",
+ "revisionTime": "2017-02-17T23:44:32Z"
+ },
+ {
+ "checksumSHA1": "lZFWy27Qo6+m/keDjNFYTxSmvZw=",
+ "path": "github.com/golang/protobuf/ptypes/any",
+ "revision": "69b215d01a5606c843240eab4937eab3acee6530",
+ "revisionTime": "2017-02-17T23:44:32Z"
+ },
+ {
+ "checksumSHA1": "8gDNKfvEupesDdOCXio3AK/XVaA=",
+ "path": "github.com/golang/protobuf/ptypes/duration",
+ "revision": "69b215d01a5606c843240eab4937eab3acee6530",
+ "revisionTime": "2017-02-17T23:44:32Z"
+ },
+ {
+ "checksumSHA1": "sfoot+dHmmOgWZS6GJ5X79ClZM0=",
+ "path": "github.com/golang/protobuf/ptypes/timestamp",
+ "revision": "69b215d01a5606c843240eab4937eab3acee6530",
+ "revisionTime": "2017-02-17T23:44:32Z"
},
{
"checksumSHA1": "9Qfs+Inw01bIOhsXfKCmNSueXLk=",
@@ -525,6 +549,12 @@
"revisionTime": "2016-08-27T17:29:50Z"
},
{
+ "checksumSHA1": "8oTYpwIGyUGF0fny/OEyxZxhk4Y=",
+ "path": "github.com/soheilhy/cmux",
+ "revision": "bf4a8ede9e87c006fe1d4278c6c7f2b8be1fa84c",
+ "revisionTime": "2016-09-26T01:07:37Z"
+ },
+ {
"checksumSHA1": "lBehULzb2/kIK3wZ0gz2yNmHq9s=",
"path": "github.com/spf13/afero",
"revision": "72b31426848c6ef12a7a8e216708cb0d1530f074",
@@ -647,20 +677,20 @@
{
"checksumSHA1": "LC+mzxnIrUS9Kr4s7shpY+A9J2o=",
"path": "golang.org/x/net/http2",
- "revision": "61557ac0112b576429a0df080e1c2cef5dfbb642",
- "revisionTime": "2017-01-26T11:54:58Z"
+ "revision": "6b27048ae5e6ad1ef927e72e437531493de612fe",
+ "revisionTime": "2017-02-17T08:49:01Z"
},
{
"checksumSHA1": "G3e2/HrQjRy2Ml9lfX0e3AGRWWE=",
"path": "golang.org/x/net/http2/hpack",
- "revision": "61557ac0112b576429a0df080e1c2cef5dfbb642",
- "revisionTime": "2017-01-26T11:54:58Z"
+ "revision": "6b27048ae5e6ad1ef927e72e437531493de612fe",
+ "revisionTime": "2017-02-17T08:49:01Z"
},
{
"checksumSHA1": "GIGmSrYACByf5JDIP9ByBZksY80=",
"path": "golang.org/x/net/idna",
- "revision": "61557ac0112b576429a0df080e1c2cef5dfbb642",
- "revisionTime": "2017-01-26T11:54:58Z"
+ "revision": "6b27048ae5e6ad1ef927e72e437531493de612fe",
+ "revisionTime": "2017-02-17T08:49:01Z"
},
{
"checksumSHA1": "UxahDzW2v4mf/+aFxruuupaoIwo=",
@@ -671,8 +701,8 @@
{
"checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=",
"path": "golang.org/x/net/lex/httplex",
- "revision": "61557ac0112b576429a0df080e1c2cef5dfbb642",
- "revisionTime": "2017-01-26T11:54:58Z"
+ "revision": "6b27048ae5e6ad1ef927e72e437531493de612fe",
+ "revisionTime": "2017-02-17T08:49:01Z"
},
{
"checksumSHA1": "GQHKESPeCcAsnerZPtHadvKUIzs=",