diff --git a/build/docs/content/03-environment-variables.md b/build/docs/content/03-environment-variables.md index b1522740..de22646d 100644 --- a/build/docs/content/03-environment-variables.md +++ b/build/docs/content/03-environment-variables.md @@ -58,6 +58,12 @@ The hard limit is 100 MB and is defined by Google Chrome itself. > The default Google Chrome rpcc buffer size may also be overridden per request thanks to the form field `googleChromeRpccBufferSize`. > See the [rpcc buffer size section](#html.rpcc_buffer_size). +## Google Chrome ignore certificate errors + +When performing a [URL](#url) conversion, Google Chrome will not accept certificate errors . + +You may allow insecure connections by setting `GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS` variable to `"1"`. **You should be careful with this feature and only enable it in your development environment.** + ## Disable LibreOffice (unoconv) You may also disable LibreOffice (unoconv) with `DISABLE_UNOCONV`. diff --git a/cmd/gotenberg/main.go b/cmd/gotenberg/main.go index 4759d7d6..6f0135f2 100644 --- a/cmd/gotenberg/main.go +++ b/cmd/gotenberg/main.go @@ -28,7 +28,7 @@ func main() { systemLogger.DebugOpf(op, "configuration: %+v", config) if !config.DisableGoogleChrome() { // start Google Chrome headless. - if err := chrome.Start(systemLogger); err != nil { + if err := chrome.Start(systemLogger, config.GoogleChromeIgnoreCertificateErrors()); err != nil { systemLogger.FatalOp(op, err) } } diff --git a/docs/index.html b/docs/index.html index d0db910f..8e1889e7 100755 --- a/docs/index.html +++ b/docs/index.html @@ -167,14 +167,14 @@ $ make publish GOTENBERG_USER_GID=You may also add it in your Docker Compose stack:

-
version: '3'
+
version: '3'
 
-services:
+services:
 
   # your other services
 
-  gotenberg:
-    image: thecodingmachine/gotenberg:6
+  gotenberg:
+    image: thecodingmachine/gotenberg:6
 
@@ -332,6 +332,12 @@ The hard limit is 100 MB and is defined by Google Chrome itself.

See the rpcc buffer size section.

+

Ignore certificate errors

+ +

By default the chrome instance will not accept certificate errors when using the URL print method. Setting this environment variable to "1" will allow insecure connections to be used. In dev environment for example. Be careful with this! Do not use in production.

+

Disable LibreOffice (unoconv)

@@ -1700,14 +1706,14 @@ if the API is under heavy load.

For instance, using the following Docker Compose file:

-
version: '3'
+
version: '3'
 
-services:
+services:
 
   # your other services
 
-  gotenberg:
-    image: thecodingmachine/gotenberg:6
+  gotenberg:
+    image: thecodingmachine/gotenberg:6
 

You may now launch your services using:

diff --git a/internal/pkg/chrome/chrome.go b/internal/pkg/chrome/chrome.go index a2250cfc..07a3df1b 100644 --- a/internal/pkg/chrome/chrome.go +++ b/internal/pkg/chrome/chrome.go @@ -16,11 +16,11 @@ import ( ) // Start starts Google Chrome headless in background. -func Start(logger xlog.Logger) error { +func Start(logger xlog.Logger, ignoreCertificateErrors bool) error { const op string = "chrome.Start" logger.DebugOp(op, "starting new Google Chrome headless process on port 9222...") resolver := func() error { - cmd, err := cmd(logger) + cmd, err := cmd(logger, ignoreCertificateErrors) if err != nil { return err } @@ -32,7 +32,7 @@ func Start(logger xlog.Logger) error { // if the process failed to start correctly, // we have to restart it. if !isViable(logger) { - return restart(logger, cmd.Process) + return restart(logger, cmd.Process, ignoreCertificateErrors) } return nil } @@ -42,7 +42,7 @@ func Start(logger xlog.Logger) error { return nil } -func cmd(logger xlog.Logger) (*exec.Cmd, error) { +func cmd(logger xlog.Logger, ignoreCertificateErrors bool) (*exec.Cmd, error) { const op string = "chrome.cmd" binary := "google-chrome-stable" args := []string{ @@ -66,6 +66,11 @@ func cmd(logger xlog.Logger) (*exec.Cmd, error) { "--mute-audio", "--no-first-run", } + + if ignoreCertificateErrors { + args = append(args, "--ignore-certificate-errors") + } + cmd, err := xexec.Command(logger, binary, args...) if err != nil { return nil, xerror.New(op, err) @@ -93,7 +98,7 @@ func kill(logger xlog.Logger, proc *os.Process) error { return nil } -func restart(logger xlog.Logger, proc *os.Process) error { +func restart(logger xlog.Logger, proc *os.Process, ignoreCertificateErrors bool) error { const op string = "chrome.restart" logger.DebugOp(op, "restarting Google Chrome headless process using port 9222...") resolver := func() error { @@ -101,7 +106,7 @@ func restart(logger xlog.Logger, proc *os.Process) error { if err := kill(logger, proc); err != nil { return err } - cmd, err := cmd(logger) + cmd, err := cmd(logger, ignoreCertificateErrors) if err != nil { return err } @@ -113,7 +118,7 @@ func restart(logger xlog.Logger, proc *os.Process) error { // if the process failed to restart correctly, // we have to restart it again. if !isViable(logger) { - return restart(logger, cmd.Process) + return restart(logger, cmd.Process, ignoreCertificateErrors) } return nil } diff --git a/internal/pkg/conf/conf.go b/internal/pkg/conf/conf.go index 45d1bce1..3f3cbe99 100644 --- a/internal/pkg/conf/conf.go +++ b/internal/pkg/conf/conf.go @@ -40,6 +40,9 @@ const ( // DefaultGoogleChromeRpccBufferSizeEnvVar contains the name // of the environment variable "DEFAULT_GOOGLE_CHROME_RPCC_BUFFER_SIZE". DefaultGoogleChromeRpccBufferSizeEnvVar string = "DEFAULT_GOOGLE_CHROME_RPCC_BUFFER_SIZE" + // GoogleChromeIgnoreCertificateErrorsEnvVar contains the name + // of the environment variable "GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS". + GoogleChromeIgnoreCertificateErrorsEnvVar string = "GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS" ) // Config contains the application @@ -53,6 +56,7 @@ type Config struct { defaultListenPort int64 disableGoogleChrome bool disableUnoconv bool + googleChromeIgnoreCertificateErrors bool logLevel xlog.Level rootPath string maximumGoogleChromeRpccBufferSize int64 @@ -75,6 +79,7 @@ func DefaultConfig() Config { rootPath: "/", maximumGoogleChromeRpccBufferSize: 104857600, // ~100 MB defaultGoogleChromeRpccBufferSize: 1048576, // 1 MB + googleChromeIgnoreCertificateErrors: false, } } @@ -188,6 +193,14 @@ func FromEnv() (Config, error) { if err != nil { return c, err } + googleChromeIgnoreCertificateErrors, err := xassert.BoolFromEnv( + GoogleChromeIgnoreCertificateErrorsEnvVar, + c.googleChromeIgnoreCertificateErrors, + ) + c.googleChromeIgnoreCertificateErrors = googleChromeIgnoreCertificateErrors + if err != nil { + return c, err + } return c, nil } result, err := resolver() @@ -274,3 +287,7 @@ func (c Config) MaximumGoogleChromeRpccBufferSize() int64 { func (c Config) DefaultGoogleChromeRpccBufferSize() int64 { return c.defaultGoogleChromeRpccBufferSize } + +func (c Config) GoogleChromeIgnoreCertificateErrors() bool { + return c.urlIgnoreCertificateErrors +} diff --git a/internal/pkg/conf/conf_test.go b/internal/pkg/conf/conf_test.go index 678ac2aa..1fbb1cf7 100644 --- a/internal/pkg/conf/conf_test.go +++ b/internal/pkg/conf/conf_test.go @@ -380,6 +380,43 @@ func TestDefaultGoogleChromeRpccBufferSizeFromEnv(t *testing.T) { os.Unsetenv(DefaultGoogleChromeRpccBufferSizeEnvVar) } +func TestGoogleChromeIgnoreCertificateErrorsFromEnv(t *testing.T) { + var ( + expected Config + result Config + err error + ) + // GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS correctly set to true. + os.Setenv(GoogleChromeIgnoreCertificateErrorsEnvVar, "1") + expected = DefaultConfig() + expected.googleChromeIgnoreCertificateErrors = true + result, err = FromEnv() + assert.Nil(t, err) + assert.Equal(t, expected, result) + os.Unsetenv(GoogleChromeIgnoreCertificateErrorsEnvVar) + // GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS correctly set to false. + os.Setenv(GooleChromeIgnoreCertificateErrorsEnvVar, "0") + expected = DefaultConfig() + expected.googleChromeIgnoreCertificateErrors = false + result, err = FromEnv() + assert.Nil(t, err) + assert.Equal(t, expected, result) + os.Unsetenv(GoogleChromeIgnoreCertificateErrorsEnvVar) + // GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS wrongly set. + os.Setenv(GoogleChromeIgnoreCertificateErrorsEnvVar, "foo") + expected = DefaultConfig() + result, err = FromEnv() + test.AssertError(t, err) + assert.Equal(t, expected, result) + os.Unsetenv(GoogleChromeIgnoreCertificateErrorsEnvVar) + // GOOGLE_CHROME_IGNORE_CERTIFICATE_ERRORS not set at all. + expected = DefaultConfig() + expected.googleChromeIgnoreCertificateErrors = false + result, err = FromEnv() + assert.Nil(t, err) + assert.Equal(t, expected, result) +} + func TestGetters(t *testing.T) { result := DefaultConfig() assert.Equal(t, result.maximumWaitTimeout, result.MaximumWaitTimeout()) @@ -394,4 +431,5 @@ func TestGetters(t *testing.T) { assert.Equal(t, result.rootPath, result.RootPath()) assert.Equal(t, result.maximumGoogleChromeRpccBufferSize, result.MaximumGoogleChromeRpccBufferSize()) assert.Equal(t, result.defaultGoogleChromeRpccBufferSize, result.DefaultGoogleChromeRpccBufferSize()) + assert.Equal(t, result.googleChromeIgnoreCertificateErrors, result.GoogleChromeIgnoreCertificateErrors()) } diff --git a/test/cmd/chrome.go b/test/cmd/chrome.go index 73d96474..82234f3e 100644 --- a/test/cmd/chrome.go +++ b/test/cmd/chrome.go @@ -14,7 +14,7 @@ func main() { systemLogger.FatalOp(op, err) } // start Google Chrome headless. - if err := chrome.Start(systemLogger); err != nil { + if err := chrome.Start(systemLogger, config.GoogleChromeIgnoreCertificateErrors()); err != nil { systemLogger.FatalOp(op, err) } }