mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-17 04:37:48 +00:00
feat(oidcgate): mux wiring and http.Server with graceful shutdown
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/lukaszraczylo/traefikoidc"
|
||||||
|
|
||||||
|
type traefikoidcConfigStub struct {
|
||||||
|
callbackURL string
|
||||||
|
logoutURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s traefikoidcConfigStub) AsOIDC() traefikoidc.Config {
|
||||||
|
return traefikoidc.Config{
|
||||||
|
CallbackURL: s.callbackURL,
|
||||||
|
LogoutURL: s.logoutURL,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// buildMux wires all six routes onto a single ServeMux:
|
||||||
|
//
|
||||||
|
// /healthz, /readyz, AuthPath, StartPath, OIDC.CallbackURL, OIDC.LogoutURL.
|
||||||
|
//
|
||||||
|
// The same `middleware` instance is delegated to by all four OIDC routes;
|
||||||
|
// the synthetic success handler is wired into the middleware at construction
|
||||||
|
// time (in main.go) so it doesn't appear here.
|
||||||
|
func buildMux(cfg *Config, middleware http.Handler, ready readyReporter) *http.ServeMux {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.Handle("/healthz", newHealthzHandler())
|
||||||
|
mux.Handle("/readyz", newReadyzHandler(ready))
|
||||||
|
mux.Handle(cfg.AuthPath, newAuthHandler(middleware))
|
||||||
|
mux.Handle(cfg.StartPath, newStartHandler(middleware))
|
||||||
|
mux.Handle(cfg.OIDC.CallbackURL, newCallbackHandler(middleware, cfg.OIDC.CallbackURL))
|
||||||
|
mux.Handle(cfg.OIDC.LogoutURL, newLogoutHandler(middleware, cfg.OIDC.LogoutURL))
|
||||||
|
return mux
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildServer wraps the mux in an http.Server with sensible timeouts.
|
||||||
|
func buildServer(cfg *Config, mux http.Handler) *http.Server { //nolint:unused
|
||||||
|
return &http.Server{
|
||||||
|
Addr: cfg.Listen,
|
||||||
|
Handler: mux,
|
||||||
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
|
IdleTimeout: 120 * time.Second,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// shutdown gracefully stops the server with a 15s deadline.
|
||||||
|
func shutdown(srv *http.Server) error { //nolint:unused
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
return srv.Shutdown(ctx)
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMux_RoutesAllEndpoints(t *testing.T) {
|
||||||
|
stub := &stubMiddleware{
|
||||||
|
fn: func(rw http.ResponseWriter, _ *http.Request) { rw.WriteHeader(http.StatusOK) },
|
||||||
|
}
|
||||||
|
mux := buildMux(&Config{
|
||||||
|
Listen: ":0",
|
||||||
|
AuthPath: "/oauth2/auth",
|
||||||
|
StartPath: "/oauth2/start",
|
||||||
|
OIDC: traefikoidcConfigStub{
|
||||||
|
callbackURL: "/oauth2/callback",
|
||||||
|
logoutURL: "/oauth2/logout",
|
||||||
|
}.AsOIDC(),
|
||||||
|
}, stub, &readyStub{ready: true})
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
path string
|
||||||
|
method string
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{"/healthz", http.MethodGet, http.StatusOK},
|
||||||
|
{"/readyz", http.MethodGet, http.StatusOK},
|
||||||
|
{"/oauth2/auth", http.MethodGet, http.StatusOK},
|
||||||
|
{"/oauth2/start", http.MethodGet, http.StatusOK},
|
||||||
|
{"/oauth2/callback", http.MethodGet, http.StatusOK},
|
||||||
|
{"/oauth2/logout", http.MethodPost, http.StatusOK},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
mux.ServeHTTP(rec, httptest.NewRequest(c.method, c.path, nil))
|
||||||
|
if rec.Code != c.want {
|
||||||
|
t.Errorf("%s %s: want %d, got %d", c.method, c.path, c.want, rec.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user