feat(http): introduce middleware for audit logs and authentication checks (157)

Introduce wrapper middleware to intercept http requests
---
Rename middleware to http
This commit is contained in:
Arda Güçlü
2025-07-02 16:08:17 +03:00
committed by GitHub
parent ebe0ba9816
commit 524e4f5d2a
3 changed files with 66 additions and 1 deletions

61
pkg/http/http.go Normal file
View File

@@ -0,0 +1,61 @@
package http
import (
"bufio"
"net"
"net/http"
"time"
"k8s.io/klog/v2"
)
func RequestMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
lrw := &loggingResponseWriter{
ResponseWriter: w,
statusCode: http.StatusOK,
}
next.ServeHTTP(lrw, r)
duration := time.Since(start)
klog.V(5).Infof("%s %s %d %v", r.Method, r.URL.Path, lrw.statusCode, duration)
})
}
type loggingResponseWriter struct {
http.ResponseWriter
statusCode int
headerWritten bool
}
func (lrw *loggingResponseWriter) WriteHeader(code int) {
if !lrw.headerWritten {
lrw.statusCode = code
lrw.headerWritten = true
lrw.ResponseWriter.WriteHeader(code)
}
}
func (lrw *loggingResponseWriter) Write(b []byte) (int, error) {
if !lrw.headerWritten {
lrw.statusCode = http.StatusOK
lrw.headerWritten = true
}
return lrw.ResponseWriter.Write(b)
}
func (lrw *loggingResponseWriter) Flush() {
if flusher, ok := lrw.ResponseWriter.(http.Flusher); ok {
flusher.Flush()
}
}
func (lrw *loggingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if hijacker, ok := lrw.ResponseWriter.(http.Hijacker); ok {
return hijacker.Hijack()
}
return nil, nil, http.ErrNotSupported
}

View File

@@ -18,6 +18,7 @@ import (
"k8s.io/kubectl/pkg/util/templates"
"github.com/manusa/kubernetes-mcp-server/pkg/config"
internalhttp "github.com/manusa/kubernetes-mcp-server/pkg/http"
"github.com/manusa/kubernetes-mcp-server/pkg/mcp"
"github.com/manusa/kubernetes-mcp-server/pkg/output"
"github.com/manusa/kubernetes-mcp-server/pkg/version"
@@ -206,9 +207,11 @@ func (m *MCPServerOptions) Run() error {
if m.StaticConfig.Port != "" {
mux := http.NewServeMux()
wrappedMux := internalhttp.RequestMiddleware(mux)
httpServer := &http.Server{
Addr: ":" + m.StaticConfig.Port,
Handler: mux,
Handler: wrappedMux,
}
sseServer := mcpServer.ServeSse(m.SSEBaseUrl, httpServer)

View File

@@ -98,6 +98,7 @@ func (s *Server) ServeHTTP(httpServer *http.Server) *server.StreamableHTTPServer
options := []server.StreamableHTTPOption{
server.WithHTTPContextFunc(contextFunc),
server.WithStreamableHTTPServer(httpServer),
server.WithStateLess(true),
}
return server.NewStreamableHTTPServer(s.server, options...)
}