mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-10-16 17:23:17 +01:00
Compare commits
4 Commits
b16ce08da7
...
v8.37.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
430ed38cc5 | ||
|
|
623e93bf3e | ||
|
|
fe4fb9416d | ||
|
|
fb7536a526 |
15
Makefile
15
Makefile
@@ -219,20 +219,17 @@ lint-prettier: ## Lint non-Golang codebase
|
|||||||
lint-todo: ## Find TODOs in Golang codebase
|
lint-todo: ## Find TODOs in Golang codebase
|
||||||
golangci-lint run --no-config --default=none --enable godox
|
golangci-lint run --no-config --default=none --enable godox
|
||||||
|
|
||||||
# TODO: restore a plain "go fix ./..." once both modernizers stop rewriting this
|
# TODO: restore a plain "go fix ./..." once the errorsastype modernizer stops
|
||||||
# codebase into code that does not compile. Re-check by dropping a flag and
|
# rewriting this codebase into code that does not compile. Re-check by dropping
|
||||||
# running "make fmt && make lint". Removing an analyzer upstream makes go fix
|
# the flag and running "make fmt && make lint". Removing the analyzer upstream
|
||||||
# fail with "flag provided but not defined", so this cannot rot silently.
|
# makes go fix fail with "flag provided but not defined", so this cannot rot
|
||||||
# embedlit folds a post-literal field assignment into a literal that already
|
# silently.
|
||||||
# sets that key, producing a duplicate field name (cmd/gotenberg.go). Fixed in
|
|
||||||
# Go 1.27.1, so drop that flag once the toolchain moves past 1.27.0.
|
|
||||||
# See https://github.com/golang/go/issues/81101.
|
|
||||||
# errorsastype rewrites errors.As to errors.AsType[T] without checking that T
|
# errorsastype rewrites errors.As to errors.AsType[T] without checking that T
|
||||||
# satisfies error, which breaks on api.HttpError since it does not embed
|
# satisfies error, which breaks on api.HttpError since it does not embed
|
||||||
# error. Still broken as of Go 1.27.1.
|
# error. Still broken as of Go 1.27.1.
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt: ## Format Golang codebase and "optimize" the dependencies
|
fmt: ## Format Golang codebase and "optimize" the dependencies
|
||||||
go fix -embedlit=false -errorsastype=false ./...
|
go fix -errorsastype=false ./...
|
||||||
golangci-lint fmt
|
golangci-lint fmt
|
||||||
go mod tidy
|
go mod tidy
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# ARG instructions do not create additional layers. Instead, next layers will
|
# ARG instructions do not create additional layers. Instead, next layers will
|
||||||
# concatenate them. Also, we have to repeat ARG instructions in each build
|
# concatenate them. Also, we have to repeat ARG instructions in each build
|
||||||
# stage that uses them.
|
# stage that uses them.
|
||||||
ARG GOLANG_VERSION=1.27.0
|
ARG GOLANG_VERSION=1.27.1
|
||||||
|
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
# pdfcpu binary build stage
|
# pdfcpu binary build stage
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/gotenberg/gotenberg/v8
|
module github.com/gotenberg/gotenberg/v8
|
||||||
|
|
||||||
go 1.27.0
|
go 1.27.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexliesenfeld/health v0.8.1
|
github.com/alexliesenfeld/health v0.8.1
|
||||||
@@ -34,7 +34,7 @@ require (
|
|||||||
go.opentelemetry.io/otel/sdk/metric v1.46.0
|
go.opentelemetry.io/otel/sdk/metric v1.46.0
|
||||||
go.opentelemetry.io/otel/trace v1.46.0
|
go.opentelemetry.io/otel/trace v1.46.0
|
||||||
golang.org/x/net v0.58.0
|
golang.org/x/net v0.58.0
|
||||||
golang.org/x/sync v0.22.0
|
golang.org/x/sync v0.23.0
|
||||||
golang.org/x/term v0.45.0
|
golang.org/x/term v0.45.0
|
||||||
golang.org/x/text v0.41.0
|
golang.org/x/text v0.41.0
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -305,8 +305,8 @@ golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
|
|||||||
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
|
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
|
||||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||||
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
|
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
|
||||||
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|||||||
@@ -201,17 +201,13 @@ func TestNewServerRecordMetrics(t *testing.T) {
|
|||||||
server.RecordMetrics(t.Context(), semconv.ServerMetricData{
|
server.RecordMetrics(t.Context(), semconv.ServerMetricData{
|
||||||
ServerName: "stuff",
|
ServerName: "stuff",
|
||||||
ResponseSize: 200,
|
ResponseSize: 200,
|
||||||
MetricAttributes: semconv.MetricAttributes{
|
Req: req,
|
||||||
Req: req,
|
StatusCode: 301,
|
||||||
StatusCode: 301,
|
AdditionalAttributes: []attribute.KeyValue{
|
||||||
AdditionalAttributes: []attribute.KeyValue{
|
attribute.String("key", "value"),
|
||||||
attribute.String("key", "value"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MetricData: semconv.MetricData{
|
|
||||||
RequestSize: 100,
|
|
||||||
ElapsedTime: 300,
|
|
||||||
},
|
},
|
||||||
|
RequestSize: 100,
|
||||||
|
ElapsedTime: 300,
|
||||||
})
|
})
|
||||||
|
|
||||||
rm := metricdata.ResourceMetrics{}
|
rm := metricdata.ResourceMetrics{}
|
||||||
|
|||||||
@@ -355,17 +355,13 @@ func telemetryMiddleware(logger *slog.Logger, serverName, correlationIdHeader st
|
|||||||
}
|
}
|
||||||
|
|
||||||
semconvSrv.RecordMetrics(ctx, semconvutil.ServerMetricData{
|
semconvSrv.RecordMetrics(ctx, semconvutil.ServerMetricData{
|
||||||
ServerName: serverName,
|
ServerName: serverName,
|
||||||
ResponseSize: c.Response().Size,
|
ResponseSize: c.Response().Size,
|
||||||
MetricAttributes: semconvutil.MetricAttributes{
|
Req: request,
|
||||||
Req: request,
|
StatusCode: status,
|
||||||
StatusCode: status,
|
AdditionalAttributes: additionalAttributes,
|
||||||
AdditionalAttributes: additionalAttributes,
|
RequestSize: request.ContentLength,
|
||||||
},
|
ElapsedTime: float64(time.Since(startTime)) / float64(time.Millisecond),
|
||||||
MetricData: semconvutil.MetricData{
|
|
||||||
RequestSize: request.ContentLength,
|
|
||||||
ElapsedTime: float64(time.Since(startTime)) / float64(time.Millisecond),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -23,6 +23,25 @@ import (
|
|||||||
"github.com/gotenberg/gotenberg/v8/pkg/gotenberg"
|
"github.com/gotenberg/gotenberg/v8/pkg/gotenberg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// chromiumDisableFeatures is the value of Chromium's --disable-features
|
||||||
|
// switch.
|
||||||
|
//
|
||||||
|
// It restates the "site-per-process,Translate,BlinkGenPropertyTrees" default
|
||||||
|
// from chromedp.DefaultExecAllocatorOptions (chromedp v0.14.2) on purpose:
|
||||||
|
// chromedp.Flag keys its flags by switch name, so a second --disable-features
|
||||||
|
// replaces chromedp's value instead of merging with it. Revisit this list when
|
||||||
|
// bumping chromedp.
|
||||||
|
//
|
||||||
|
// WebUIOmniboxPopup and WebUIOmniboxAimPopup became enabled by default in
|
||||||
|
// Chromium 151.0.7922.132. Their presenters build the address-bar popup WebUI
|
||||||
|
// at browser start, headless included, which leaves a renderer process holding
|
||||||
|
// ~85 MB of anonymous memory for a UI a PDF service can never show. Chromium
|
||||||
|
// silently ignores feature names it does not know, so both stay harmless on
|
||||||
|
// older builds (they exist but default to disabled on the Chromium pinned for
|
||||||
|
// ppc64el) and once upstream eventually removes them.
|
||||||
|
// See https://github.com/gotenberg/gotenberg/issues/1656.
|
||||||
|
const chromiumDisableFeatures = "site-per-process,Translate,BlinkGenPropertyTrees,WebUIOmniboxPopup,WebUIOmniboxAimPopup"
|
||||||
|
|
||||||
type browser interface {
|
type browser interface {
|
||||||
gotenberg.Process
|
gotenberg.Process
|
||||||
pdf(ctx context.Context, logger *slog.Logger, url, outputPath string, options PdfOptions, aggregate *networkAggregate) error
|
pdf(ctx context.Context, logger *slog.Logger, url, outputPath string, options PdfOptions, aggregate *networkAggregate) error
|
||||||
@@ -133,6 +152,8 @@ func (b *chromiumBrowser) Start(logger *slog.Logger) error {
|
|||||||
chromedp.Flag("disable-dev-shm-usage", true),
|
chromedp.Flag("disable-dev-shm-usage", true),
|
||||||
// See https://github.com/gotenberg/gotenberg/issues/1293.
|
// See https://github.com/gotenberg/gotenberg/issues/1293.
|
||||||
chromedp.Flag("disable-component-update", false),
|
chromedp.Flag("disable-component-update", false),
|
||||||
|
// See https://github.com/gotenberg/gotenberg/issues/1656.
|
||||||
|
chromedp.Flag("disable-features", chromiumDisableFeatures),
|
||||||
)
|
)
|
||||||
|
|
||||||
if b.arguments.allowInsecureLocalhost {
|
if b.arguments.allowInsecureLocalhost {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package chromium
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -37,3 +38,24 @@ func TestChromiumBrowser_Start_rejectsOverlappingStart(t *testing.T) {
|
|||||||
t.Fatal("expected the browser to stay not started")
|
t.Fatal("expected the browser to stay not started")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestChromiumDisableFeatures guards the override described in
|
||||||
|
// https://github.com/gotenberg/gotenberg/issues/1656. Gotenberg replaces
|
||||||
|
// chromedp's --disable-features value rather than extending it, as
|
||||||
|
// chromedp.Flag keys its flags by switch name. Dropping one of chromedp's own
|
||||||
|
// entries while editing this list would silently re-enable it.
|
||||||
|
func TestChromiumDisableFeatures(t *testing.T) {
|
||||||
|
for _, feature := range []string{
|
||||||
|
// chromedp.DefaultExecAllocatorOptions.
|
||||||
|
"site-per-process",
|
||||||
|
"Translate",
|
||||||
|
"BlinkGenPropertyTrees",
|
||||||
|
// The address-bar popup WebUI, built even in headless.
|
||||||
|
"WebUIOmniboxPopup",
|
||||||
|
"WebUIOmniboxAimPopup",
|
||||||
|
} {
|
||||||
|
if !slices.Contains(strings.Split(chromiumDisableFeatures, ","), feature) {
|
||||||
|
t.Errorf("expected %q to be disabled, got %q", feature, chromiumDisableFeatures)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user