@@ -93,12 +93,16 @@ func (md MD) Copy() MD {
9393}
9494
9595// Get obtains the values for a given key.
96+ //
97+ // All keys are converted to lowercase.
9698func (md MD ) Get (k string ) []string {
9799 k = strings .ToLower (k )
98100 return md [k ]
99101}
100102
101103// Set sets the value of a given key with a slice of values.
104+ //
105+ // All keys are converted to lowercase.
102106func (md MD ) Set (k string , vals ... string ) {
103107 if len (vals ) == 0 {
104108 return
@@ -107,7 +111,10 @@ func (md MD) Set(k string, vals ...string) {
107111 md [k ] = vals
108112}
109113
110- // Append adds the values to key k, not overwriting what was already stored at that key.
114+ // Append adds the values to key k, not overwriting what was already stored at
115+ // that key.
116+ //
117+ // All keys are converted to lowercase.
111118func (md MD ) Append (k string , vals ... string ) {
112119 if len (vals ) == 0 {
113120 return
@@ -117,8 +124,9 @@ func (md MD) Append(k string, vals ...string) {
117124}
118125
119126// Join joins any number of mds into a single MD.
120- // The order of values for each key is determined by the order in which
121- // the mds containing those values are presented to Join.
127+ //
128+ // The order of values for each key is determined by the order in which the mds
129+ // containing those values are presented to Join.
122130func Join (mds ... MD ) MD {
123131 out := MD {}
124132 for _ , md := range mds {
@@ -145,8 +153,12 @@ func NewOutgoingContext(ctx context.Context, md MD) context.Context {
145153}
146154
147155// AppendToOutgoingContext returns a new context with the provided kv merged
148- // with any existing metadata in the context. Please refer to the
149- // documentation of Pairs for a description of kv.
156+ // with any existing metadata in the context. Please refer to the documentation
157+ // of Pairs for a description of kv.
158+ //
159+ // Unlike Pairs, the keys are not turned into lowercase immediately. Users of
160+ // FromOutgoingContextRaw and FromOutgoingContext need to handle them
161+ // accordingly. Read the corresponding doc for more details.
150162func AppendToOutgoingContext (ctx context.Context , kv ... string ) context.Context {
151163 if len (kv )% 2 == 1 {
152164 panic (fmt .Sprintf ("metadata: AppendToOutgoingContext got an odd number of input pairs for metadata: %d" , len (kv )))
@@ -159,20 +171,38 @@ func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context
159171 return context .WithValue (ctx , mdOutgoingKey {}, rawMD {md : md .md , added : added })
160172}
161173
162- // FromIncomingContext returns the incoming metadata in ctx if it exists. The
174+ // FromIncomingContext returns the incoming metadata in ctx if it exists. The
163175// returned MD should not be modified. Writing to it may cause races.
164176// Modification should be made to copies of the returned MD.
165- func FromIncomingContext (ctx context.Context ) (md MD , ok bool ) {
166- md , ok = ctx .Value (mdIncomingKey {}).(MD )
167- return
177+ //
178+ // All keys in the return MD are lowercase.
179+ func FromIncomingContext (ctx context.Context ) (MD , bool ) {
180+ md , ok := ctx .Value (mdIncomingKey {}).(MD )
181+ if ! ok {
182+ return nil , false
183+ }
184+ out := MD {}
185+ for k , v := range md {
186+ // We need to manually convert all keys to lower case, because MD is a
187+ // map, and there's no guarantee that the MD attached to the context is
188+ // created using our helper functions.
189+ key := strings .ToLower (k )
190+ out [key ] = v
191+ }
192+ return out , true
168193}
169194
170- // FromOutgoingContextRaw returns the un-merged, intermediary contents
171- // of rawMD. Remember to perform strings.ToLower on the keys. The returned
172- // MD should not be modified. Writing to it may cause races. Modification
173- // should be made to copies of the returned MD.
195+ // FromOutgoingContextRaw returns the un-merged, intermediary contents of rawMD.
196+ // The returned MD should not be modified. Writing to it may cause races.
197+ // Modification should be made to copies of the returned MD.
198+ //
199+ // Remember to perform strings.ToLower on the keys, for both the returned MD (MD
200+ // is a map, there's no guarantee it's created using our helper functions) and
201+ // the extra kv pairs (AppendToOutgoingContext doesn't turn them into
202+ // lowercase).
174203//
175- // This is intended for gRPC-internal use ONLY.
204+ // This is intended for gRPC-internal use ONLY. Users should use
205+ // FromOutgoingContext instead.
176206func FromOutgoingContextRaw (ctx context.Context ) (MD , [][]string , bool ) {
177207 raw , ok := ctx .Value (mdOutgoingKey {}).(rawMD )
178208 if ! ok {
@@ -182,16 +212,25 @@ func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) {
182212 return raw .md , raw .added , true
183213}
184214
185- // FromOutgoingContext returns the outgoing metadata in ctx if it exists. The
215+ // FromOutgoingContext returns the outgoing metadata in ctx if it exists. The
186216// returned MD should not be modified. Writing to it may cause races.
187217// Modification should be made to copies of the returned MD.
218+ //
219+ // All keys in the return MD are lowercase.
188220func FromOutgoingContext (ctx context.Context ) (MD , bool ) {
189221 raw , ok := ctx .Value (mdOutgoingKey {}).(rawMD )
190222 if ! ok {
191223 return nil , false
192224 }
193225
194- out := raw .md .Copy ()
226+ out := MD {}
227+ for k , v := range raw .md {
228+ // We need to manually convert all keys to lower case, because MD is a
229+ // map, and there's no guarantee that the MD attached to the context is
230+ // created using our helper functions.
231+ key := strings .ToLower (k )
232+ out [key ] = v
233+ }
195234 for _ , added := range raw .added {
196235 if len (added )% 2 == 1 {
197236 panic (fmt .Sprintf ("metadata: FromOutgoingContext got an odd number of input pairs for metadata: %d" , len (added )))
0 commit comments