diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go index 1af5cc4eb..f89318641 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go @@ -2,6 +2,10 @@ package runtime import ( "strconv" + + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/ptypes/duration" + "github.com/golang/protobuf/ptypes/timestamp" ) // String just returns the given string. @@ -56,3 +60,17 @@ func Uint32(val string) (uint32, error) { } return uint32(i), nil } + +// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp. +func Timestamp(val string) (*timestamp.Timestamp, error) { + var r *timestamp.Timestamp + err := jsonpb.UnmarshalString(val, r) + return r, err +} + +// Duration converts the given string into a timestamp.Duration. +func Duration(val string) (*duration.Duration, error) { + var r *duration.Duration + err := jsonpb.UnmarshalString(val, r) + return r, err +} diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go index ae6a5d551..1770b8534 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go @@ -34,34 +34,47 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal w.Header().Set("Transfer-Encoding", "chunked") w.Header().Set("Content-Type", marshaler.ContentType()) if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + HTTPError(ctx, mux, marshaler, w, req, err) return } - w.WriteHeader(http.StatusOK) - f.Flush() + + var delimiter []byte + if d, ok := marshaler.(Delimited); ok { + delimiter = d.Delimiter() + } else { + delimiter = []byte("\n") + } + + var wroteHeader bool for { resp, err := recv() if err == io.EOF { return } if err != nil { - handleForwardResponseStreamError(marshaler, w, err) + handleForwardResponseStreamError(wroteHeader, marshaler, w, err) return } if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { - handleForwardResponseStreamError(marshaler, w, err) + handleForwardResponseStreamError(wroteHeader, marshaler, w, err) return } buf, err := marshaler.Marshal(streamChunk(resp, nil)) if err != nil { grpclog.Printf("Failed to marshal response chunk: %v", err) + handleForwardResponseStreamError(wroteHeader, marshaler, w, err) return } if _, err = w.Write(buf); err != nil { grpclog.Printf("Failed to send response chunk: %v", err) return } + wroteHeader = true + if _, err = w.Write(delimiter); err != nil { + grpclog.Printf("Failed to send delimiter chunk: %v", err) + return + } f.Flush() } } @@ -134,13 +147,20 @@ func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, re return nil } -func handleForwardResponseStreamError(marshaler Marshaler, w http.ResponseWriter, err error) { +func handleForwardResponseStreamError(wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, err error) { buf, merr := marshaler.Marshal(streamChunk(nil, err)) if merr != nil { grpclog.Printf("Failed to marshal an error: %v", merr) return } - if _, werr := fmt.Fprintf(w, "%s\n", buf); werr != nil { + if !wroteHeader { + s, ok := status.FromError(err) + if !ok { + s = status.New(codes.Unknown, err.Error()) + } + w.WriteHeader(HTTPStatusFromCode(s.Code())) + } + if _, werr := w.Write(buf); werr != nil { grpclog.Printf("Failed to notify error to client: %v", werr) return } diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go index 0acd2ca29..b3a21418b 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go @@ -35,3 +35,8 @@ func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder { func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder { return json.NewEncoder(w) } + +// Delimiter for newline encoded JSON streams. +func (j *JSONBuiltin) Delimiter() []byte { + return []byte("\n") +} diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go index 49f13f7fc..d42cc593e 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go @@ -182,3 +182,8 @@ type protoEnum interface { } var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() + +// Delimiter for newline encoded JSON streams. +func (j *JSONPb) Delimiter() []byte { + return []byte("\n") +} diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go new file mode 100644 index 000000000..f65d1a267 --- /dev/null +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go @@ -0,0 +1,62 @@ +package runtime + +import ( + "io" + + "errors" + "github.com/golang/protobuf/proto" + "io/ioutil" +) + +// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes +type ProtoMarshaller struct{} + +// ContentType always returns "application/octet-stream". +func (*ProtoMarshaller) ContentType() string { + return "application/octet-stream" +} + +// Marshal marshals "value" into Proto +func (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) { + message, ok := value.(proto.Message) + if !ok { + return nil, errors.New("unable to marshal non proto field") + } + return proto.Marshal(message) +} + +// Unmarshal unmarshals proto "data" into "value" +func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error { + message, ok := value.(proto.Message) + if !ok { + return errors.New("unable to unmarshal non proto field") + } + return proto.Unmarshal(data, message) +} + +// NewDecoder returns a Decoder which reads proto stream from "reader". +func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder { + return DecoderFunc(func(value interface{}) error { + buffer, err := ioutil.ReadAll(reader) + if err != nil { + return err + } + return marshaller.Unmarshal(buffer, value) + }) +} + +// NewEncoder returns an Encoder which writes proto stream into "writer". +func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder { + return EncoderFunc(func(value interface{}) error { + buffer, err := marshaller.Marshal(value) + if err != nil { + return err + } + _, err = writer.Write(buffer) + if err != nil { + return err + } + + return nil + }) +} diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go index 6d434f13c..98fe6e88a 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go @@ -40,3 +40,9 @@ type EncoderFunc func(v interface{}) error // Encode delegates invocations to the underlying function itself. func (f EncoderFunc) Encode(v interface{}) error { return f(v) } + +// Delimited defines the streaming delimiter. +type Delimited interface { + // Delimiter returns the record seperator for the stream. + Delimiter() []byte +} diff --git a/glide.lock b/glide.lock index 0188e0d68..bc499956f 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 23d3b011a2e95e7c285287f62d6c7404ee42ccf6f81055cd24ab58da51a10f42 -updated: 2017-12-18T15:54:23.990881-08:00 +hash: 717378e57448533f1e2b054fe152b3f51e5e397292527c82ab24fb2c6c7d2a8f +updated: 2018-01-09T12:39:45.249170188-08:00 imports: - name: github.com/beorn7/perks version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 @@ -61,7 +61,7 @@ imports: - name: github.com/grpc-ecosystem/go-grpc-prometheus version: 0dafe0d496ea71181bf2dd039e7e3f44b6bd11a7 - name: github.com/grpc-ecosystem/grpc-gateway - version: 8cc3a55af3bcf171a1c23a90c4df9cf591706104 + version: 07f5e79768022f9a3265235f0db4ac8c3f675fec subpackages: - runtime - runtime/internal diff --git a/glide.yaml b/glide.yaml index 20c49b3af..46fa0e79e 100644 --- a/glide.yaml +++ b/glide.yaml @@ -45,7 +45,7 @@ import: - package: github.com/google/btree version: 925471ac9e2131377a91e1595defec898166fe49 - package: github.com/grpc-ecosystem/grpc-gateway - version: v1.3.0 + version: v1.3.1 subpackages: - runtime - runtime/internal