mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
feat(api): added tls/ssl support
This commit is contained in:
committed by
Julien Neuhart
parent
e50de4201d
commit
20b8991fa4
@@ -28,6 +28,8 @@ func init() {
|
||||
// middlewares or health checks.
|
||||
type Api struct {
|
||||
port int
|
||||
tlsCertFile string
|
||||
tlsKeyFile string
|
||||
startTimeout time.Duration
|
||||
timeout time.Duration
|
||||
rootPath string
|
||||
@@ -159,6 +161,8 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor {
|
||||
fs := flag.NewFlagSet("api", flag.ExitOnError)
|
||||
fs.Int("api-port", 3000, "Set the port on which the API should listen")
|
||||
fs.String("api-port-from-env", "", "Set the environment variable with the port on which the API should listen - override the default port")
|
||||
fs.String("api-tls-cert-file", "", "Path to the TLS/SSL certificate file - for HTTPS support")
|
||||
fs.String("api-tls-key-file", "", "Path to the TLS/SSL key file - for HTTPS support")
|
||||
fs.Duration("api-start-timeout", time.Duration(30)*time.Second, "Set the time limit for the API to start")
|
||||
fs.Duration("api-timeout", time.Duration(30)*time.Second, "Set the time limit for requests")
|
||||
fs.String("api-root-path", "/", "Set the root path of the API - for service discovery via URL paths")
|
||||
@@ -175,6 +179,8 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor {
|
||||
func (a *Api) Provision(ctx *gotenberg.Context) error {
|
||||
flags := ctx.ParsedFlags()
|
||||
a.port = flags.MustInt("api-port")
|
||||
a.tlsCertFile = flags.MustString("api-tls-cert-file")
|
||||
a.tlsKeyFile = flags.MustString("api-tls-key-file")
|
||||
a.startTimeout = flags.MustDuration("api-start-timeout")
|
||||
a.timeout = flags.MustDuration("api-timeout")
|
||||
a.rootPath = flags.MustString("api-root-path")
|
||||
@@ -301,6 +307,12 @@ func (a *Api) Validate() error {
|
||||
)
|
||||
}
|
||||
|
||||
if (a.tlsCertFile != "" && a.tlsKeyFile == "") || (a.tlsCertFile == "" && a.tlsKeyFile != "") {
|
||||
err = multierr.Append(err,
|
||||
errors.New("tls certificate and key file must both be set"),
|
||||
)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(a.rootPath, "/") {
|
||||
err = multierr.Append(err,
|
||||
errors.New("root path must start with /"),
|
||||
@@ -478,10 +490,19 @@ func (a *Api) Start() error {
|
||||
|
||||
// As the following code is blocking, run it in a goroutine.
|
||||
go func() {
|
||||
server := &http2.Server{}
|
||||
err := a.srv.StartH2CServer(fmt.Sprintf(":%d", a.port), server)
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
a.logger.Fatal(err.Error())
|
||||
if a.tlsCertFile != "" && a.tlsKeyFile != "" {
|
||||
// Start an HTTPS server (supports HTTP/2).
|
||||
err := a.srv.StartTLS(fmt.Sprintf(":%d", a.port), a.tlsCertFile, a.tlsKeyFile)
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
a.logger.Fatal(err.Error())
|
||||
}
|
||||
} else {
|
||||
// Start an HTTP/2 Cleartext (non-HTTPS) server.
|
||||
server := &http2.Server{}
|
||||
err := a.srv.StartH2CServer(fmt.Sprintf(":%d", a.port), server)
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
a.logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -462,6 +462,8 @@ func TestApi_Validate(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
port int
|
||||
tlsCertFile string
|
||||
tlsKeyFile string
|
||||
rootPath string
|
||||
traceHeader string
|
||||
routes []Route
|
||||
@@ -486,6 +488,26 @@ func TestApi_Validate(t *testing.T) {
|
||||
middlewares: nil,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "invalid tls files: only cert file provided",
|
||||
port: 10,
|
||||
tlsCertFile: "cert.pem",
|
||||
rootPath: "/foo/",
|
||||
traceHeader: "foo",
|
||||
routes: nil,
|
||||
middlewares: nil,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "invalid tls files: only key file provided",
|
||||
port: 10,
|
||||
tlsKeyFile: "key.pem",
|
||||
rootPath: "/foo/",
|
||||
traceHeader: "foo",
|
||||
routes: nil,
|
||||
middlewares: nil,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "invalid root path: missing / prefix",
|
||||
port: 10,
|
||||
@@ -647,10 +669,45 @@ func TestApi_Validate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
scenario: "success with tls",
|
||||
port: 10,
|
||||
tlsCertFile: "cert.pem",
|
||||
tlsKeyFile: "key.pem",
|
||||
rootPath: "/foo/",
|
||||
traceHeader: "foo",
|
||||
routes: []Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/foo",
|
||||
Handler: func(_ echo.Context) error { return nil },
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/forms/foo",
|
||||
Handler: func(_ echo.Context) error { return nil },
|
||||
IsMultipart: true,
|
||||
},
|
||||
},
|
||||
middlewares: []Middleware{
|
||||
{
|
||||
Priority: HighPriority,
|
||||
Handler: func() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}(),
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
mod := Api{
|
||||
port: tc.port,
|
||||
tlsCertFile: tc.tlsCertFile,
|
||||
tlsKeyFile: tc.tlsKeyFile,
|
||||
rootPath: tc.rootPath,
|
||||
traceHeader: tc.traceHeader,
|
||||
routes: tc.routes,
|
||||
@@ -673,6 +730,8 @@ func TestApi_Start(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
readyFn []func() error
|
||||
tlsCertFile string
|
||||
tlsKeyFile string
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
@@ -691,10 +750,22 @@ func TestApi_Start(t *testing.T) {
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
scenario: "success with tls",
|
||||
readyFn: []func() error{
|
||||
func() error { return nil },
|
||||
func() error { return nil },
|
||||
},
|
||||
tlsCertFile: "/tests/test/testdata/api/cert.pem",
|
||||
tlsKeyFile: "/tests/test/testdata/api/key.pem",
|
||||
expectError: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
mod := new(Api)
|
||||
mod.port = 3000
|
||||
mod.tlsCertFile = tc.tlsCertFile
|
||||
mod.tlsKeyFile = tc.tlsKeyFile
|
||||
mod.startTimeout = time.Duration(30) * time.Second
|
||||
mod.rootPath = "/"
|
||||
mod.basicAuthUsername = "foo"
|
||||
|
||||
Reference in New Issue
Block a user