mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-16 20:32:13 +01:00
fix: websocket timeout reached (fixes #524)
This commit is contained in:
@@ -420,6 +420,14 @@ func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath
|
|||||||
args = append(args, chromedp.UserAgent(options.UserAgent))
|
args = append(args, chromedp.UserAgent(options.UserAgent))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://github.com/gotenberg/gotenberg/issues/524.
|
||||||
|
deadline, ok := ctx.Deadline()
|
||||||
|
if !ok {
|
||||||
|
return errors.New("context has no deadline")
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, chromedp.WSURLReadTimeout(time.Until(deadline)))
|
||||||
|
|
||||||
allocatorCtx, cancel := chromedp.NewExecAllocator(ctx, args...)
|
allocatorCtx, cancel := chromedp.NewExecAllocator(ctx, args...)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
|||||||
@@ -224,7 +224,8 @@ func TestChromium_Routes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestChromium_PDF(t *testing.T) {
|
func TestChromium_PDF(t *testing.T) {
|
||||||
for i, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
URL string
|
URL string
|
||||||
@@ -243,34 +244,51 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
expectErr bool
|
expectErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
name: "context has no deadline",
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample1/index.html",
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "URL does not match the expression from the allowed list",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
allowList: regexp.MustCompile("file:///tmp/*"),
|
allowList: regexp.MustCompile("file:///tmp/*"),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "URL does not match the expression from the denied list",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
denyList: regexp.MustCompile("file:///tests/*"),
|
denyList: regexp.MustCompile("file:///tests/*"),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with user agent",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
UserAgent: "foo",
|
UserAgent: "foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample10/index.html",
|
name: "fail on console exceptions",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample10/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
FailOnConsoleExceptions: true,
|
FailOnConsoleExceptions: true,
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "disable JavaScript",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample9/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample9/index.html",
|
||||||
disableJavaScript: true,
|
disableJavaScript: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with extra HTTP headers",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
ExtraHTTPHeaders: map[string]string{
|
ExtraHTTPHeaders: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
@@ -278,7 +296,9 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample11/index.html",
|
name: "with extra link tags",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample11/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
ExtraLinkTags: []LinkTag{
|
ExtraLinkTags: []LinkTag{
|
||||||
{
|
{
|
||||||
@@ -291,26 +311,34 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample8/index.html",
|
name: "with invalid emulated media type",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample8/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
EmulatedMediaType: "foo",
|
EmulatedMediaType: "foo",
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample8/index.html",
|
name: "with screen emulated media type",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample8/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
EmulatedMediaType: "screen",
|
EmulatedMediaType: "screen",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample8/index.html",
|
name: "with print emulated media type",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample8/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
EmulatedMediaType: "print",
|
EmulatedMediaType: "print",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample11/index.html",
|
name: "with extra script tags",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample11/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
ExtraScriptTags: []ScriptTag{
|
ExtraScriptTags: []ScriptTag{
|
||||||
{
|
{
|
||||||
@@ -320,12 +348,15 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with wait delay",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
WaitDelay: time.Duration(1) * time.Nanosecond,
|
WaitDelay: time.Duration(1) * time.Nanosecond,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "with invalid wait window status",
|
||||||
timeout: time.Duration(3) * time.Second,
|
timeout: time.Duration(3) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
@@ -334,6 +365,7 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "with wait window status",
|
||||||
timeout: time.Duration(3) * time.Second,
|
timeout: time.Duration(3) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
@@ -341,6 +373,7 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "with wait for expression that should not happen",
|
||||||
timeout: time.Duration(3) * time.Second,
|
timeout: time.Duration(3) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
@@ -349,6 +382,7 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "with valid wait for expression",
|
||||||
timeout: time.Duration(3) * time.Second,
|
timeout: time.Duration(3) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample2/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
@@ -356,27 +390,35 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with invalid wait for expression",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
WaitForExpression: "return undefined",
|
WaitForExpression: "return undefined",
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with too big margin bottom",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
MarginBottom: 100,
|
MarginBottom: 100,
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with invalid page ranges",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
PageRanges: "foo",
|
PageRanges: "foo",
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "with a lot of options",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
userAgent: "foo",
|
userAgent: "foo",
|
||||||
incognito: true,
|
incognito: true,
|
||||||
@@ -388,18 +430,26 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
proxyServer: "foo",
|
proxyServer: "foo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample1/index.html",
|
name: "with file using local and remote assets",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample1/index.html",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "URL does match the expression from the allowed list",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample3/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample3/index.html",
|
||||||
allowList: regexp.MustCompile("file:///tests/*"),
|
allowList: regexp.MustCompile("file:///tests/*"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "URL does match the expression from the denied list",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample3/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample3/index.html",
|
||||||
denyList: regexp.MustCompile("file:///etc/*"),
|
denyList: regexp.MustCompile("file:///etc/*"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
name: "with custom header and footer templates",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
|
||||||
options: Options{
|
options: Options{
|
||||||
HeaderTemplate: func() string {
|
HeaderTemplate: func() string {
|
||||||
b, err := os.ReadFile("/tests/test/testdata/chromium/url/sample2/header.html")
|
b, err := os.ReadFile("/tests/test/testdata/chromium/url/sample2/header.html")
|
||||||
@@ -420,14 +470,20 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample5/index.html",
|
name: "with file using a .gif",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample5/index.html",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "with allow file access from files",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample6/index.html",
|
URL: "file:///tests/test/testdata/chromium/html/sample6/index.html",
|
||||||
allowFileAccessFromFiles: true,
|
allowFileAccessFromFiles: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
URL: "file:///tests/test/testdata/chromium/html/sample7/index.html",
|
name: "with file using a style attribute",
|
||||||
|
timeout: time.Duration(60) * time.Second,
|
||||||
|
URL: "file:///tests/test/testdata/chromium/html/sample7/index.html",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
func() {
|
func() {
|
||||||
@@ -456,13 +512,13 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
|
|
||||||
outputDir, err := gotenberg.MkdirAll()
|
outputDir, err := gotenberg.MkdirAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %d: expected error but got: %v", i, err)
|
t.Fatalf("test %s: expected error but got: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
err := os.RemoveAll(outputDir)
|
err := os.RemoveAll(outputDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
t.Fatalf("test %s: expected no error but got: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -476,11 +532,11 @@ func TestChromium_PDF(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.expectErr && err == nil {
|
if tc.expectErr && err == nil {
|
||||||
t.Errorf("test %d: expected error but got: %v", i, err)
|
t.Errorf("test %s: expected error but got: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tc.expectErr && err != nil {
|
if !tc.expectErr && err != nil {
|
||||||
t.Errorf("test %d: expected no error but got: %v", i, err)
|
t.Errorf("test %s: expected no error but got: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user