Compare commits

...

7 Commits

Author SHA1 Message Date
Julien Neuhart
6e47f16fe1 fix: filename case (#351) 2021-09-15 17:41:03 +02:00
Julien Neuhart
13e6c2dbeb fix: add latest version of noto color emoji front (#345) 2021-09-09 20:08:07 +02:00
remoteexception
9d27dfb41c fix: add more supported file extensions for unovonv (#340)
* Add supported file extensions for unovonv

* Fix expected file extensions length

Co-authored-by: Jana Storch <jana.storch@dpdhl.com>
2021-09-09 20:07:45 +02:00
remoteexception
9529905875 fix: only use webhook ports between 1025 and 65536 (#346)
- ports between 0 and 1024 can only be used by root in some OS

Co-authored-by: Jana Storch <jana.storch@dpdhl.com>
2021-09-09 20:06:49 +02:00
Snyk bot
eef7fc4b51 fix: build/Dockerfile to reduce vulnerabilities (#336)
The
2021-09-03 22:25:54 +02:00
Julien Neuhart
a88435f6b6 feat: add Live Demo link in the README 2021-08-29 14:38:10 +02:00
Julien Neuhart
0b22598783 fix: typo in api module godoc -> remove pointer for middleware 2021-08-28 17:59:18 +02:00
15 changed files with 133 additions and 17 deletions

View File

@@ -10,6 +10,7 @@ DOCKER_REPOSITORY=gotenberg
GOTENBERG_VERSION=snapshot GOTENBERG_VERSION=snapshot
GOTENBERG_USER_GID=1001 GOTENBERG_USER_GID=1001
GOTENBERG_USER_UID=1001 GOTENBERG_USER_UID=1001
NOTO_COLOR_EMOJI_VERSION=v2.028 # See https://github.com/googlefonts/noto-emoji/releases.
PDFTK_VERSION=1353200058 # See https://gitlab.com/pdftk-java/pdftk/-/releases - Binary package. PDFTK_VERSION=1353200058 # See https://gitlab.com/pdftk-java/pdftk/-/releases - Binary package.
GOLANGCI_LINT_VERSION=v1.42.0 # See https://github.com/golangci/golangci-lint/releases. GOLANGCI_LINT_VERSION=v1.42.0 # See https://github.com/golangci/golangci-lint/releases.
@@ -20,6 +21,7 @@ build: ## Build the Gotenberg's Docker image
--build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \ --build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \
--build-arg GOTENBERG_USER_GID=$(GOTENBERG_USER_GID) \ --build-arg GOTENBERG_USER_GID=$(GOTENBERG_USER_GID) \
--build-arg GOTENBERG_USER_UID=$(GOTENBERG_USER_UID) \ --build-arg GOTENBERG_USER_UID=$(GOTENBERG_USER_UID) \
--build-arg NOTO_COLOR_EMOJI_VERSION=$(NOTO_COLOR_EMOJI_VERSION) \
--build-arg PDFTK_VERSION=$(PDFTK_VERSION) \ --build-arg PDFTK_VERSION=$(PDFTK_VERSION) \
-t $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION) \ -t $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION) \
-f build/Dockerfile . -f build/Dockerfile .

View File

@@ -2,7 +2,7 @@
<img src="https://user-images.githubusercontent.com/8983173/130322857-185831e2-f041-46eb-a17f-0a69d066c4e5.png" alt="Gotenberg Logo" width="150" height="150" /> <img src="https://user-images.githubusercontent.com/8983173/130322857-185831e2-f041-46eb-a17f-0a69d066c4e5.png" alt="Gotenberg Logo" width="150" height="150" />
<h3 align="center">Gotenberg</h3> <h3 align="center">Gotenberg</h3>
<p align="center">A Docker-powered stateless API for PDF files</p> <p align="center">A Docker-powered stateless API for PDF files</p>
<p align="center"><a href="https://gotenberg.dev/docs/about">Documentation</a><!-- &#183; <a href="#">OpenAPI</a></p>--> <p align="center"><a href="https://gotenberg.dev/docs/about">Documentation</a> &#183; 🔥 <a href="https://gotenberg.dev/docs/get-started/live-demo">Live Demo</a></p>
</p> </p>
--- ---

View File

@@ -26,7 +26,7 @@ ARG GOTENBERG_VERSION
RUN go build -o gotenberg -ldflags "-X 'github.com/gotenberg/gotenberg/v7/cmd.Version=$GOTENBERG_VERSION'" cmd/gotenberg/main.go RUN go build -o gotenberg -ldflags "-X 'github.com/gotenberg/gotenberg/v7/cmd.Version=$GOTENBERG_VERSION'" cmd/gotenberg/main.go
FROM debian:bullseye-slim FROM debian:11-slim
ARG GOTENBERG_VERSION ARG GOTENBERG_VERSION
@@ -48,6 +48,7 @@ COPY build/pdftk.sh /usr/bin/pdftk
# Setup the Docker image. # Setup the Docker image.
ARG GOTENBERG_USER_GID ARG GOTENBERG_USER_GID
ARG GOTENBERG_USER_UID ARG GOTENBERG_USER_UID
ARG NOTO_COLOR_EMOJI_VERSION
ARG PDFTK_VERSION ARG PDFTK_VERSION
# Script for installing either Google Chrome stable on amd64 architecture or # Script for installing either Google Chrome stable on amd64 architecture or
@@ -108,6 +109,11 @@ RUN \
fonts-sil-gentium \ fonts-sil-gentium \
fonts-sil-gentium-basic &&\ fonts-sil-gentium-basic &&\
rm -f ./ttf-mscorefonts-installer_3.8_all.deb &&\ rm -f ./ttf-mscorefonts-installer_3.8_all.deb &&\
# Add Color and Black-and-White Noto emoji font.
# Credits:
# https://github.com/gotenberg/gotenberg/pull/325.
# https://github.com/googlefonts/noto-emoji.
curl -Ls "https://github.com/googlefonts/noto-emoji/raw/$NOTO_COLOR_EMOJI_VERSION/fonts/NotoColorEmoji.ttf" -o /usr/local/share/fonts/NotoColorEmoji.ttf &&\
# Install Google Chrome / Chromium. # Install Google Chrome / Chromium.
/tmp/install-chromium.sh &&\ /tmp/install-chromium.sh &&\
# Install LibreOffice. # Install LibreOffice.

8
go.mod
View File

@@ -5,17 +5,17 @@ go 1.17
require ( require (
github.com/alexliesenfeld/health v0.6.0 github.com/alexliesenfeld/health v0.6.0
github.com/andybalholm/brotli v1.0.3 // indirect github.com/andybalholm/brotli v1.0.3 // indirect
github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4 github.com/chromedp/cdproto v0.0.0-20210910012206-68626162910d
github.com/chromedp/chromedp v0.7.4 github.com/chromedp/chromedp v0.7.4
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 github.com/hashicorp/go-retryablehttp v0.7.0
github.com/klauspost/compress v1.13.4 // indirect github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect
github.com/labstack/echo/v4 v4.5.0 github.com/labstack/echo/v4 v4.5.0
github.com/labstack/gommon v0.3.0 github.com/labstack/gommon v0.3.0
github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mholt/archiver/v3 v3.5.0 github.com/mholt/archiver/v3 v3.5.0
github.com/microcosm-cc/bluemonday v1.0.15 github.com/microcosm-cc/bluemonday v1.0.15
github.com/nwaples/rardecode v1.1.2 // indirect github.com/nwaples/rardecode v1.1.2 // indirect
@@ -26,7 +26,7 @@ require (
github.com/ulikunitz/xz v0.5.10 // indirect github.com/ulikunitz/xz v0.5.10 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 go.uber.org/multierr v1.7.0
go.uber.org/zap v1.19.0 go.uber.org/zap v1.19.1
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect

10
go.sum
View File

@@ -11,6 +11,8 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
github.com/chromedp/cdproto v0.0.0-20210713064928-7d28b402946a/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= github.com/chromedp/cdproto v0.0.0-20210713064928-7d28b402946a/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4 h1:cD7F5LfNjC4dtb+BQe1KxxE8RsceYtS+Kyo+yEs4iUc= github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4 h1:cD7F5LfNjC4dtb+BQe1KxxE8RsceYtS+Kyo+yEs4iUc=
github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
github.com/chromedp/cdproto v0.0.0-20210910012206-68626162910d h1:77O+89zb1W9dPNUGjXOGt/J4LP70jPIPz9Rxs3aSX1w=
github.com/chromedp/cdproto v0.0.0-20210910012206-68626162910d/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
github.com/chromedp/chromedp v0.7.4 h1:U+0d3WbB/Oj4mDuBOI0P7S3PJEued5UZIl5AJ3QulwU= github.com/chromedp/chromedp v0.7.4 h1:U+0d3WbB/Oj4mDuBOI0P7S3PJEued5UZIl5AJ3QulwU=
github.com/chromedp/chromedp v0.7.4/go.mod h1:dBj+SXuQHznp6ZPwZeDDEBZKwclUwDLbZ0hjMialMYs= github.com/chromedp/chromedp v0.7.4/go.mod h1:dBj+SXuQHznp6ZPwZeDDEBZKwclUwDLbZ0hjMialMYs=
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
@@ -54,6 +56,8 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s= github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
@@ -77,6 +81,8 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE= github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc= github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
github.com/microcosm-cc/bluemonday v1.0.15 h1:J4uN+qPng9rvkBZBoBb8YGR+ijuklIMpSOZZLjYpbeY= github.com/microcosm-cc/bluemonday v1.0.15 h1:J4uN+qPng9rvkBZBoBb8YGR+ijuklIMpSOZZLjYpbeY=
@@ -124,11 +130,14 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
@@ -166,6 +175,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4= golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View File

@@ -89,7 +89,7 @@ const (
// Middleware is a middleware which can be added to the API's middlewares // Middleware is a middleware which can be added to the API's middlewares
// chain. // chain.
// //
// middleware := &Middleware{ // middleware := Middleware{
// Handler: func() echo.MiddlewareFunc { // Handler: func() echo.MiddlewareFunc {
// return func(next echo.HandlerFunc) echo.HandlerFunc { // return func(next echo.HandlerFunc) echo.HandlerFunc {
// return func(c echo.Context) error { // return func(c echo.Context) error {

View File

@@ -125,10 +125,9 @@ func newContext(echoCtx echo.Context, logger *zap.Logger, timeout time.Duration)
copyToDisk := func(fh *multipart.FileHeader) error { copyToDisk := func(fh *multipart.FileHeader) error {
// Avoid directory traversal and normalize filename. // Avoid directory traversal and normalize filename.
// See https://github.com/gotenberg/gotenberg/issues/104. // See https://github.com/gotenberg/gotenberg/issues/104.
// See https://github.com/gotenberg/gotenberg/issues/228.
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC) t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
filename, _, err := transform.String(t, strings.ToLower(filepath.Base(fh.Filename))) filename, _, err := transform.String(t, filepath.Base(fh.Filename))
if err != nil { if err != nil {
return fmt.Errorf("transform filename: %w", err) return fmt.Errorf("transform filename: %w", err)
} }

View File

@@ -396,7 +396,9 @@ func (form *FormData) mustAssign(key, value string, target interface{}) *FormDat
// path binds the absolute path of a form data file to a string variable. // path binds the absolute path of a form data file to a string variable.
func (form *FormData) path(filename string, target *string) *FormData { func (form *FormData) path(filename string, target *string) *FormData {
for name, path := range form.files { for name, path := range form.files {
if name == filename { // See https://github.com/gotenberg/gotenberg/issues/228.
nameLowerExt := strings.TrimSuffix(name, filepath.Ext(name)) + strings.ToLower(filepath.Ext(name))
if name == filename || nameLowerExt == filename {
*target = path *target = path
return form return form
} }

View File

@@ -850,6 +850,7 @@ func TestFormData_MandatoryPath(t *testing.T) {
func TestFormData_Content(t *testing.T) { func TestFormData_Content(t *testing.T) {
for i, tc := range []struct { for i, tc := range []struct {
form *FormData form *FormData
filename string
defaultValue string defaultValue string
expect string expect string
expectErr bool expectErr bool
@@ -863,6 +864,7 @@ func TestFormData_Content(t *testing.T) {
"bar": "/bar", "bar": "/bar",
}, },
}, },
filename: "foo",
}, },
{ {
form: &FormData{ form: &FormData{
@@ -870,6 +872,7 @@ func TestFormData_Content(t *testing.T) {
"bar": "/bar", "bar": "/bar",
}, },
}, },
filename: "foo",
defaultValue: "foo", defaultValue: "foo",
expect: "foo", expect: "foo",
}, },
@@ -879,6 +882,7 @@ func TestFormData_Content(t *testing.T) {
"foo": "/foo", "foo": "/foo",
}, },
}, },
filename: "foo",
expectErr: true, expectErr: true,
}, },
{ {
@@ -887,12 +891,31 @@ func TestFormData_Content(t *testing.T) {
"foo": "/tests/test/testdata/api/sample1.txt", "foo": "/tests/test/testdata/api/sample1.txt",
}, },
}, },
expect: "foo", filename: "foo",
expect: "foo",
},
{
form: &FormData{
files: map[string]string{
"foo.TXT": "/tests/test/testdata/api/sample1.txt",
},
},
filename: "foo.txt",
expect: "foo",
},
{
form: &FormData{
files: map[string]string{
"foo.txt": "/tests/test/testdata/api/sample1.txt",
},
},
filename: "foo.txt",
expect: "foo",
}, },
} { } {
var actual string var actual string
tc.form.Content("foo", &actual, tc.defaultValue) tc.form.Content(tc.filename, &actual, tc.defaultValue)
if actual != tc.expect { if actual != tc.expect {
t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expect, actual) t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expect, actual)
@@ -911,11 +934,13 @@ func TestFormData_Content(t *testing.T) {
func TestFormData_MandatoryContent(t *testing.T) { func TestFormData_MandatoryContent(t *testing.T) {
for i, tc := range []struct { for i, tc := range []struct {
form *FormData form *FormData
filename string
expect string expect string
expectErr bool expectErr bool
}{ }{
{ {
form: &FormData{}, form: &FormData{},
filename: "foo",
expectErr: true, expectErr: true,
}, },
{ {
@@ -924,6 +949,7 @@ func TestFormData_MandatoryContent(t *testing.T) {
"bar": "/bar", "bar": "/bar",
}, },
}, },
filename: "foo",
expectErr: true, expectErr: true,
}, },
{ {
@@ -932,6 +958,7 @@ func TestFormData_MandatoryContent(t *testing.T) {
"foo": "/foo", "foo": "/foo",
}, },
}, },
filename: "foo",
expectErr: true, expectErr: true,
}, },
{ {
@@ -940,12 +967,31 @@ func TestFormData_MandatoryContent(t *testing.T) {
"foo": "/tests/test/testdata/api/sample1.txt", "foo": "/tests/test/testdata/api/sample1.txt",
}, },
}, },
expect: "foo", filename: "foo",
expect: "foo",
},
{
form: &FormData{
files: map[string]string{
"foo.TXT": "/tests/test/testdata/api/sample1.txt",
},
},
filename: "foo.txt",
expect: "foo",
},
{
form: &FormData{
files: map[string]string{
"foo.txt": "/tests/test/testdata/api/sample1.txt",
},
},
filename: "foo.txt",
expect: "foo",
}, },
} { } {
var actual string var actual string
tc.form.MandatoryContent("foo", &actual) tc.form.MandatoryContent(tc.filename, &actual)
if actual != tc.expect { if actual != tc.expect {
t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expect, actual) t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expect, actual)
@@ -995,6 +1041,21 @@ func TestFormData_Paths(t *testing.T) {
}, },
expectCount: 2, expectCount: 2,
}, },
{
form: &FormData{
files: map[string]string{
"foo.zip": "/foo.zip",
"b.PDF": "/b.PDF",
"a.pdf": "/a.pdf",
},
},
extensions: []string{".pdf"},
expect: []string{
"/a.pdf",
"/b.PDF",
},
expectCount: 2,
},
} { } {
var actual []string var actual []string
@@ -1051,6 +1112,21 @@ func TestFormData_MandatoryPaths(t *testing.T) {
}, },
expectCount: 2, expectCount: 2,
}, },
{
form: &FormData{
files: map[string]string{
"foo.zip": "/foo.zip",
"b.PDF": "/b.PDF",
"a.pdf": "/a.pdf",
},
},
extensions: []string{".pdf"},
expect: []string{
"/a.pdf",
"/b.PDF",
},
expectCount: 2,
},
} { } {
var actual []string var actual []string

View File

@@ -111,7 +111,7 @@ func TestHttpErrorHandler(t *testing.T) {
func() { func() {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
webhookPort := rand.Intn(65535-1+1) + 1 webhookPort := rand.Intn(65535-1025+1) + 1025
tc.webhookClient.errorURL = fmt.Sprintf(tc.webhookClient.errorURL, webhookPort) tc.webhookClient.errorURL = fmt.Sprintf(tc.webhookClient.errorURL, webhookPort)
@@ -825,7 +825,7 @@ func TestContextMiddlewareWithWebhook(t *testing.T) {
webhook.HidePort = true webhook.HidePort = true
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
webhookPort := rand.Intn(65535-1+1) + 1 webhookPort := rand.Intn(65535-1025+1) + 1025
if tc.autoWebhookURLs { if tc.autoWebhookURLs {
c.Request().Header.Set("Gotenberg-Webhook-Url", fmt.Sprintf("http://localhost:%d/", webhookPort)) c.Request().Header.Set("Gotenberg-Webhook-Url", fmt.Sprintf("http://localhost:%d/", webhookPort))

View File

@@ -312,6 +312,9 @@ func TestChromium_PDF(t *testing.T) {
}(), }(),
}, },
}, },
{
URL: "file:///tests/test/testdata/chromium/html/sample5/index.html",
},
} { } {
func() { func() {
mod := new(Chromium) mod := new(Chromium)

View File

@@ -229,6 +229,7 @@ func (mod Unoconv) Extensions() []string {
".fodg", ".fodg",
".gif", ".gif",
".jpg", ".jpg",
".jpeg",
".met", ".met",
".odd", ".odd",
".otg", ".otg",
@@ -243,9 +244,11 @@ func (mod Unoconv) Extensions() []string {
".swf", ".swf",
".sxd", ".sxd",
".sxw", ".sxw",
".tif",
".tiff", ".tiff",
".xhtml", ".xhtml",
".xpm", ".xpm",
".odp",
".fodp", ".fodp",
".potm", ".potm",
".pot", ".pot",

View File

@@ -146,7 +146,7 @@ func TestUnoconv_Extensions(t *testing.T) {
extensions := mod.Extensions() extensions := mod.Extensions()
actual := len(extensions) actual := len(extensions)
expect := 73 expect := 76
if actual != expect { if actual != expect {
t.Errorf("expected %d extensions but got %d", expect, actual) t.Errorf("expected %d extensions but got %d", expect, actual)

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gutenberg</title>
</head>
<body>
<div class="page-break-after">
<div class="center">
<h1>Gutenberg</h1>
<img src="MyImg.gif">
</div>
</div>
</body>
</html>