Don't double encode protobuf runtime.Unknown

When using runtime.Object and runtime.RawExtension, passing runtime.Unknown to protobuf serializer should result in the raw message being serialized (since all normal protobuf objects are runtime.Unknown). Also, avoid setting a content-type when decoding a protobuf object except when the content appears to be proto.
parent 8f08cb33
...@@ -124,7 +124,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi ...@@ -124,7 +124,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil { if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
*intoUnknown = unk *intoUnknown = unk
if len(intoUnknown.ContentType) == 0 { if ok, _ := s.RecognizesData(bytes.NewBuffer(unk.Raw)); ok {
intoUnknown.ContentType = s.contentType intoUnknown.ContentType = s.contentType
} }
return intoUnknown, &actual, nil return intoUnknown, &actual, nil
...@@ -167,17 +167,30 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi ...@@ -167,17 +167,30 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
// Encode serializes the provided object to the given writer. // Encode serializes the provided object to the given writer.
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error { func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
prefixSize := uint64(len(s.prefix))
var unk runtime.Unknown var unk runtime.Unknown
kind := obj.GetObjectKind().GroupVersionKind() switch t := obj.(type) {
unk = runtime.Unknown{ case *runtime.Unknown:
TypeMeta: runtime.TypeMeta{ estimatedSize := prefixSize + uint64(t.Size())
Kind: kind.Kind, data := make([]byte, estimatedSize)
APIVersion: kind.GroupVersion().String(), i, err := t.MarshalTo(data[prefixSize:])
}, if err != nil {
return err
}
copy(data, s.prefix)
_, err = w.Write(data[:prefixSize+uint64(i)])
return err
default:
kind := obj.GetObjectKind().GroupVersionKind()
unk = runtime.Unknown{
TypeMeta: runtime.TypeMeta{
Kind: kind.Kind,
APIVersion: kind.GroupVersion().String(),
},
}
} }
prefixSize := uint64(len(s.prefix))
switch t := obj.(type) { switch t := obj.(type) {
case bufferedMarshaller: case bufferedMarshaller:
// this path performs a single allocation during write but requires the caller to implement // this path performs a single allocation during write but requires the caller to implement
......
...@@ -205,7 +205,7 @@ func TestDecode(t *testing.T) { ...@@ -205,7 +205,7 @@ func TestDecode(t *testing.T) {
0x0a, 0x15, 0x0a, 0x15,
0x0a, 0x0d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, // apiversion 0x0a, 0x0d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, // apiversion
0x12, 0x04, 0x74, 0x65, 0x73, 0x74, // kind 0x12, 0x04, 0x74, 0x65, 0x73, 0x74, // kind
0x12, 0x03, 0x01, 0x02, 0x03, // data 0x12, 0x07, 0x6b, 0x38, 0x73, 0x00, 0x01, 0x02, 0x03, // data
0x1a, 0x00, // content-type 0x1a, 0x00, // content-type
0x22, 0x00, // content-encoding 0x22, 0x00, // content-encoding
} }
...@@ -227,8 +227,7 @@ func TestDecode(t *testing.T) { ...@@ -227,8 +227,7 @@ func TestDecode(t *testing.T) {
}, },
{ {
obj: &runtime.Unknown{ obj: &runtime.Unknown{
ContentType: "application/protobuf", Raw: []byte{},
Raw: []byte{},
}, },
data: wire1, data: wire1,
}, },
...@@ -238,8 +237,9 @@ func TestDecode(t *testing.T) { ...@@ -238,8 +237,9 @@ func TestDecode(t *testing.T) {
APIVersion: "other/version", APIVersion: "other/version",
Kind: "test", Kind: "test",
}, },
// content type is set because the prefix matches the content
ContentType: "application/protobuf", ContentType: "application/protobuf",
Raw: []byte{0x01, 0x02, 0x03}, Raw: []byte{0x6b, 0x38, 0x73, 0x00, 0x01, 0x02, 0x03},
}, },
data: wire2, data: wire2,
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment