metadata.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. *
  3. * Copyright 2014 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package metadata define the structure of the metadata supported by gRPC library.
  19. // Please refer to https://grpc.io/docs/guides/wire.html for more information about custom-metadata.
  20. package metadata // import "google.golang.org/grpc/metadata"
  21. import (
  22. "fmt"
  23. "strings"
  24. "golang.org/x/net/context"
  25. )
  26. // DecodeKeyValue returns k, v, nil. It is deprecated and should not be used.
  27. func DecodeKeyValue(k, v string) (string, string, error) {
  28. return k, v, nil
  29. }
  30. // MD is a mapping from metadata keys to values. Users should use the following
  31. // two convenience functions New and Pairs to generate MD.
  32. type MD map[string][]string
  33. // New creates an MD from a given key-value map.
  34. //
  35. // Only the following ASCII characters are allowed in keys:
  36. // - digits: 0-9
  37. // - uppercase letters: A-Z (normalized to lower)
  38. // - lowercase letters: a-z
  39. // - special characters: -_.
  40. // Uppercase letters are automatically converted to lowercase.
  41. //
  42. // Keys beginning with "grpc-" are reserved for grpc-internal use only and may
  43. // result in errors if set in metadata.
  44. func New(m map[string]string) MD {
  45. md := MD{}
  46. for k, val := range m {
  47. key := strings.ToLower(k)
  48. md[key] = append(md[key], val)
  49. }
  50. return md
  51. }
  52. // Pairs returns an MD formed by the mapping of key, value ...
  53. // Pairs panics if len(kv) is odd.
  54. //
  55. // Only the following ASCII characters are allowed in keys:
  56. // - digits: 0-9
  57. // - uppercase letters: A-Z (normalized to lower)
  58. // - lowercase letters: a-z
  59. // - special characters: -_.
  60. // Uppercase letters are automatically converted to lowercase.
  61. //
  62. // Keys beginning with "grpc-" are reserved for grpc-internal use only and may
  63. // result in errors if set in metadata.
  64. func Pairs(kv ...string) MD {
  65. if len(kv)%2 == 1 {
  66. panic(fmt.Sprintf("metadata: Pairs got the odd number of input pairs for metadata: %d", len(kv)))
  67. }
  68. md := MD{}
  69. var key string
  70. for i, s := range kv {
  71. if i%2 == 0 {
  72. key = strings.ToLower(s)
  73. continue
  74. }
  75. md[key] = append(md[key], s)
  76. }
  77. return md
  78. }
  79. // Len returns the number of items in md.
  80. func (md MD) Len() int {
  81. return len(md)
  82. }
  83. // Copy returns a copy of md.
  84. func (md MD) Copy() MD {
  85. return Join(md)
  86. }
  87. // Join joins any number of mds into a single MD.
  88. // The order of values for each key is determined by the order in which
  89. // the mds containing those values are presented to Join.
  90. func Join(mds ...MD) MD {
  91. out := MD{}
  92. for _, md := range mds {
  93. for k, v := range md {
  94. out[k] = append(out[k], v...)
  95. }
  96. }
  97. return out
  98. }
  99. type mdIncomingKey struct{}
  100. type mdOutgoingKey struct{}
  101. // NewIncomingContext creates a new context with incoming md attached.
  102. func NewIncomingContext(ctx context.Context, md MD) context.Context {
  103. return context.WithValue(ctx, mdIncomingKey{}, md)
  104. }
  105. // NewOutgoingContext creates a new context with outgoing md attached.
  106. func NewOutgoingContext(ctx context.Context, md MD) context.Context {
  107. return context.WithValue(ctx, mdOutgoingKey{}, md)
  108. }
  109. // FromIncomingContext returns the incoming metadata in ctx if it exists. The
  110. // returned MD should not be modified. Writing to it may cause races.
  111. // Modification should be made to copies of the returned MD.
  112. func FromIncomingContext(ctx context.Context) (md MD, ok bool) {
  113. md, ok = ctx.Value(mdIncomingKey{}).(MD)
  114. return
  115. }
  116. // FromOutgoingContext returns the outgoing metadata in ctx if it exists. The
  117. // returned MD should not be modified. Writing to it may cause races.
  118. // Modification should be made to the copies of the returned MD.
  119. func FromOutgoingContext(ctx context.Context) (md MD, ok bool) {
  120. md, ok = ctx.Value(mdOutgoingKey{}).(MD)
  121. return
  122. }