@@ -18,6 +18,27 @@ const (
1818 keyPosition = 5 // example: /api/v1/route/method/apikey
1919)
2020
21+ // pathSegment returns the idx-th element of strings.Split(pathStr, "/") using strings.SplitSeq
22+ // so the full split slice is not allocated.
23+ func pathSegment (pathStr string , idx int ) string {
24+ segIdx := 0
25+
26+ for seg := range strings .SplitSeq (pathStr , "/" ) {
27+ if segIdx == idx {
28+ before , _ , found := strings .Cut (seg , "?" )
29+ if found {
30+ return before
31+ }
32+
33+ return seg
34+ }
35+
36+ segIdx ++
37+ }
38+
39+ return ""
40+ }
41+
2142type responseWrapper struct {
2243 http.ResponseWriter
2344
@@ -68,12 +89,23 @@ func (s *server) parseAPIKey(next http.Handler) http.Handler {
6889 return http .HandlerFunc (func (resp http.ResponseWriter , req * http.Request ) {
6990 key := req .Header .Get ("X-Api-Key" )
7091 if len (key ) != keyLength {
71- if uri := strings .Split (req .Header .Get ("X-Original-Uri" ), "/" ); len (uri ) > keyPosition {
72- key = strings .Split (uri [keyPosition ], "?" )[0 ]
73- }
92+ key = pathSegment (req .Header .Get ("X-Original-Uri" ), keyPosition )
93+ }
94+
95+ pooled := s .apiKeyVarsPool .Get ()
96+
97+ urlVars , ok := pooled .(map [string ]string )
98+ if ! ok {
99+ urlVars = make (map [string ]string , 1 )
74100 }
75101
76- req = mux .SetURLVars (req , map [string ]string {apiKey : key })
102+ urlVars [apiKey ] = key
103+ req = mux .SetURLVars (req , urlVars )
104+
105+ defer func () {
106+ delete (urlVars , apiKey )
107+ s .apiKeyVarsPool .Put (urlVars )
108+ }()
77109
78110 if len (key ) != keyLength {
79111 s .metrics .HTTPRequests .WithLabelValues (exp .HTTPEventInvalidKey ).Inc ()
0 commit comments