diff --git a/cmd/boardvoting/handlers.go b/cmd/boardvoting/handlers.go index 0442364..0efdf30 100644 --- a/cmd/boardvoting/handlers.go +++ b/cmd/boardvoting/handlers.go @@ -29,11 +29,12 @@ import ( "strings" "time" - "git.cacert.org/cacert-boardvoting/internal/models" - "git.cacert.org/cacert-boardvoting/ui" "github.com/Masterminds/sprig/v3" "github.com/gorilla/csrf" "github.com/julienschmidt/httprouter" + + "git.cacert.org/cacert-boardvoting/internal/models" + "git.cacert.org/cacert-boardvoting/ui" ) func newTemplateCache() (map[string]*template.Template, error) { diff --git a/cmd/boardvoting/main.go b/cmd/boardvoting/main.go index 3100dad..ec0a71e 100644 --- a/cmd/boardvoting/main.go +++ b/cmd/boardvoting/main.go @@ -119,34 +119,30 @@ func main() { errChan := make(chan error, 1) - go func() { - redirect := &http.Server{ - Addr: config.HTTPAddress, - Handler: http.RedirectHandler(config.BaseURL, http.StatusMovedPermanently), - IdleTimeout: config.Timeouts.Idle, - ReadHeaderTimeout: config.Timeouts.ReadHeader, - ReadTimeout: config.Timeouts.Read, - WriteTimeout: config.Timeouts.Write, - } + infoLog.Printf("TLS config setup, starting TLS server on %s", config.HTTPSAddress) - if err := redirect.ListenAndServe(); err != nil { - errChan <- err - } + go setupHTTPRedirect(config, errChan) - close(errChan) - }() - - tlsConfig, err := setupTLSConfig(config) + err = app.startHTTPSServer(config) if err != nil { - errorLog.Fatalf("could not setup TLS configuration: %v", err) + errorLog.Fatalf("ListenAndServeTLS (HTTPS) failed: %v", err) } - infoLog.Printf("TLS config setup, starting TLS server on %s", config.HTTPSAddress) + if err := <-errChan; err != nil { + errorLog.Fatalf("ListenAndServe (HTTP) failed: %v", err) + } +} + +func (app *application) startHTTPSServer(config *Config) error { + tlsConfig, err := setupTLSConfig(config) + if err != nil { + return fmt.Errorf("could not setup TLS configuration: %w", err) + } srv := &http.Server{ Addr: config.HTTPSAddress, TLSConfig: tlsConfig, - ErrorLog: errorLog, + ErrorLog: app.errorLog, Handler: app.routes(), IdleTimeout: config.Timeouts.Idle, ReadHeaderTimeout: config.Timeouts.ReadHeader, @@ -156,12 +152,27 @@ func main() { err = srv.ListenAndServeTLS(config.ServerCert, config.ServerKey) if err != nil { - errorLog.Fatalf("ListenAndServeTLS (HTTPS) failed: %v", err) + return fmt.Errorf("") } - if err := <-errChan; err != nil { - errorLog.Fatalf("ListenAndServe (HTTP) failed: %v", err) + return nil +} + +func setupHTTPRedirect(config *Config, errChan chan error) { + redirect := &http.Server{ + Addr: config.HTTPAddress, + Handler: http.RedirectHandler(config.BaseURL, http.StatusMovedPermanently), + IdleTimeout: config.Timeouts.Idle, + ReadHeaderTimeout: config.Timeouts.ReadHeader, + ReadTimeout: config.Timeouts.Read, + WriteTimeout: config.Timeouts.Write, } + + if err := redirect.ListenAndServe(); err != nil { + errChan <- err + } + + close(errChan) } func setupTLSConfig(config *Config) (*tls.Config, error) { diff --git a/cmd/boardvoting/middleware.go b/cmd/boardvoting/middleware.go index 86303c8..54b836b 100644 --- a/cmd/boardvoting/middleware.go +++ b/cmd/boardvoting/middleware.go @@ -18,7 +18,6 @@ limitations under the License. package main import ( - "fmt" "net/http" ) @@ -42,16 +41,3 @@ func (app *application) logRequest(next http.Handler) http.Handler { next.ServeHTTP(w, r) }) } - -func (app *application) recoverPanic(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - defer func() { - if err := recover(); err != nil { - w.Header().Set("Connection", "close") - app.serverError(w, fmt.Errorf("%s", err)) - } - }() - - next.ServeHTTP(w, r) - }) -} diff --git a/cmd/boardvoting/routes.go b/cmd/boardvoting/routes.go index be9449d..0c0b26c 100644 --- a/cmd/boardvoting/routes.go +++ b/cmd/boardvoting/routes.go @@ -18,6 +18,7 @@ limitations under the License. package main import ( + "fmt" "io/fs" "net/http" @@ -30,8 +31,6 @@ import ( ) func (app *application) routes() http.Handler { - router := httprouter.New() - staticDir, _ := fs.Sub(ui.Files, "static") staticData, ok := staticDir.(fs.ReadDirFS) @@ -41,6 +40,14 @@ func (app *application) routes() http.Handler { fileServer := statigz.FileServer(staticData, brotli.AddEncoding, statigz.EncodeOnInit) + router := httprouter.New() + + router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { app.notFound(w) }) + router.PanicHandler = func(w http.ResponseWriter, _ *http.Request, err interface{}) { + w.Header().Set("Connection", "close") + app.serverError(w, fmt.Errorf("%s", err)) + } + router.Handler(http.MethodGet, "/", http.RedirectHandler("/motions/", http.StatusMovedPermanently)) router.Handler( http.MethodGet, @@ -50,14 +57,14 @@ func (app *application) routes() http.Handler { router.Handler(http.MethodGet, "/static/*filepath", http.StripPrefix("/static", fileServer)) router.HandlerFunc(http.MethodGet, "/motions/", app.motionList) router.HandlerFunc(http.MethodGet, "/motions/:tag", app.motionDetails) + router.HandlerFunc(http.MethodGet, "/vote/:tag", app.voteForm) + router.HandlerFunc(http.MethodPost, "/vote/:tag", app.voteSubmit) + router.HandlerFunc(http.MethodGet, "/proxy/:tag", app.proxyVoteForm) + router.HandlerFunc(http.MethodPost, "/proxy/:tag", app.proxyVoteSubmit) router.HandlerFunc(http.MethodGet, "/newmotion/", app.newMotionForm) router.HandlerFunc(http.MethodPost, "/newmotion/", app.newMotionSubmit) - router.HandlerFunc(http.MethodGet, "/vote/", app.voteForm) - router.HandlerFunc(http.MethodPost, "/vote/", app.voteSubmit) - router.HandlerFunc(http.MethodGet, "/proxy/", app.proxyVoteForm) - router.HandlerFunc(http.MethodPost, "/proxy/", app.proxyVoteSubmit) - standard := alice.New(app.recoverPanic, app.logRequest, secureHeaders) + standard := alice.New(app.logRequest, secureHeaders) return standard.Then(router) }