refactor(pdfengines): remove qpdf embed fallback (#1628)

This commit is contained in:
Julien Neuhart
2026-08-14 11:07:16 +02:00
parent cc1341c3cf
commit 1303e0ebc9
3 changed files with 7 additions and 47 deletions

View File

@@ -91,7 +91,7 @@ PDFENGINES_WATERMARK_ENGINES=pdfcpu,pdftk
PDFENGINES_STAMP_ENGINES=pdfcpu,pdftk
PDFENGINES_ENCRYPT_ENGINES=qpdf,pdfcpu,pdftk
PDFENGINES_ROTATE_ENGINES=pdfcpu,pdftk
PDFENGINES_EMBED_ENGINES=pdfcpu,qpdf
PDFENGINES_EMBED_ENGINES=pdfcpu
PDFENGINES_EMBED_METADATA_ENGINES=qpdf
PDFENGINES_FACTUR_X_ENGINES=qpdf
PROMETHEUS_NAMESPACE=gotenberg

View File

@@ -62,7 +62,7 @@ func (mod *PdfEngines) Descriptor() gotenberg.ModuleDescriptor {
fs.StringSlice("pdfengines-read-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the read metadata feature - empty means all")
fs.StringSlice("pdfengines-write-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the write metadata feature - empty means all")
fs.StringSlice("pdfengines-encrypt-engines", []string{"qpdf", "pdftk", "pdfcpu"}, "Set the PDF engines and their order for the password protection feature - empty means all")
fs.StringSlice("pdfengines-embed-engines", []string{"pdfcpu", "qpdf"}, "Set the PDF engines and their order for the file embedding feature - empty means all")
fs.StringSlice("pdfengines-embed-engines", []string{"pdfcpu"}, "Set the PDF engines and their order for the file embedding feature - empty means all")
fs.StringSlice("pdfengines-embed-metadata-engines", []string{"qpdf"}, "Set the PDF engines and their order for the embed metadata feature - empty means all")
fs.StringSlice("pdfengines-read-bookmarks-engines", []string{"pdfcpu"}, "Set the PDF engines and their order for the read bookmarks feature - empty means all")
fs.StringSlice("pdfengines-write-bookmarks-engines", []string{"pdfcpu"}, "Set the PDF engines and their order for the write bookmarks feature - empty means all")

View File

@@ -419,57 +419,17 @@ func (engine *QPdf) Encrypt(ctx context.Context, logger *slog.Logger, inputPath
}
// EmbedFiles is not available in this implementation.
// EmbedFiles embeds the given files into a PDF as attachments using qpdf's
// --add-attachment. It is a fallback for pdfcpu: qpdf reads PDFs whose document
// info pdfcpu's stricter validation rejects (for example a non-conformant
// /Trapped value written by ExifTool). See
// https://github.com/gotenberg/gotenberg/issues/1628.
func (engine *QPdf) EmbedFiles(ctx context.Context, logger *slog.Logger, filePaths []string, inputPath string) error {
ctx, span := gotenberg.Tracer().Start(ctx, "qpdf.EmbedFiles",
_, span := gotenberg.Tracer().Start(ctx, "qpdf.EmbedFiles",
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(engine.spanAttrs()...),
)
defer span.End()
if len(filePaths) == 0 {
span.SetStatus(codes.Ok, "")
return nil
}
fail := func(err error) error {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
// Each --add-attachment group must be terminated by "--", so qpdf attaches
// one file per invocation. Chain them, writing to a temporary file and
// moving it back over the input each time.
outputPath := inputPath + "~embed"
for _, filePath := range filePaths {
args := make([]string, 0, 6+len(engine.globalArgs))
args = append(args, engine.globalArgs...)
args = append(args, "--add-attachment", filePath, "--key="+filepath.Base(filePath))
args = append(args, "--", inputPath, outputPath)
cmd, err := gotenberg.CommandContext(ctx, logger, engine.binPath, args...)
if err != nil {
return fail(fmt.Errorf("create command: %w", err))
}
_, err = cmd.Exec()
if err != nil {
return fail(fmt.Errorf("embed files with QPDF: %w", err))
}
err = os.Rename(outputPath, inputPath)
if err != nil {
return fail(fmt.Errorf("embed files with QPDF: replace input: %w", err))
}
}
span.SetStatus(codes.Ok, "")
return nil
err := fmt.Errorf("embed files with QPDF: %w", gotenberg.ErrPdfEngineMethodNotSupported)
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
// EmbedFilesMetadata sets metadata on already-embedded files in a PDF using