@@ -32,7 +32,9 @@ import (
3232 "go.uber.org/thriftrw/protocol/stream"
3333 "go.uber.org/thriftrw/thrifttest/streamtest"
3434 "go.uber.org/thriftrw/wire"
35+ "go.uber.org/yarpc/api/transport"
3536 "go.uber.org/yarpc/api/transport/transporttest"
37+ "go.uber.org/yarpc/internal/observability"
3638 "go.uber.org/yarpc/internal/testtime"
3739)
3840
@@ -246,3 +248,149 @@ func TestDecodeNoWireAppliationError(t *testing.T) {
246248 require .NoError (t , h .Handle (ctx , req , rw ))
247249 assert .True (t , rw .IsApplicationError )
248250}
251+
252+ func TestHeaderKeyContainsUppercase (t * testing.T ) {
253+ tests := []struct {
254+ name string
255+ input string
256+ expected bool
257+ }{
258+ {
259+ name : "all lowercase" ,
260+ input : "lowercase" ,
261+ expected : false ,
262+ },
263+ {
264+ name : "all uppercase" ,
265+ input : "UPPERCASE" ,
266+ expected : true ,
267+ },
268+ {
269+ name : "mixed case" ,
270+ input : "MixedCase" ,
271+ expected : true ,
272+ },
273+ {
274+ name : "empty string" ,
275+ input : "" ,
276+ expected : false ,
277+ },
278+ {
279+ name : "numbers and lowercase" ,
280+ input : "header123" ,
281+ expected : false ,
282+ },
283+ {
284+ name : "numbers and uppercase" ,
285+ input : "HEADER123" ,
286+ expected : true ,
287+ },
288+ {
289+ name : "special characters only" ,
290+ input : "-_-" ,
291+ expected : false ,
292+ },
293+ {
294+ name : "special characters with uppercase" ,
295+ input : "X-Request-ID" ,
296+ expected : true ,
297+ },
298+ {
299+ name : "special characters with lowercase" ,
300+ input : "x-request-id" ,
301+ expected : false ,
302+ },
303+ {
304+ name : "single uppercase letter" ,
305+ input : "A" ,
306+ expected : true ,
307+ },
308+ {
309+ name : "single lowercase letter" ,
310+ input : "a" ,
311+ expected : false ,
312+ },
313+ {
314+ name : "uppercase at end" ,
315+ input : "headerX" ,
316+ expected : true ,
317+ },
318+ {
319+ name : "uppercase at start" ,
320+ input : "Xheader" ,
321+ expected : true ,
322+ },
323+ }
324+
325+ for _ , tt := range tests {
326+ t .Run (tt .name , func (t * testing.T ) {
327+ result := headerKeyContainsUppercase (tt .input )
328+ assert .Equal (t , tt .expected , result , "headerKeyContainsUppercase(%q) = %v, want %v" , tt .input , result , tt .expected )
329+ })
330+ }
331+ }
332+
333+ func TestCheckAndEmitUnsafeHeaders (t * testing.T ) {
334+ tests := []struct {
335+ name string
336+ setupRequest func () * transport.Request
337+ setupMeter func () * observability.MeterInfo
338+ expectMetrics func (t * testing.T , meter * observability.MeterInfo )
339+ }{
340+ {
341+ name : "nil meter info" ,
342+ setupRequest : func () * transport.Request {
343+ return request ()
344+ },
345+ setupMeter : func () * observability.MeterInfo {
346+ return nil
347+ },
348+ expectMetrics : func (t * testing.T , meter * observability.MeterInfo ) {
349+ // Should not panic, just return early
350+ },
351+ },
352+ {
353+ name : "nil edge in meter info" ,
354+ setupRequest : func () * transport.Request {
355+ return request ()
356+ },
357+ setupMeter : func () * observability.MeterInfo {
358+ return & observability.MeterInfo {
359+ Edge : nil ,
360+ }
361+ },
362+ expectMetrics : func (t * testing.T , meter * observability.MeterInfo ) {
363+ // Should not panic, just return early
364+ },
365+ },
366+ {
367+ name : "nil request" ,
368+ setupRequest : func () * transport.Request {
369+ return nil
370+ },
371+ setupMeter : func () * observability.MeterInfo {
372+ return & observability.MeterInfo {}
373+ },
374+ expectMetrics : func (t * testing.T , meter * observability.MeterInfo ) {
375+ // Should not panic, just return early
376+ },
377+ },
378+ }
379+
380+ for _ , tt := range tests {
381+ t .Run (tt .name , func (t * testing.T ) {
382+ h := thriftNoWireHandler {}
383+ req := tt .setupRequest ()
384+ meter := tt .setupMeter ()
385+
386+ // Should not panic
387+ require .NotPanics (t , func () {
388+ h .checkAndEmitUnsafeHeaders (meter , req )
389+ })
390+
391+ if tt .expectMetrics != nil {
392+ tt .expectMetrics (t , meter )
393+ }
394+ })
395+ }
396+ }
0 commit comments