// Package test implements utilities for testing package test import ( "crypto/tls" "crypto/x509" "net" "net/http" "net/http/httptest" "herkulessi.de/git/eduvpn-common/internal/httpwrap" ) // Server wraps a HTTP test server type Server struct { *httptest.Server } // NewServer creates a new test server func NewServer(handler http.Handler, listener net.Listener) *Server { if listener == nil { s := httptest.NewTLSServer(handler) return &Server{s} } s := httptest.NewUnstartedServer(handler) // This is only for tests and if this fails, bad luck s.Listener.Close() //nolint:errcheck s.Listener = listener s.StartTLS() return &Server{s} } // HandlerPath handles a specific HTTP query type HandlerPath struct { Method string Path string Response string ResponseHandler func(http.ResponseWriter, *http.Request) ResponseCode int } // HandlerFunc handles a HTTP request func (hp *HandlerPath) HandlerFunc() func(http.ResponseWriter, *http.Request) { if hp.ResponseHandler != nil { return hp.ResponseHandler } return func(w http.ResponseWriter, r *http.Request) { if r.Method != hp.Method { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } w.WriteHeader(hp.ResponseCode) _, err := w.Write([]byte(hp.Response)) if err != nil { panic(err) } } } // NewServerWithHandles creates a new test servers with path and responses func NewServerWithHandles(hps []HandlerPath, listener net.Listener) *Server { mux := http.NewServeMux() for _, hp := range hps { if hp.ResponseCode == 0 { hp.ResponseCode = 200 } mux.HandleFunc(hp.Path, hp.HandlerFunc()) } return NewServer(mux, listener) } // Client returns a test client that trusts the HTTPS certificates func (srv *Server) Client() (*httpwrap.Client, error) { // Get the certs from the test server certs := x509.NewCertPool() for _, c := range srv.TLS.Certificates { roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1]) if err != nil { return nil, err } for _, root := range roots { certs.AddCert(root) } } client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ RootCAs: certs, }, }, } // Override the client such that it only trusts the test server cert httpC := httpwrap.NewClient(client) return httpC, nil }