diff --git a/cmd/gotenberg.go b/cmd/gotenberg.go index 318e36ef..7c3d37da 100644 --- a/cmd/gotenberg.go +++ b/cmd/gotenberg.go @@ -35,6 +35,7 @@ var Version = "snapshot" // Run starts the Gotenberg application. Call this in the main of your program. func Run() { fmt.Printf(banner, Version) + gotenberg.Version = Version // Create the root FlagSet and adds the modules flags to it. fs := flag.NewFlagSet("gotenberg", flag.ExitOnError) diff --git a/pkg/gotenberg/version.go b/pkg/gotenberg/version.go new file mode 100644 index 00000000..36940b8e --- /dev/null +++ b/pkg/gotenberg/version.go @@ -0,0 +1,4 @@ +package gotenberg + +// Version is the... version of the Gotenberg application. +var Version = "snapshot" diff --git a/pkg/modules/api/api.go b/pkg/modules/api/api.go index e7d7c979..76fd362f 100644 --- a/pkg/modules/api/api.go +++ b/pkg/modules/api/api.go @@ -323,8 +323,9 @@ func (a *Api) Validate() error { return err } - routesMap := make(map[string]string, len(a.routes)+1) + routesMap := make(map[string]string, len(a.routes)+2) routesMap["/health"] = "/health" + routesMap["/version"] = "/version" for _, route := range a.routes { if route.Path == "" { @@ -442,7 +443,7 @@ func (a *Api) Start() error { ) } - // Let's not forget the health check route. + // Let's not forget the health check route... a.srv.GET( fmt.Sprintf("%s%s", a.rootPath, "health"), func() echo.HandlerFunc { @@ -453,6 +454,14 @@ func (a *Api) Start() error { hardTimeoutMiddleware(hardTimeout), ) + // ...and the version route. + a.srv.GET( + fmt.Sprintf("%s%s", a.rootPath, "version"), + func(c echo.Context) error { + return c.String(http.StatusOK, gotenberg.Version) + }, + ) + // Wait for all modules to be ready. ctx, cancel := context.WithTimeout(context.Background(), a.startTimeout) defer cancel() diff --git a/pkg/modules/api/api_test.go b/pkg/modules/api/api_test.go index a5e5b0fb..1e23fd07 100644 --- a/pkg/modules/api/api_test.go +++ b/pkg/modules/api/api_test.go @@ -790,6 +790,15 @@ func TestApi_Start(t *testing.T) { t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) } + // version request. + versionRequest := httptest.NewRequest(http.MethodGet, "/version", nil) + versionRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) + + mod.srv.ServeHTTP(recorder, versionRequest) + if recorder.Code != http.StatusOK { + t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) + } + // "multipart/form-data" request. multipartRequest := func(url string) *http.Request { body := &bytes.Buffer{} diff --git a/pkg/modules/webhook/middleware.go b/pkg/modules/webhook/middleware.go index d7e8ad8a..fb0865ea 100644 --- a/pkg/modules/webhook/middleware.go +++ b/pkg/modules/webhook/middleware.go @@ -159,7 +159,7 @@ func webhookMiddleware(w *Webhook) api.Middleware { } headers := map[string]string{ - echo.HeaderContentType: echo.MIMEApplicationJSONCharsetUTF8, + echo.HeaderContentType: echo.MIMEApplicationJSON, c.Get("traceHeader").(string): c.Get("trace").(string), } diff --git a/pkg/modules/webhook/middleware_test.go b/pkg/modules/webhook/middleware_test.go index 9fc1f8fe..8940f406 100644 --- a/pkg/modules/webhook/middleware_test.go +++ b/pkg/modules/webhook/middleware_test.go @@ -376,7 +376,7 @@ func TestWebhookMiddlewareAsynchronousProcess(t *testing.T) { return errors.New("foo") } }(), - expectWebhookContentType: echo.MIMEApplicationJSONCharsetUTF8, + expectWebhookContentType: echo.MIMEApplicationJSON, expectWebhookMethod: http.MethodPost, expectWebhookErrorStatus: http.StatusInternalServerError, expectWebhookErrorMessage: http.StatusText(http.StatusInternalServerError), @@ -390,7 +390,7 @@ func TestWebhookMiddlewareAsynchronousProcess(t *testing.T) { return api.NewSentinelHttpError(http.StatusBadRequest, http.StatusText(http.StatusBadRequest)) } }(), - expectWebhookContentType: echo.MIMEApplicationJSONCharsetUTF8, + expectWebhookContentType: echo.MIMEApplicationJSON, expectWebhookMethod: http.MethodPost, expectWebhookErrorStatus: http.StatusBadRequest, expectWebhookErrorMessage: http.StatusText(http.StatusBadRequest), @@ -430,7 +430,7 @@ func TestWebhookMiddlewareAsynchronousProcess(t *testing.T) { } }(), returnedError: echo.ErrInternalServerError, - expectWebhookContentType: echo.MIMEApplicationJSONCharsetUTF8, + expectWebhookContentType: echo.MIMEApplicationJSON, expectWebhookMethod: http.MethodPost, expectWebhookErrorStatus: http.StatusInternalServerError, expectWebhookErrorMessage: http.StatusText(http.StatusInternalServerError), @@ -493,7 +493,7 @@ func TestWebhookMiddlewareAsynchronousProcess(t *testing.T) { } } - if contentType == echo.MIMEApplicationJSONCharsetUTF8 { + if contentType == echo.MIMEApplicationJSON { body, err := io.ReadAll(c.Request().Body) if err != nil { errChan <- err