Merge pull request #470 from iamqizhao/master
i) lower case metedata key names; ii) make binary encoding consistent…
diff --git a/metadata/metadata.go b/metadata/metadata.go
index adebc38..52070db 100644
--- a/metadata/metadata.go
+++ b/metadata/metadata.go
@@ -46,27 +46,16 @@
binHdrSuffix = "-bin"
)
-// grpc-http2 requires ASCII header key and value (more detail can be found in
-// "Requests" subsection in go/grpc-http2).
-func isASCII(s string) bool {
- for _, c := range s {
- if c > 127 {
- return false
- }
- }
- return true
-}
-
// encodeKeyValue encodes key and value qualified for transmission via gRPC.
// Transmitting binary headers violates HTTP/2 spec.
// TODO(zhaoq): Maybe check if k is ASCII also.
func encodeKeyValue(k, v string) (string, string) {
- if isASCII(v) {
- return k, v
+ k = strings.ToLower(k)
+ if strings.HasSuffix(k, binHdrSuffix) {
+ val := base64.StdEncoding.EncodeToString([]byte(v))
+ v = string(val)
}
- key := strings.ToLower(k + binHdrSuffix)
- val := base64.StdEncoding.EncodeToString([]byte(v))
- return key, string(val)
+ return k, v
}
// DecodeKeyValue returns the original key and value corresponding to the
@@ -75,12 +64,11 @@
if !strings.HasSuffix(k, binHdrSuffix) {
return k, v, nil
}
- key := k[:len(k)-len(binHdrSuffix)]
val, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return "", "", err
}
- return key, string(val), nil
+ return k, string(val), nil
}
// MD is a mapping from metadata keys to values. Users should use the following
diff --git a/metadata/metadata_test.go b/metadata/metadata_test.go
index ef3a1b8..b2082d0 100644
--- a/metadata/metadata_test.go
+++ b/metadata/metadata_test.go
@@ -40,6 +40,27 @@
const binaryValue = string(128)
+func TestEncodeKeyValue(t *testing.T) {
+ for _, test := range []struct {
+ // input
+ kin string
+ vin string
+ // output
+ kout string
+ vout string
+ }{
+ {"key", "abc", "key", "abc"},
+ {"KEY", "abc", "key", "abc"},
+ {"key-bin", "abc", "key-bin", "YWJj"},
+ {"key-bin", binaryValue, "key-bin", "woA="},
+ } {
+ k, v := encodeKeyValue(test.kin, test.vin)
+ if k != test.kout || !reflect.DeepEqual(v, test.vout) {
+ t.Fatalf("encodeKeyValue(%q, %q) = %q, %q, want %q, %q", test.kin, test.vin, k, v, test.kout, test.vout)
+ }
+ }
+}
+
func TestDecodeKeyValue(t *testing.T) {
for _, test := range []struct {
// input
@@ -51,8 +72,8 @@
err error
}{
{"a", "abc", "a", "abc", nil},
- {"key-bin", "Zm9vAGJhcg==", "key", "foo\x00bar", nil},
- {"key-bin", "woA=", "key", binaryValue, nil},
+ {"key-bin", "Zm9vAGJhcg==", "key-bin", "foo\x00bar", nil},
+ {"key-bin", "woA=", "key-bin", binaryValue, nil},
} {
k, v, err := DecodeKeyValue(test.kin, test.vin)
if k != test.kout || !reflect.DeepEqual(v, test.vout) || !reflect.DeepEqual(err, test.err) {
@@ -66,17 +87,21 @@
// input
kv []string
// output
- md MD
+ md MD
+ size int
}{
- {[]string{}, MD{}},
- {[]string{"k1", "v1", "k2", binaryValue}, New(map[string]string{
+ {[]string{}, MD{}, 0},
+ {[]string{"k1", "v1", "k2-bin", binaryValue}, New(map[string]string{
"k1": "v1",
- "k2-bin": "woA=",
- })},
+ "k2-bin": binaryValue,
+ }), 2},
} {
md := Pairs(test.kv...)
if !reflect.DeepEqual(md, test.md) {
t.Fatalf("Pairs(%v) = %v, want %v", test.kv, md, test.md)
}
+ if md.Len() != test.size {
+ t.Fatalf("Pairs(%v) generates md of size %d, want %d", md.Len(), test.size)
+ }
}
}