Compare commits

...

22 Commits

Author SHA1 Message Date
Julien Neuhart
5fb35c2d48 fix: chromium exact colors (#361) 2021-09-21 18:51:52 +02:00
Julien Neuhart
dfe89f0d83 fix: add gotenberg flag for chromium flag --allow-file-access-from-files (#360) 2021-09-21 18:39:13 +02:00
Julien Neuhart
c500ec071e feat: support armhf & i386 architectures (#355) 2021-09-21 18:38:11 +02:00
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
Julien Neuhart
40cc019a51 fix: typo Docker Registry -> Docker Repository 2021-08-27 19:14:17 +02:00
Julien Neuhart
781094ab05 fix: typo arch64 -> amd64 2021-08-27 18:50:06 +02:00
Julien Neuhart
21cfe2e535 Merge branch 'main' of github.com:gotenberg/gotenberg 2021-08-27 18:48:08 +02:00
Julien Neuhart
4f72684080 chore: upgrade LibreOffice to version 7.2 (#335) 2021-08-27 18:47:48 +02:00
Julien Neuhart
5ac514366e Merge branch 'main' of github.com:gotenberg/gotenberg 2021-08-27 14:49:56 +02:00
Julien Neuhart
d5d6285eef fix: use google chrome stable on amd64 (#333) 2021-08-27 14:48:09 +02:00
Julien Neuhart
0e34b41bce Merge branch 'main' of github.com:gotenberg/gotenberg 2021-08-27 13:48:22 +02:00
Julien Neuhart
e157066bcc chore: upgrade Go version to 1.17 (#334) 2021-08-27 13:46:44 +02:00
Julien Neuhart
f43a63ac6e chore: upgrade Go version to 1.17 2021-08-27 12:54:07 +02:00
Julien Neuhart
a5828fa01a fix: add --disable-gpu flag to Chromium / chore: upgrade base image to bullseye (#331) 2021-08-27 09:41:59 +02:00
Julien Neuhart
662d3ff795 chore: use echo.WrapHandler for health route 2021-08-25 17:12:54 +02:00
Julien Neuhart
a97f05db3b chore: add markdown table sample & test 2021-08-24 19:24:16 +02:00
32 changed files with 33215 additions and 97 deletions

View File

@@ -24,4 +24,4 @@ jobs:
- name: Build and push Docker image - name: Build and push Docker image
run: | run: |
make release GOTENBERG_VERSION=${{ github.event.release.tag_name }} make release GOTENBERG_VERSION=${{ github.event.release.tag_name }}
make release GOTENBERG_VERSION=${{ github.event.release.tag_name }} DOCKER_REGISTRY=thecodingmachine make release GOTENBERG_VERSION=${{ github.event.release.tag_name }} DOCKER_REPOSITORY=thecodingmachine

View File

@@ -19,7 +19,7 @@ jobs:
- name: Run linters - name: Run linters
uses: golangci/golangci-lint-action@v2 uses: golangci/golangci-lint-action@v2
with: with:
version: v1.39 version: v1.42
tests: tests:
needs: needs:

View File

@@ -5,13 +5,14 @@ help: ## Show the help
.PHONY: it .PHONY: it
it: build build-tests ## Initialize the development environment it: build build-tests ## Initialize the development environment
GOLANG_VERSION=1.16 GOLANG_VERSION=1.17
DOCKER_REGISTRY=gotenberg 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.39.0 # See https://github.com/golangci/golangci-lint/releases. GOLANGCI_LINT_VERSION=v1.42.0 # See https://github.com/golangci/golangci-lint/releases.
.PHONY: build .PHONY: build
build: ## Build the Gotenberg's Docker image build: ## Build the Gotenberg's Docker image
@@ -20,8 +21,9 @@ 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_REGISTRY)/gotenberg:$(GOTENBERG_VERSION) \ -t $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION) \
-f build/Dockerfile . -f build/Dockerfile .
GOTENBERG_GRACEFUL_SHUTDOWN_DURATION=30s GOTENBERG_GRACEFUL_SHUTDOWN_DURATION=30s
@@ -44,6 +46,7 @@ API_DISABLE_WEBHOOK=false
CHROMIUM_USER_AGENT= CHROMIUM_USER_AGENT=
CHROMIUM_INCOGNITO=false CHROMIUM_INCOGNITO=false
CHROMIUM_IGNORE_CERTIFICATE_ERRORS=false CHROMIUM_IGNORE_CERTIFICATE_ERRORS=false
CHROMIUM_ALLOW_FILE_ACCESS_FROM_FILES=false
CHROMIUM_ALLOW_LIST= CHROMIUM_ALLOW_LIST=
CHROMIUM_DENY_LIST="^file:///[^tmp].*" CHROMIUM_DENY_LIST="^file:///[^tmp].*"
CHROMIUM_DISABLE_ROUTES=false CHROMIUM_DISABLE_ROUTES=false
@@ -57,7 +60,7 @@ PDFENGINES_DISABLE_ROUTES=false
run: ## Start a Gotenberg container run: ## Start a Gotenberg container
docker run --rm -it \ docker run --rm -it \
-p $(API_PORT):$(API_PORT) \ -p $(API_PORT):$(API_PORT) \
$(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION) \ $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION) \
gotenberg \ gotenberg \
--gotenberg-graceful-shutdown-duration=$(GOTENBERG_GRACEFUL_SHUTDOWN_DURATION) \ --gotenberg-graceful-shutdown-duration=$(GOTENBERG_GRACEFUL_SHUTDOWN_DURATION) \
--api-port=$(API_PORT) \ --api-port=$(API_PORT) \
@@ -79,6 +82,7 @@ run: ## Start a Gotenberg container
--chromium-user-agent=$(CHROMIUM_USER_AGENT) \ --chromium-user-agent=$(CHROMIUM_USER_AGENT) \
--chromium-incognito=$(CHROMIUM_INCOGNITO) \ --chromium-incognito=$(CHROMIUM_INCOGNITO) \
--chromium-ignore-certificate-errors=$(CHROMIUM_IGNORE_CERTIFICATE_ERRORS) \ --chromium-ignore-certificate-errors=$(CHROMIUM_IGNORE_CERTIFICATE_ERRORS) \
--chromium-allow-file-access-from-files=$(CHROMIUM_ALLOW_FILE_ACCESS_FROM_FILES) \
--chromium-allow-list=$(CHROMIUM_ALLOW_LIST) \ --chromium-allow-list=$(CHROMIUM_ALLOW_LIST) \
--chromium-deny-list=$(CHROMIUM_DENY_LIST) \ --chromium-deny-list=$(CHROMIUM_DENY_LIST) \
--chromium-disable-routes=$(CHROMIUM_DISABLE_ROUTES) \ --chromium-disable-routes=$(CHROMIUM_DISABLE_ROUTES) \
@@ -92,24 +96,24 @@ run: ## Start a Gotenberg container
build-tests: ## Build the tests' Docker image build-tests: ## Build the tests' Docker image
docker build \ docker build \
--build-arg GOLANG_VERSION=$(GOLANG_VERSION) \ --build-arg GOLANG_VERSION=$(GOLANG_VERSION) \
--build-arg DOCKER_REGISTRY=$(DOCKER_REGISTRY) \ --build-arg DOCKER_REPOSITORY=$(DOCKER_REPOSITORY) \
--build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \ --build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \
--build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) \ --build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) \
-t $(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION)-tests \ -t $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION)-tests \
-f test/Dockerfile . -f test/Dockerfile .
.PHONY: tests .PHONY: tests
tests: ## Start the testing environment tests: ## Start the testing environment
docker run --rm -it \ docker run --rm -it \
-v $(PWD):/tests \ -v $(PWD):/tests \
$(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION)-tests \ $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION)-tests \
bash bash
.PHONY: tests-once .PHONY: tests-once
tests-once: ## Run the tests once (prefer the "tests" command while developing) tests-once: ## Run the tests once (prefer the "tests" command while developing)
docker run --rm \ docker run --rm \
-v $(PWD):/tests \ -v $(PWD):/tests \
$(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION)-tests \ $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION)-tests \
gotest gotest
.PHONY: fmt .PHONY: fmt
@@ -123,11 +127,11 @@ godoc: ## Run a webserver with Gotenberg godoc (go get golang.org/x/tools/cmd/go
godoc -http=:6060 godoc -http=:6060
.PHONY: release .PHONY: release
release: ## Build the Gotenberg's Docker image for linux/amd64 and linux/arm64 platforms, then push it to a Docker Registry release: ## Build the Gotenberg's Docker image for many platforms, then push it to a Docker repository
./scripts/release.sh \ ./scripts/release.sh \
$(GOLANG_VERSION) \ $(GOLANG_VERSION) \
$(GOTENBERG_VERSION) \ $(GOTENBERG_VERSION) \
$(GOTENBERG_USER_GID) \ $(GOTENBERG_USER_GID) \
$(GOTENBERG_USER_UID) \ $(GOTENBERG_USER_UID) \
$(PDFTK_VERSION) \ $(PDFTK_VERSION) \
$(DOCKER_REGISTRY) $(DOCKER_REPOSITORY)

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>
--- ---
@@ -18,7 +18,7 @@ Open a terminal and run the following command:
docker run --rm -p 3000:3000 gotenberg/gotenberg:7 docker run --rm -p 3000:3000 gotenberg/gotenberg:7
``` ```
Alternatively, using the historic Docker registry from our sponsor [TheCodingMachine](https://www.thecodingmachine.com): Alternatively, using the historic Docker repository from our sponsor [TheCodingMachine](https://www.thecodingmachine.com):
``` ```
docker run --rm -p 3000:3000 thecodingmachine/gotenberg:7 docker run --rm -p 3000:3000 thecodingmachine/gotenberg:7

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:buster-slim FROM debian:11-slim
ARG GOTENBERG_VERSION ARG GOTENBERG_VERSION
@@ -48,8 +48,14 @@ 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
# Chromium on other architectures.
# See https://github.com/gotenberg/gotenberg/issues/328.
COPY build/install-chromium.sh /tmp/install-chromium.sh
RUN \ RUN \
# Create a non-root user. # Create a non-root user.
# All processes in the Docker container will run with this dedicated user. # All processes in the Docker container will run with this dedicated user.
@@ -61,7 +67,7 @@ RUN \
# Note: procps for "top" command (useful when debugging processes). # Note: procps for "top" command (useful when debugging processes).
# Note: tini is a helper for reaping zombie processes. # Note: tini is a helper for reaping zombie processes.
apt-get update -qq &&\ apt-get update -qq &&\
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends curl gnupg procps tini &&\ DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends curl gnupg procps tini python3 default-jre-headless &&\
# Install fonts. # Install fonts.
# Credits: # Credits:
# https://github.com/arachnys/athenapdf/blob/master/cli/Dockerfile. # https://github.com/arachnys/athenapdf/blob/master/cli/Dockerfile.
@@ -84,6 +90,7 @@ RUN \
fonts-telu \ fonts-telu \
fonts-thai-tlwg \ fonts-thai-tlwg \
ttf-wqy-zenhei \ ttf-wqy-zenhei \
fonts-arphic-ukai \
fonts-arphic-uming \ fonts-arphic-uming \
fonts-ipafont-mincho \ fonts-ipafont-mincho \
fonts-ipafont-gothic \ fonts-ipafont-gothic \
@@ -102,23 +109,30 @@ 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 &&\
echo "deb https://httpredir.debian.org/debian/ buster-backports main contrib non-free" >> /etc/apt/sources.list &&\ # 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.
/tmp/install-chromium.sh &&\
# Install LibreOffice.
# Note: we use the sid distribution to get the latest LibreOffice version.
# See https://github.com/gotenberg/gotenberg/pull/322.
echo "deb https://httpredir.debian.org/debian/ sid main contrib non-free" >> /etc/apt/sources.list &&\
apt-get update -qq &&\ apt-get update -qq &&\
# Install Chromium and LibreOffice. DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends -t sid libreoffice &&\
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends chromium &&\
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends -t buster-backports libreoffice &&\
# Download unoconv (Python script). # Download unoconv (Python script).
curl -Ls https://raw.githubusercontent.com/dagwieers/unoconv/master/unoconv -o /usr/bin/unoconv &&\ curl -Ls https://raw.githubusercontent.com/dagwieers/unoconv/master/unoconv -o /usr/bin/unoconv &&\
chmod +x /usr/bin/unoconv &&\ chmod +x /usr/bin/unoconv &&\
# unoconv will look for the Python binary, which has to be at version 3. # unoconv will look for the Python binary, which has to be at version 3.
ln -s /usr/bin/python3 /usr/bin/python &&\ ln -s /usr/bin/python3 /usr/bin/python &&\
# Download PDFtk. # Download PDFtk.
# Credits: https://github.com/thecodingmachine/gotenberg/pull/273. # See https://github.com/gotenberg/gotenberg/pull/273.
curl -o /usr/bin/pdftk-all.jar "https://gitlab.com/pdftk-java/pdftk/-/jobs/$PDFTK_VERSION/artifacts/raw/build/libs/pdftk-all.jar" &&\ curl -o /usr/bin/pdftk-all.jar "https://gitlab.com/pdftk-java/pdftk/-/jobs/$PDFTK_VERSION/artifacts/raw/build/libs/pdftk-all.jar" &&\
chmod a+x /usr/bin/pdftk-all.jar &&\ chmod a+x /usr/bin/pdftk-all.jar &&\
# See https://github.com/nextcloud/docker/issues/380. # See https://github.com/nextcloud/docker/issues/380.
mkdir -p /usr/share/man/man1mkdir -p /usr/share/man/man1 &&\ mkdir -p /usr/share/man/man1mkdir -p /usr/share/man/man1 &&\
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends default-jre-headless &&\
# Cleanup. # Cleanup.
# Note: the Debian image does automatically a clean after each install thanks to a hook. # Note: the Debian image does automatically a clean after each install thanks to a hook.
# Therefore, there is no need for apt-get clean. # Therefore, there is no need for apt-get clean.

View File

@@ -1,9 +1,9 @@
# Note: ARG instructions do not create additional layers. # Note: ARG instructions do not create additional layers.
# Instead, next layers will concatenate them. # Instead, next layers will concatenate them.
ARG DOCKER_REGISTRY ARG DOCKER_REPOSITORY
ARG GOTENBERG_VERSION ARG GOTENBERG_VERSION
FROM $DOCKER_REGISTRY/gotenberg:$GOTENBERG_VERSION FROM $DOCKER_REPOSITORY/gotenberg:$GOTENBERG_VERSION
USER root USER root

15
build/install-chromium.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
set -e
ARCH=$(dpkg --print-architecture)
if [[ "$ARCH" == "amd64" ]]; then
curl https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends --allow-unauthenticated google-chrome-stable
mv /usr/bin/google-chrome-stable /usr/bin/chromium
else
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends chromium
fi

31
go.mod
View File

@@ -1,21 +1,21 @@
module github.com/gotenberg/gotenberg/v7 module github.com/gotenberg/gotenberg/v7
go 1.16 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-20210808225517-c36c1bd4c35e 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
@@ -34,5 +34,24 @@ require (
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 // indirect golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 // indirect
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
golang.org/x/text v0.3.7 golang.org/x/text v0.3.7
golang.org/x/tools v0.1.5 // indirect )
require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/dsnet/compress v0.0.1 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.1.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650 // indirect
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
) )

25
go.sum
View File

@@ -9,8 +9,8 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
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-20210808225517-c36c1bd4c35e h1:uYQIvPKwL7YQh+tQC+EUXmvWosBeOYbJZKrh4NnS0UM= github.com/chromedp/cdproto v0.0.0-20210910012206-68626162910d h1:77O+89zb1W9dPNUGjXOGt/J4LP70jPIPz9Rxs3aSX1w=
github.com/chromedp/cdproto v0.0.0-20210808225517-c36c1bd4c35e/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= 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=
@@ -29,7 +29,6 @@ github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
@@ -52,8 +51,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
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.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= 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=
@@ -75,8 +74,8 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
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.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 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=
@@ -122,13 +121,13 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= 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.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
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.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= 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=
@@ -138,7 +137,6 @@ golang.org/x/image v0.0.0-20190823064033-3a9bac650e44/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -166,6 +164,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=
@@ -179,9 +178,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

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 {
@@ -382,11 +382,7 @@ func (a *API) Start() error {
checks := append(a.healthChecks, health.WithTimeout(a.processTimeout)) checks := append(a.healthChecks, health.WithTimeout(a.processTimeout))
checker := health.NewChecker(checks...) checker := health.NewChecker(checks...)
return func(echoCtx echo.Context) error { return echo.WrapHandler(health.NewHandler(checker))
health.NewHandler(checker).ServeHTTP(echoCtx.Response().Writer, echoCtx.Request())
return nil
}
}(), }(),
timeoutMiddleware(hardTimeout), timeoutMiddleware(hardTimeout),
) )

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

@@ -45,14 +45,15 @@ var (
// Chromium is a module which provides both an API and routes for converting // Chromium is a module which provides both an API and routes for converting
// HTML document to PDF. // HTML document to PDF.
type Chromium struct { type Chromium struct {
binPath string binPath string
engine gotenberg.PDFEngine engine gotenberg.PDFEngine
userAgent string userAgent string
incognito bool incognito bool
ignoreCertificateErrors bool ignoreCertificateErrors bool
allowList *regexp.Regexp allowFileAccessFromFiles bool
denyList *regexp.Regexp allowList *regexp.Regexp
disableRoutes bool denyList *regexp.Regexp
disableRoutes bool
} }
// Options are the available options for converting HTML document to PDF. // Options are the available options for converting HTML document to PDF.
@@ -183,6 +184,7 @@ func (mod Chromium) Descriptor() gotenberg.ModuleDescriptor {
fs.String("chromium-user-agent", "", "Override the default User-Agent header") fs.String("chromium-user-agent", "", "Override the default User-Agent header")
fs.Bool("chromium-incognito", false, "Start Chromium with incognito mode") fs.Bool("chromium-incognito", false, "Start Chromium with incognito mode")
fs.Bool("chromium-ignore-certificate-errors", false, "Ignore the certificate errors") fs.Bool("chromium-ignore-certificate-errors", false, "Ignore the certificate errors")
fs.Bool("chromium-allow-file-access-from-files", false, "Allow file:// URIs to read other file:// URIs")
fs.String("chromium-allow-list", "", "Set the allowed URLs for Chromium using a regular expression") fs.String("chromium-allow-list", "", "Set the allowed URLs for Chromium using a regular expression")
fs.String("chromium-deny-list", "^file:///[^tmp].*", "Set the denied URLs for Chromium using a regular expression") fs.String("chromium-deny-list", "^file:///[^tmp].*", "Set the denied URLs for Chromium using a regular expression")
fs.Bool("chromium-disable-routes", false, "Disable the routes") fs.Bool("chromium-disable-routes", false, "Disable the routes")
@@ -197,6 +199,7 @@ func (mod Chromium) Descriptor() gotenberg.ModuleDescriptor {
func (mod *Chromium) Provision(ctx *gotenberg.Context) error { func (mod *Chromium) Provision(ctx *gotenberg.Context) error {
flags := ctx.ParsedFlags() flags := ctx.ParsedFlags()
mod.ignoreCertificateErrors = flags.MustBool("chromium-ignore-certificate-errors") mod.ignoreCertificateErrors = flags.MustBool("chromium-ignore-certificate-errors")
mod.allowFileAccessFromFiles = flags.MustBool("chromium-allow-file-access-from-files")
mod.allowList = flags.MustRegexp("chromium-allow-list") mod.allowList = flags.MustRegexp("chromium-allow-list")
mod.denyList = flags.MustRegexp("chromium-deny-list") mod.denyList = flags.MustRegexp("chromium-deny-list")
mod.disableRoutes = flags.MustBool("chromium-disable-routes") mod.disableRoutes = flags.MustBool("chromium-disable-routes")
@@ -257,12 +260,18 @@ func (mod Chromium) Routes() ([]api.MultipartFormDataRoute, error) {
// drastically. In such a scenario, the given context may also be done before // drastically. In such a scenario, the given context may also be done before
// the end of the conversion. // the end of the conversion.
func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath string, options Options) error { func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath string, options Options) error {
debug := debugLogger{logger: logger.Named("chromium.debug")}
userProfileDirPath := gotenberg.NewDirPath() userProfileDirPath := gotenberg.NewDirPath()
args := append(chromedp.DefaultExecAllocatorOptions[:], args := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.CombinedOutput(debug),
chromedp.ExecPath(mod.binPath), chromedp.ExecPath(mod.binPath),
chromedp.NoSandbox, chromedp.NoSandbox,
// See: // See:
// https://github.com/gotenberg/gotenberg/issues/327
// https://github.com/chromedp/chromedp/issues/904
chromedp.DisableGPU,
// See:
// https://github.com/puppeteer/puppeteer/issues/661 // https://github.com/puppeteer/puppeteer/issues/661
// https://github.com/puppeteer/puppeteer/issues/2410 // https://github.com/puppeteer/puppeteer/issues/2410
chromedp.Flag("font-render-hinting", "none"), chromedp.Flag("font-render-hinting", "none"),
@@ -281,10 +290,17 @@ func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath
args = append(args, chromedp.IgnoreCertErrors) args = append(args, chromedp.IgnoreCertErrors)
} }
if mod.allowFileAccessFromFiles {
// See https://github.com/gotenberg/gotenberg/issues/356.
args = append(args, chromedp.Flag("allow-file-access-from-files", true))
}
allocatorCtx, cancel := chromedp.NewExecAllocator(ctx, args...) allocatorCtx, cancel := chromedp.NewExecAllocator(ctx, args...)
defer cancel() defer cancel()
taskCtx, cancel := chromedp.NewContext(allocatorCtx) taskCtx, cancel := chromedp.NewContext(allocatorCtx,
chromedp.WithDebugf(debug.Printf),
)
defer cancel() defer cancel()
// We validate the "main" URL against our allow / deny lists. // We validate the "main" URL against our allow / deny lists.
@@ -347,6 +363,31 @@ func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath
return fmt.Errorf("wait for events: %w", err) return fmt.Errorf("wait for events: %w", err)
}), }),
chromedp.ActionFunc(func(ctx context.Context) error {
// See:
// https://github.com/gotenberg/gotenberg/issues/354
// https://github.com/puppeteer/puppeteer/issues/2685
// https://github.com/chromedp/chromedp/issues/520
script := `
(() => {
const css = 'html { -webkit-print-color-adjust: exact !important; }';
const style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);
})();
`
evaluate := chromedp.Evaluate(script, nil)
err := evaluate.Do(ctx)
if err == nil {
return nil
}
return fmt.Errorf("add CSS for exact colors: %w", err)
}),
chromedp.ActionFunc(func(ctx context.Context) error { chromedp.ActionFunc(func(ctx context.Context) error {
if options.WaitDelay > 0 { if options.WaitDelay > 0 {
// We wait for a given amount of time so that JavaScript // We wait for a given amount of time so that JavaScript

View File

@@ -210,16 +210,17 @@ func TestChromium_Routes(t *testing.T) {
func TestChromium_PDF(t *testing.T) { func TestChromium_PDF(t *testing.T) {
for i, tc := range []struct { for i, tc := range []struct {
timeout time.Duration timeout time.Duration
cancel context.CancelFunc cancel context.CancelFunc
URL string URL string
options Options options Options
userAgent string userAgent string
incognito bool incognito bool
ignoreCertificateErrors bool ignoreCertificateErrors bool
allowList *regexp.Regexp allowFileAccessFromFiles bool
denyList *regexp.Regexp allowList *regexp.Regexp
expectErr bool denyList *regexp.Regexp
expectErr bool
}{ }{
{ {
URL: "file:///tests/test/testdata/chromium/html/sample4/index.html", URL: "file:///tests/test/testdata/chromium/html/sample4/index.html",
@@ -275,10 +276,11 @@ func TestChromium_PDF(t *testing.T) {
expectErr: true, expectErr: true,
}, },
{ {
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,
ignoreCertificateErrors: true, ignoreCertificateErrors: true,
allowFileAccessFromFiles: true,
}, },
{ {
URL: "file:///tests/test/testdata/chromium/html/sample1/index.html", URL: "file:///tests/test/testdata/chromium/html/sample1/index.html",
@@ -312,6 +314,16 @@ func TestChromium_PDF(t *testing.T) {
}(), }(),
}, },
}, },
{
URL: "file:///tests/test/testdata/chromium/html/sample5/index.html",
},
{
URL: "file:///tests/test/testdata/chromium/html/sample6/index.html",
allowFileAccessFromFiles: true,
},
{
URL: "file:///tests/test/testdata/chromium/html/sample7/index.html",
},
} { } {
func() { func() {
mod := new(Chromium) mod := new(Chromium)
@@ -319,6 +331,7 @@ func TestChromium_PDF(t *testing.T) {
mod.userAgent = tc.userAgent mod.userAgent = tc.userAgent
mod.incognito = tc.incognito mod.incognito = tc.incognito
mod.ignoreCertificateErrors = tc.ignoreCertificateErrors mod.ignoreCertificateErrors = tc.ignoreCertificateErrors
mod.allowFileAccessFromFiles = tc.allowFileAccessFromFiles
if tc.allowList == nil { if tc.allowList == nil {
tc.allowList = regexp.MustCompile("") tc.allowList = regexp.MustCompile("")

View File

@@ -0,0 +1,31 @@
package chromium
import (
"fmt"
"io"
"go.uber.org/zap"
)
// debugLogger is wrapper around a zap.Logger which is used for debugging
// Chromium.
type debugLogger struct {
logger *zap.Logger
}
// Write logs the bytes in a debug message.
func (debug debugLogger) Write(p []byte) (n int, err error) {
debug.logger.Debug(string(p))
return len(p), nil
}
// Printf logs a debug message.
func (debug debugLogger) Printf(format string, v ...interface{}) {
debug.logger.Debug(fmt.Sprintf(format, v...))
}
// Interface guards.
var (
_ io.Writer = (*debugLogger)(nil)
)

View File

@@ -0,0 +1,24 @@
package chromium
import (
"testing"
"go.uber.org/zap"
)
func TestDebugLogger_Write(t *testing.T) {
actual, err := debugLogger{logger: zap.NewNop()}.Write([]byte("foo"))
expected := len([]byte("foo"))
if actual != expected {
t.Errorf("expected %d but got %d", expected, actual)
}
if err != nil {
t.Errorf("expected not error but got: %v", err)
}
}
func TestDebugLogger_Printf(t *testing.T) {
debugLogger{logger: zap.NewNop()}.Printf("%s", "foo")
}

View File

@@ -432,6 +432,29 @@ func TestConvertMarkdownHandler(t *testing.T) {
outputDir: "/tmp/foo", outputDir: "/tmp/foo",
expectOutputPathsCount: 1, expectOutputPathsCount: 1,
}, },
{
ctx: func() *api.MockContext {
ctx := &api.MockContext{Context: &api.Context{}}
ctx.SetDirPath("/tmp/foo")
ctx.SetFiles(map[string]string{
"index.html": "/tests/test/testdata/chromium/markdown/sample3/index.html",
"markdown1.md": "/tests/test/testdata/chromium/markdown/sample3/markdown.md",
})
return ctx
}(),
api: func() API {
chromiumAPI := struct{ ProtoAPI }{}
chromiumAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ Options) error {
return nil
}
return chromiumAPI
}(),
outputDir: "/tmp/foo",
expectOutputPathsCount: 1,
},
} { } {
func() { func() {
if tc.outputDir != "" { if tc.outputDir != "" {

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)

View File

@@ -7,7 +7,7 @@ GOTENBERG_VERSION="$2"
GOTENBERG_USER_GID="$3" GOTENBERG_USER_GID="$3"
GOTENBERG_USER_UID="$4" GOTENBERG_USER_UID="$4"
PDFTK_VERSION="$5" PDFTK_VERSION="$5"
DOCKER_REGISTRY="$6" DOCKER_REPOSITORY="$6"
GOTENBERG_VERSION="${GOTENBERG_VERSION//v}" GOTENBERG_VERSION="${GOTENBERG_VERSION//v}"
SEMVER=( ${GOTENBERG_VERSION//./ } ) SEMVER=( ${GOTENBERG_VERSION//./ } )
@@ -26,22 +26,26 @@ docker buildx build \
--build-arg PDFTK_VERSION="$PDFTK_VERSION" \ --build-arg PDFTK_VERSION="$PDFTK_VERSION" \
--platform linux/amd64 \ --platform linux/amd64 \
--platform linux/arm64 \ --platform linux/arm64 \
-t "$DOCKER_REGISTRY/gotenberg:latest" \ --platform linux/arm/v7 \
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}" \ --platform linux/386 \
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}" \ -t "$DOCKER_REPOSITORY/gotenberg:latest" \
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}" \ -t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}" \
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}" \
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}" \
--push \ --push \
-f build/Dockerfile . -f build/Dockerfile .
# Cloud Run variant. # Cloud Run variant.
docker buildx build \ docker buildx build \
--build-arg DOCKER_REGISTRY="$DOCKER_REGISTRY" \ --build-arg DOCKER_REPOSITORY="$DOCKER_REPOSITORY" \
--build-arg GOTENBERG_VERSION="$GOTENBERG_VERSION" \ --build-arg GOTENBERG_VERSION="$GOTENBERG_VERSION" \
--platform linux/amd64 \ --platform linux/amd64 \
--platform linux/arm64 \ --platform linux/arm64 \
-t "$DOCKER_REGISTRY/gotenberg:latest-cloudrun" \ --platform linux/arm/v7 \
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}-cloudrun" \ --platform linux/386 \
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}-cloudrun" \ -t "$DOCKER_REPOSITORY/gotenberg:latest-cloudrun" \
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}-cloudrun" \ -t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}-cloudrun" \
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}-cloudrun" \
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}-cloudrun" \
--push \ --push \
-f build/Dockerfile.cloudrun . -f build/Dockerfile.cloudrun .

View File

@@ -1,5 +1,5 @@
ARG GOLANG_VERSION ARG GOLANG_VERSION
ARG DOCKER_REGISTRY ARG DOCKER_REPOSITORY
ARG GOTENBERG_VERSION ARG GOTENBERG_VERSION
ARG GOLANGCI_LINT_VERSION ARG GOLANGCI_LINT_VERSION
@@ -7,7 +7,7 @@ FROM golang:$GOLANG_VERSION-stretch as golang
# We're extending the Gotenberg's Docker image because our code relies on external # We're extending the Gotenberg's Docker image because our code relies on external
# dependencies like Google Chrome, LibreOffice, etc. # dependencies like Google Chrome, LibreOffice, etc.
FROM $DOCKER_REGISTRY/gotenberg:$GOTENBERG_VERSION FROM $DOCKER_REPOSITORY/gotenberg:$GOTENBERG_VERSION
USER root USER root

View File

@@ -32,7 +32,7 @@
<div class="center"> <div class="center">
<h1>This image is loaded from a URL</h1> <h1>This image is loaded from a URL</h1>
<img src="https://gutendev.com/wp-content/uploads/2018/10/01_03-1.jpg"> <img src="https://user-images.githubusercontent.com/8983173/130322857-185831e2-f041-46eb-a17f-0a69d066c4e5.png">
</div> </div>
</body> </body>
</html> </html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gutenberg</title>
</head>
<body>
<h1>Gutenberg</h1>
<img src="MyImg.gif">
</body>
</html>

View File

@@ -0,0 +1,20 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Gutenberg</title>
</head>
<body>
<div class="center">
<h1>Gutenberg</h1>
</div>
<blockquote cite="https://sites.google.com/site/johanngutenbergper5/q">
<p>It is a press, certainly, but a press from which shall flow in inexhaustible streams...Through it, God will spread His Word. A spring of truth shall flow from it: like a new star it shall scatter the darkness of ignorance, and cause a light heretofore unknown to shine amongst men.</p>
<footer><a href="https://sites.google.com/site/johanngutenbergper5/q">Johannes Gutenberg</a></cite></footer>
</blockquote>
<script src="paged.polyfill.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
body {
font-family: Arial, Helvetica, sans-serif;
}
.center {
text-align: center;
}

View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gutenberg</title>
</head>
<body>
<h1>Gutenberg</h1>
<p style="color: #d1d0d0;">
It is a press, certainly, but a press from which shall flow in inexhaustible streams...Through it, God will spread His Word. A spring of truth shall flow from it: like a new star it shall scatter the darkness of ignorance, and cause a light heretofore unknown to shine amongst men.
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gutenberg</title>
</head>
<body>
<h1>Table in markdown</h1>
<h2>toHTML</h2>
{{ toHTML "markdown.md" }}
<h2>Actual HTML</h2>
<textarea readonly="readonly" cols="100" rows="50">
{{ toHTML "markdown.md" }}
</textarea>
</body>
</html>

View File

@@ -0,0 +1,5 @@
| Tables | Are | Cool |
|----------|:-------------:|------:|
| col 1 is | left-aligned | $1600 |
| col 2 is | centered | $12 |
| col 3 is | right-aligned | $1 |