@@ -19,7 +19,14 @@ func NewRouter(lim Limiter) stdhttp.Handler {
1919 sem := make (chan struct {}, 1000 ) // Limit to 1000 concurrent requests
2020
2121 mux .HandleFunc ("/check" , func (w stdhttp.ResponseWriter , r * stdhttp.Request ) {
22+ // Enforce POST method
23+ if r .Method != stdhttp .MethodPost {
24+ stdhttp .Error (w , "Method not allowed" , stdhttp .StatusMethodNotAllowed )
25+ return
26+ }
27+
2228 start := time .Now ()
29+
2330 select {
2431 case sem <- struct {}{}:
2532 defer func () { <- sem }()
@@ -31,64 +38,38 @@ func NewRouter(lim Limiter) stdhttp.Handler {
3138 ctx , cancel := context .WithTimeout (r .Context (), 50 * time .Millisecond )
3239 defer cancel ()
3340
34- // Read from header, matching what k6 sends
3541 apiKey := r .Header .Get ("X-API-Key" )
3642 if apiKey == "" {
3743 stdhttp .Error (w , "Missing X-API-Key" , stdhttp .StatusBadRequest )
3844 return
3945 }
4046
4147 allowed , err := lim .AllowRequest (ctx , apiKey )
42- metrics .RecordDecision (apiKey , allowed )
43- metrics .RecordDecisionLatency (time .Since (start ))
4448 if err != nil {
4549 metrics .RecordRedisError ()
4650 stdhttp .Error (w , err .Error (), stdhttp .StatusInternalServerError )
4751 return
4852 }
4953
54+ // Record metrics after successful call
55+ metrics .RecordDecision (apiKey , allowed )
56+ metrics .RecordDecisionLatency (time .Since (start ))
57+
5058 w .Header ().Set ("Content-Type" , "application/json" )
5159 if allowed {
5260 w .WriteHeader (stdhttp .StatusOK )
5361 } else {
5462 w .WriteHeader (stdhttp .StatusTooManyRequests )
5563 }
64+
5665 _ = json .NewEncoder (w ).Encode (map [string ]any {
5766 "allowed" : allowed ,
5867 "api_key" : apiKey ,
5968 })
6069 })
6170
71+ // Prometheus metrics endpoint
6272 mux .Handle ("/metrics" , promhttp .Handler ())
6373
6474 return mux
6575}
66-
67- func checkHandler (lim Limiter ) stdhttp.HandlerFunc {
68- return func (w stdhttp.ResponseWriter , r * stdhttp.Request ) {
69- if r .Method != stdhttp .MethodPost {
70- stdhttp .Error (w , "Method not allowed" , stdhttp .StatusMethodNotAllowed )
71- return
72- }
73-
74- apiKey := r .Header .Get ("X-API-Key" )
75- if apiKey == "" {
76- stdhttp .Error (w , "Missing X-API-Key" , stdhttp .StatusBadRequest )
77- return
78- }
79-
80- allowed , _ := lim .AllowRequest (r .Context (), apiKey )
81-
82- status := stdhttp .StatusOK
83- if ! allowed {
84- status = stdhttp .StatusTooManyRequests
85- }
86-
87- w .Header ().Set ("Content-Type" , "application/json" )
88- w .WriteHeader (status )
89- _ = json .NewEncoder (w ).Encode (map [string ]any {
90- "allowed" : allowed ,
91- "api_key" : apiKey ,
92- })
93- }
94- }
0 commit comments