Skip to content
This repository was archived by the owner on Apr 14, 2024. It is now read-only.

Commit 2fd4d87

Browse files
author
Julien Neuhart
authored
Merge pull request #12 from thecodingmachine/6.1.0
v7 (Gotenberg 6.1.0)
2 parents 921a34c + 82551fb commit 2fd4d87

20 files changed

+494
-232
lines changed

Makefile

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
GOLANG_VERSION=1.13
2-
GOTENBERG_VERSION=6.0.1
2+
GOTENBERG_VERSION=6
3+
GOTENBERG_LOG_LEVEL=ERROR
34
VERSION=snapshot
4-
GOLANGCI_LINT_VERSION=1.19.1
5+
GOLANGCI_LINT_VERSION=1.20.1
56

67
# gofmt and goimports all go files.
78
fmt:
@@ -15,5 +16,5 @@ lint:
1516

1617
# run all tests.
1718
tests:
18-
docker build --build-arg GOLANG_VERSION=$(GOLANG_VERSION) --build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) -t thecodingmachine/gotenberg-go-client:tests -f build/tests/Dockerfile .
19+
docker build --build-arg GOLANG_VERSION=$(GOLANG_VERSION) --build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) --build-arg GOTENBERG_LOG_LEVEL=$(GOTENBERG_LOG_LEVEL) -t thecodingmachine/gotenberg-go-client:tests -f build/tests/Dockerfile .
1920
docker run --rm -it -v "$(PWD):/tests" thecodingmachine/gotenberg-go-client:tests

README.md

+41-20
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,57 @@ A simple Go client for interacting with a Gotenberg API.
55
## Install
66

77
```bash
8-
$ go get -u github.com/thecodingmachine/gotenberg-go-client/v6
8+
$ go get -u github.com/thecodingmachine/gotenberg-go-client/v7
99
```
1010

1111
## Usage
1212

1313
```golang
14-
import "github.com/thecodingmachine/gotenberg-go-client/v6"
15-
16-
func main() {
17-
// HTML conversion example.
18-
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
19-
req, _ := gotenberg.NewHTMLRequest("index.html")
20-
req.Header("header.html")
21-
req.Footer("footer.html")
22-
req.Assets(
23-
"font.woff",
24-
"img.gif",
25-
"style.css",
26-
)
27-
req.PaperSize(gotenberg.A4)
28-
req.Margins(gotenberg.NormalMargins)
29-
req.Landscape(false)
30-
dest := "foo.pdf"
31-
c.Store(req, dest)
14+
import (
15+
"time"
16+
"net/http"
17+
18+
"github.com/thecodingmachine/gotenberg-go-client/v7"
19+
)
20+
21+
// create the client.
22+
client := &gotenberg.Client{Hostname: "http://localhost:3000"}
23+
// ... or use your own *http.Client.
24+
httpClient := &http.Client{
25+
Timeout: time.Duration(5) * time.Second,
3226
}
27+
client := &gotenberg.Client{Hostname: "http://localhost:3000", HTTPClient: httpClient}
28+
29+
// prepare the files required for your conversion.
30+
31+
// from a path.
32+
index, _ := gotenberg.NewDocumentFromPath("index.html", "/path/to/file")
33+
// ... or from a string.
34+
index, _ := gotenberg.NewDocumentFromString("index.html", "<html>Foo</html>")
35+
// ... or from bytes.
36+
index, _ := gotenberg.NewDocumentFromBytes("index.html", []byte("<html>Foo</html>"))
37+
38+
header, _ := gotenberg.NewDocumentFromPath("header.html", "/path/to/file")
39+
footer, _ := gotenberg.NewDocumentFromPath("footer.html", "/path/to/file")
40+
style, _ := gotenberg.NewDocumentFromPath("style.css", "/path/to/file")
41+
img, _ := gotenberg.NewDocumentFromPath("img.png", "/path/to/file")
42+
43+
req := gotenberg.NewHTMLRequest(index)
44+
req.Header(header)
45+
req.Footer(footer)
46+
req.Assets(style, img)
47+
req.PaperSize(gotenberg.A4)
48+
req.Margins(gotenberg.NoMargins)
49+
50+
//store method allows you to... store the resulting PDF in a particular destination.
51+
client.Store(req, "path/you/want/the/pdf/to/be/stored.pdf")
52+
53+
// if you wish to redirect the response directly to the browser, you may also use:
54+
resp, _ := client.Post(req)
3355
```
3456

3557
For more complete usages, head to the [documentation](https://thecodingmachine.github.io/gotenberg).
3658

37-
3859
## Badges
3960

4061
[![Travis CI](https://travis-ci.org/thecodingmachine/gotenberg-go-client.svg?branch=master)](https://travis-ci.org/thecodingmachine/gotenberg-go-client)

build/lint/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ COPY go.sum .
3232
# Install module dependencies.
3333
RUN go mod download
3434

35-
CMD [ "golangci-lint", "run" ,"--tests=false", "--enable-all", "--disable=dupl" ]
35+
CMD [ "golangci-lint", "run" ,"--tests=false", "--enable-all", "--disable=dupl", "--disable=wsl" ]

build/tests/Dockerfile

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ USER root
1414
# | Libraries used in the build process of this image.
1515
# |
1616

17-
RUN apt-get install -y git gcc
17+
RUN apt-get update &&\
18+
apt-get install -y git gcc
1819

1920
# |--------------------------------------------------------------------------
2021
# | Golang
@@ -38,6 +39,10 @@ ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
3839
# | Last instructions of this build.
3940
# |
4041

42+
ARG GOTENBERG_LOG_LEVEL
43+
44+
ENV LOG_LEVEL=${GOTENBERG_LOG_LEVEL}
45+
4146
# Define our workding outside of $GOPATH (we're using go modules).
4247
WORKDIR /tests
4348

build/tests/docker-entrypoint.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ set -xe
55
# Testing Go client.
66
gotenberg &
77
sleep 10
8-
go test -race -cover -covermode=atomic github.com/thecodingmachine/gotenberg-go-client/v6
8+
go test -race -cover -covermode=atomic github.com/thecodingmachine/gotenberg-go-client/v7
99
sleep 10 # allows Gotenberg to remove generated files.

chrome.go

+21-19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const (
1414
marginLeft string = "marginLeft"
1515
marginRight string = "marginRight"
1616
landscapeChrome string = "landscape"
17+
pageRanges string = "pageRanges"
1718
googleChromeRpccBufferSize string = "googleChromeRpccBufferSize"
1819
)
1920

@@ -46,14 +47,14 @@ var (
4647
)
4748

4849
type chromeRequest struct {
49-
headerFilePath string
50-
footerFilePath string
50+
header Document
51+
footer Document
5152

5253
*request
5354
}
5455

5556
func newChromeRequest() *chromeRequest {
56-
return &chromeRequest{"", "", newRequest()}
57+
return &chromeRequest{nil, nil, newRequest()}
5758
}
5859

5960
// WaitDelay sets waitDelay form field.
@@ -62,21 +63,13 @@ func (req *chromeRequest) WaitDelay(delay float64) {
6263
}
6364

6465
// Header sets header form file.
65-
func (req *chromeRequest) Header(fpath string) error {
66-
if !fileExists(fpath) {
67-
return fmt.Errorf("%s: header file does not exist", fpath)
68-
}
69-
req.headerFilePath = fpath
70-
return nil
66+
func (req *chromeRequest) Header(header Document) {
67+
req.header = header
7168
}
7269

7370
// Footer sets footer form file.
74-
func (req *chromeRequest) Footer(fpath string) error {
75-
if !fileExists(fpath) {
76-
return fmt.Errorf("%s: footer file does not exist", fpath)
77-
}
78-
req.footerFilePath = fpath
79-
return nil
71+
func (req *chromeRequest) Footer(footer Document) {
72+
req.footer = footer
8073
}
8174

8275
// PaperSize sets paperWidth and paperHeight form fields.
@@ -99,14 +92,23 @@ func (req *chromeRequest) Landscape(isLandscape bool) {
9992
req.values[landscapeChrome] = strconv.FormatBool(isLandscape)
10093
}
10194

95+
// PageRanges sets pageRanges form field.
96+
func (req *chromeRequest) PageRanges(ranges string) {
97+
req.values[pageRanges] = ranges
98+
}
99+
102100
// GoogleChromeRpccBufferSize sets googleChromeRpccBufferSize form field.
103101
func (req *chromeRequest) GoogleChromeRpccBufferSize(bufferSize int64) {
104102
req.values[googleChromeRpccBufferSize] = strconv.FormatInt(bufferSize, 10)
105103
}
106104

107-
func (req *chromeRequest) formFiles() map[string]string {
108-
files := make(map[string]string)
109-
files["header.html"] = req.headerFilePath
110-
files["footer.html"] = req.footerFilePath
105+
func (req *chromeRequest) formFiles() map[string]Document {
106+
files := make(map[string]Document)
107+
if req.header != nil {
108+
files["header.html"] = req.header
109+
}
110+
if req.footer != nil {
111+
files["footer.html"] = req.footer
112+
}
111113
return files
112114
}

client.go

+40-18
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,39 @@ import (
1414
)
1515

1616
const (
17-
resultFilename string = "resultFilename"
18-
waitTimeout string = "waitTimeout"
19-
webhookURL string = "webhookURL"
20-
webhookURLTimeout string = "webhookURLTimeout"
17+
resultFilename string = "resultFilename"
18+
waitTimeout string = "waitTimeout"
19+
webhookURL string = "webhookURL"
20+
webhookURLTimeout string = "webhookURLTimeout"
21+
webhookURLBaseHTTPHeaderKey string = "Gotenberg-Webhookurl-"
2122
)
2223

2324
// Client facilitates interacting with
2425
// the Gotenberg API.
2526
type Client struct {
26-
Hostname string
27+
Hostname string
28+
HTTPClient *http.Client
2729
}
2830

2931
// Request is a type for sending
3032
// form values and form files to
3133
// the Gotenberg API.
3234
type Request interface {
3335
postURL() string
36+
customHTTPHeaders() map[string]string
3437
formValues() map[string]string
35-
formFiles() map[string]string
38+
formFiles() map[string]Document
3639
}
3740

3841
type request struct {
39-
values map[string]string
42+
httpHeaders map[string]string
43+
values map[string]string
4044
}
4145

4246
func newRequest() *request {
4347
return &request{
44-
values: make(map[string]string),
48+
httpHeaders: make(map[string]string),
49+
values: make(map[string]string),
4550
}
4651
}
4752

@@ -50,7 +55,7 @@ func (req *request) ResultFilename(filename string) {
5055
req.values[resultFilename] = filename
5156
}
5257

53-
// WaitTiemout sets waitTimeout form field.
58+
// WaitTimeout sets waitTimeout form field.
5459
func (req *request) WaitTimeout(timeout float64) {
5560
req.values[waitTimeout] = strconv.FormatFloat(timeout, 'f', 2, 64)
5661
}
@@ -65,6 +70,16 @@ func (req *request) WebhookURLTimeout(timeout float64) {
6570
req.values[webhookURLTimeout] = strconv.FormatFloat(timeout, 'f', 2, 64)
6671
}
6772

73+
// AddWebhookURLHTTPHeader add a webhook custom HTTP header.
74+
func (req *request) AddWebhookURLHTTPHeader(key, value string) {
75+
key = fmt.Sprintf("%s%s", webhookURLBaseHTTPHeaderKey, key)
76+
req.httpHeaders[key] = value
77+
}
78+
79+
func (req *request) customHTTPHeaders() map[string]string {
80+
return req.httpHeaders
81+
}
82+
6883
func (req *request) formValues() map[string]string {
6984
return req.values
7085
}
@@ -76,8 +91,19 @@ func (c *Client) Post(req Request) (*http.Response, error) {
7691
if err != nil {
7792
return nil, err
7893
}
94+
if c.HTTPClient == nil {
95+
c.HTTPClient = &http.Client{}
96+
}
7997
URL := fmt.Sprintf("%s%s", c.Hostname, req.postURL())
80-
resp, err := http.Post(URL, contentType, body) /* #nosec */
98+
httpReq, err := http.NewRequest(http.MethodPost, URL, body)
99+
if err != nil {
100+
return nil, err
101+
}
102+
httpReq.Header.Set("Content-Type", contentType)
103+
for key, value := range req.customHTTPHeaders() {
104+
httpReq.Header.Set(key, value)
105+
}
106+
resp, err := c.HTTPClient.Do(httpReq) /* #nosec */
81107
if err != nil {
82108
return nil, err
83109
}
@@ -138,14 +164,10 @@ func multipartForm(req Request) (*bytes.Buffer, string, error) {
138164
body := &bytes.Buffer{}
139165
writer := multipart.NewWriter(body)
140166
defer writer.Close() // nolint: errcheck
141-
for filename, fpath := range req.formFiles() {
142-
// https://github.com/thecodingmachine/gotenberg-go-client/issues/3
143-
if fpath == "" {
144-
continue
145-
}
146-
in, err := os.Open(fpath)
167+
for filename, document := range req.formFiles() {
168+
in, err := document.Reader()
147169
if err != nil {
148-
return nil, "", fmt.Errorf("%s: opening file: %v", filename, err)
170+
return nil, "", fmt.Errorf("%s: creating reader: %v", filename, err)
149171
}
150172
defer in.Close() // nolint: errcheck
151173
part, err := writer.CreateFormFile("files", filename)
@@ -154,7 +176,7 @@ func multipartForm(req Request) (*bytes.Buffer, string, error) {
154176
}
155177
_, err = io.Copy(part, in)
156178
if err != nil {
157-
return nil, "", fmt.Errorf("%s: copying file: %v", filename, err)
179+
return nil, "", fmt.Errorf("%s: copying data: %v", filename, err)
158180
}
159181
}
160182
for name, value := range req.formValues() {

0 commit comments

Comments
 (0)