updating with base branch

This commit is contained in:
Julien Neuhart
2019-12-10 15:17:25 +01:00
47 changed files with 1728 additions and 594 deletions

View File

@@ -2,6 +2,7 @@ package printer
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
@@ -30,18 +31,20 @@ type chromePrinter struct {
// ChromePrinterOptions helps customizing the
// Google Chrome Printer behaviour.
type ChromePrinterOptions struct {
WaitTimeout float64
WaitDelay float64
HeaderHTML string
FooterHTML string
PaperWidth float64
PaperHeight float64
MarginTop float64
MarginBottom float64
MarginLeft float64
MarginRight float64
Landscape bool
PageRanges string
WaitTimeout float64
WaitDelay float64
HeaderHTML string
FooterHTML string
PaperWidth float64
PaperHeight float64
MarginTop float64
MarginBottom float64
MarginLeft float64
MarginRight float64
Landscape bool
PageRanges string
RpccBufferSize int64
CustomHTTPHeaders map[string]string
}
// DefaultChromePrinterOptions returns the default
@@ -49,18 +52,20 @@ type ChromePrinterOptions struct {
func DefaultChromePrinterOptions(config conf.Config) ChromePrinterOptions {
const defaultHeaderFooterHTML string = "<html><head></head><body></body></html>"
return ChromePrinterOptions{
WaitTimeout: config.DefaultWaitTimeout(),
WaitDelay: 0.0,
HeaderHTML: defaultHeaderFooterHTML,
FooterHTML: defaultHeaderFooterHTML,
PaperWidth: 8.27,
PaperHeight: 11.7,
MarginTop: 1.0,
MarginBottom: 1.0,
MarginLeft: 1.0,
MarginRight: 1.0,
Landscape: false,
PageRanges: "",
WaitTimeout: config.DefaultWaitTimeout(),
WaitDelay: 0.0,
HeaderHTML: defaultHeaderFooterHTML,
FooterHTML: defaultHeaderFooterHTML,
PaperWidth: 8.27,
PaperHeight: 11.7,
MarginTop: 1.0,
MarginBottom: 1.0,
MarginLeft: 1.0,
MarginRight: 1.0,
Landscape: false,
PageRanges: "",
RpccBufferSize: config.DefaultGoogleChromeRpccBufferSize(),
CustomHTTPHeaders: make(map[string]string),
}
}
@@ -113,7 +118,18 @@ func (p chromePrinter) Print(destination string) error {
}
// connect the client to the new target.
newTargetWsURL := fmt.Sprintf("ws://127.0.0.1:9222/devtools/page/%s", newTarget.TargetID)
newContextConn, err := rpcc.DialContext(ctx, newTargetWsURL)
newContextConn, err := rpcc.DialContext(
ctx,
newTargetWsURL,
/*
see:
https://github.com/thecodingmachine/gotenberg/issues/108
https://github.com/mafredri/cdp/issues/4
https://github.com/ChromeDevTools/devtools-protocol/issues/24
*/
rpcc.WithWriteBufferSize(int(p.opts.RpccBufferSize)),
rpcc.WithCompression(),
)
if err != nil {
return err
}
@@ -133,6 +149,10 @@ func (p chromePrinter) Print(destination string) error {
if err := p.enableEvents(ctx, targetClient); err != nil {
return err
}
// add custom headers (if any).
if err := p.setCustomHTTPHeaders(ctx, targetClient); err != nil {
return err
}
// listen for all events.
if err := p.listenEvents(ctx, targetClient); err != nil {
return err
@@ -166,7 +186,7 @@ func (p chromePrinter) Print(destination string) error {
printToPdfArgs,
)
if err != nil {
// TODO: find a way to check it in the handlers.
// find a way to check it in the handlers?
if strings.Contains(err.Error(), "Page range syntax error") {
return xerror.Invalid(
op,
@@ -174,6 +194,16 @@ func (p chromePrinter) Print(destination string) error {
err,
)
}
if strings.Contains(err.Error(), "rpcc: message too large") {
return xerror.Invalid(
op,
fmt.Sprintf(
"'%d' bytes are not enough: increase the Google Chrome rpcc buffer size (up to 100 MB)",
p.opts.RpccBufferSize,
),
err,
)
}
return err
}
if err := ioutil.WriteFile(destination, print.Data, 0644); err != nil {
@@ -238,6 +268,32 @@ func (p chromePrinter) enableEvents(ctx context.Context, client *cdp.Client) err
return nil
}
func (p chromePrinter) setCustomHTTPHeaders(ctx context.Context, client *cdp.Client) error {
const op string = "printer.chromePrinter.setCustomHTTPHeaders"
resolver := func() error {
if len(p.opts.CustomHTTPHeaders) == 0 {
p.logger.DebugOp(op, "skipping custom HTTP headers as none have been provided...")
return nil
}
customHTTPHeaders := make(map[string]string)
// useless but for the logs.
for key, value := range p.opts.CustomHTTPHeaders {
customHTTPHeaders[key] = value
p.logger.DebugfOp(op, "set '%s' to custom HTTP header '%s'", value, key)
}
b, err := json.Marshal(customHTTPHeaders)
if err != nil {
return err
}
// should always be called after client.Network.Enable.
return client.Network.SetExtraHTTPHeaders(ctx, network.NewSetExtraHTTPHeadersArgs(b))
}
if err := resolver(); err != nil {
return xerror.New(op, err)
}
return nil
}
func (p chromePrinter) listenEvents(ctx context.Context, client *cdp.Client) error {
const op string = "printer.chromePrinter.listenEvents"
resolver := func() error {

View File

@@ -2,6 +2,7 @@ package printer
import (
"context"
"sort"
"github.com/thecodingmachine/gotenberg/internal/pkg/conf"
"github.com/thecodingmachine/gotenberg/internal/pkg/xcontext"
@@ -54,6 +55,8 @@ func (p mergePrinter) Print(destination string) error {
defer cancel()
p.ctx = ctx
}
// see https://github.com/thecodingmachine/gotenberg/issues/139.
sort.Strings(p.fpaths)
p.logger.DebugfOp(op, "merging '%v'...", p.fpaths)
resolver := func() error {
var args []string

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"github.com/phayes/freeport"
@@ -56,6 +57,8 @@ func (p officePrinter) Print(destination string) error {
ctx, cancel := xcontext.WithTimeout(p.logger, p.opts.WaitTimeout)
defer cancel()
resolver := func() error {
// see https://github.com/thecodingmachine/gotenberg/issues/139.
sort.Strings(p.fpaths)
fpaths := make([]string, len(p.fpaths))
dirPath := filepath.Dir(destination)
for i, fpath := range p.fpaths {
@@ -111,7 +114,7 @@ func (p officePrinter) unoconv(ctx context.Context, fpath, destination string) e
}
args = append(args, "--output", destination, fpath)
if err := xexec.Run(ctx, p.logger, "unoconv", args...); err != nil {
// TODO: find a way to check it in the handlers.
// find a way to check it in the handlers?
if p.opts.PageRanges != "" && strings.Contains(err.Error(), "exit status 5") {
return xerror.Invalid(
op,