mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-17 04:32:15 +01:00
adding custom headers for remoteURL
This commit is contained in:
@@ -124,6 +124,7 @@ func urlHandler(c echo.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
opts.CustomHeaders = resource.RemoteURLCustomHeaders(r)
|
||||||
if !r.HasArg(resource.RemoteURLArgKey) {
|
if !r.HasArg(resource.RemoteURLArgKey) {
|
||||||
return xerror.Invalid(
|
return xerror.Invalid(
|
||||||
op,
|
op,
|
||||||
@@ -323,11 +324,14 @@ func convertAsync(ctx context.Context, p printer.Printer, filename, fpath string
|
|||||||
}
|
}
|
||||||
req.Header.Set(echo.HeaderContentType, "application/pdf")
|
req.Header.Set(echo.HeaderContentType, "application/pdf")
|
||||||
// set custom headers (if any).
|
// set custom headers (if any).
|
||||||
for key, value := range resource.WebhookURLCustomHeaders(r) {
|
customHeaders := resource.WebhookURLCustomHeaders(r)
|
||||||
for _, v := range value {
|
if len(customHeaders) > 0 {
|
||||||
req.Header.Add(key, v)
|
for key, value := range customHeaders {
|
||||||
logger.DebugfOp(op, "added '%s' to custom header '%s'", v, key)
|
req.Header.Set(key, value)
|
||||||
|
logger.DebugfOp(op, "set '%s' to custom header '%s'", value, key)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logger.DebugOp(op, "skipping custom headers as none have been provided...")
|
||||||
}
|
}
|
||||||
// send the result file.
|
// send the result file.
|
||||||
logger.DebugfOp(
|
logger.DebugfOp(
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ func (ctx *Context) WithResource(directoryName string) error {
|
|||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
// retrieve custom headers from request.
|
// retrieve custom headers from request.
|
||||||
for name, value := range ctx.Request().Header {
|
for key, value := range ctx.Request().Header {
|
||||||
r.WithCustomHeader(name, value)
|
r.WithCustomHeader(key, value[0])
|
||||||
}
|
}
|
||||||
// retrieve form values from request.
|
// retrieve form values from request.
|
||||||
for _, key := range resource.ArgKeys() {
|
for _, key := range resource.ArgKeys() {
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ const (
|
|||||||
WebhookURLCustomHeaderCanonicalBaseKey string = "Gotenberg-Webhookurl-"
|
WebhookURLCustomHeaderCanonicalBaseKey string = "Gotenberg-Webhookurl-"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fetchCustomHeaders(r Resource, baseKey string) map[string][]string {
|
func fetchCustomHeaders(r Resource, baseKey string) map[string]string {
|
||||||
customHeaders := make(map[string][]string)
|
customHeaders := make(map[string]string)
|
||||||
for key, value := range r.customHeaders {
|
for key, value := range r.customHeaders {
|
||||||
if strings.Contains(key, baseKey) {
|
if strings.Contains(key, baseKey) {
|
||||||
realKey := strings.Replace(key, baseKey, "", 1)
|
realKey := strings.Replace(key, baseKey, "", 1)
|
||||||
@@ -26,12 +26,12 @@ func fetchCustomHeaders(r Resource, baseKey string) map[string][]string {
|
|||||||
|
|
||||||
// RemoteURLCustomHeaders is a helper for retrieving
|
// RemoteURLCustomHeaders is a helper for retrieving
|
||||||
// the custom headers for the URL conversion.
|
// the custom headers for the URL conversion.
|
||||||
func RemoteURLCustomHeaders(r Resource) map[string][]string {
|
func RemoteURLCustomHeaders(r Resource) map[string]string {
|
||||||
return fetchCustomHeaders(r, RemoteURLCustomHeaderCanonicalBaseKey)
|
return fetchCustomHeaders(r, RemoteURLCustomHeaderCanonicalBaseKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebhookURLCustomHeaders is a helper for retrieving
|
// WebhookURLCustomHeaders is a helper for retrieving
|
||||||
// the custom headers for the webhook URL.
|
// the custom headers for the webhook URL.
|
||||||
func WebhookURLCustomHeaders(r Resource) map[string][]string {
|
func WebhookURLCustomHeaders(r Resource) map[string]string {
|
||||||
return fetchCustomHeaders(r, WebhookURLCustomHeaderCanonicalBaseKey)
|
return fetchCustomHeaders(r, WebhookURLCustomHeaderCanonicalBaseKey)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,17 +18,13 @@ func TestRemoteURLCustomHeaders(t *testing.T) {
|
|||||||
customHeaderValue := "bar"
|
customHeaderValue := "bar"
|
||||||
customHeaderCanonicalRealKey := "Foo"
|
customHeaderCanonicalRealKey := "Foo"
|
||||||
customHeaderCanonicalKey := http.CanonicalHeaderKey(fmt.Sprintf("%s%s", RemoteURLCustomHeaderCanonicalBaseKey, customHeaderCanonicalRealKey))
|
customHeaderCanonicalKey := http.CanonicalHeaderKey(fmt.Sprintf("%s%s", RemoteURLCustomHeaderCanonicalBaseKey, customHeaderCanonicalRealKey))
|
||||||
r.WithCustomHeader(customHeaderCanonicalKey, []string{customHeaderValue})
|
r.WithCustomHeader(customHeaderCanonicalKey, customHeaderValue)
|
||||||
r.WithCustomHeader("Bar", []string{"Bar"})
|
r.WithCustomHeader("Bar", "Bar")
|
||||||
expected := map[string][]string{
|
expected := map[string]string{
|
||||||
customHeaderCanonicalRealKey: []string{
|
customHeaderCanonicalRealKey: customHeaderValue,
|
||||||
customHeaderValue,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
notExpected := map[string][]string{
|
notExpected := map[string]string{
|
||||||
customHeaderCanonicalKey: []string{
|
customHeaderCanonicalKey: customHeaderValue,
|
||||||
customHeaderValue,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
v := RemoteURLCustomHeaders(r)
|
v := RemoteURLCustomHeaders(r)
|
||||||
assert.Equal(t, expected, v)
|
assert.Equal(t, expected, v)
|
||||||
@@ -44,17 +40,13 @@ func TestWebhookURLCustomHeaders(t *testing.T) {
|
|||||||
customHeaderValue := "bar"
|
customHeaderValue := "bar"
|
||||||
customHeaderCanonicalRealKey := "Foo"
|
customHeaderCanonicalRealKey := "Foo"
|
||||||
customHeaderCanonicalKey := http.CanonicalHeaderKey(fmt.Sprintf("%s%s", WebhookURLCustomHeaderCanonicalBaseKey, customHeaderCanonicalRealKey))
|
customHeaderCanonicalKey := http.CanonicalHeaderKey(fmt.Sprintf("%s%s", WebhookURLCustomHeaderCanonicalBaseKey, customHeaderCanonicalRealKey))
|
||||||
r.WithCustomHeader(customHeaderCanonicalKey, []string{customHeaderValue})
|
r.WithCustomHeader(customHeaderCanonicalKey, customHeaderValue)
|
||||||
r.WithCustomHeader("Bar", []string{"Bar"})
|
r.WithCustomHeader("Bar", "Bar")
|
||||||
expected := map[string][]string{
|
expected := map[string]string{
|
||||||
customHeaderCanonicalRealKey: []string{
|
customHeaderCanonicalRealKey: customHeaderValue,
|
||||||
customHeaderValue,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
notExpected := map[string][]string{
|
notExpected := map[string]string{
|
||||||
customHeaderCanonicalKey: []string{
|
customHeaderCanonicalKey: customHeaderValue,
|
||||||
customHeaderValue,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
v := WebhookURLCustomHeaders(r)
|
v := WebhookURLCustomHeaders(r)
|
||||||
assert.Equal(t, expected, v)
|
assert.Equal(t, expected, v)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package resource
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -25,7 +26,7 @@ const TemporaryDirectory string = "tmp"
|
|||||||
type Resource struct {
|
type Resource struct {
|
||||||
logger xlog.Logger
|
logger xlog.Logger
|
||||||
dirPath string
|
dirPath string
|
||||||
customHeaders map[string][]string
|
customHeaders map[string]string
|
||||||
args map[ArgKey]string
|
args map[ArgKey]string
|
||||||
files map[string]file
|
files map[string]file
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ func New(logger xlog.Logger, directoryName string) (Resource, error) {
|
|||||||
return Resource{
|
return Resource{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
dirPath: dirPath,
|
dirPath: dirPath,
|
||||||
customHeaders: make(map[string][]string),
|
customHeaders: make(map[string]string),
|
||||||
args: make(map[ArgKey]string),
|
args: make(map[ArgKey]string),
|
||||||
files: make(map[string]file),
|
files: make(map[string]file),
|
||||||
}, nil
|
}, nil
|
||||||
@@ -76,15 +77,17 @@ func (r Resource) Close() error {
|
|||||||
|
|
||||||
// WithCustomHeader add a new custom header to the Resource.
|
// WithCustomHeader add a new custom header to the Resource.
|
||||||
// Given key should be in canonical format.
|
// Given key should be in canonical format.
|
||||||
func (r *Resource) WithCustomHeader(key string, value []string) {
|
func (r *Resource) WithCustomHeader(key string, value string) {
|
||||||
const op string = "resource.Resource.WithCustomHeader"
|
const op string = "resource.Resource.WithCustomHeader"
|
||||||
if strings.Contains(key, RemoteURLCustomHeaderCanonicalBaseKey) ||
|
// should already be in canonical format.
|
||||||
strings.Contains(key, WebhookURLCustomHeaderCanonicalBaseKey) {
|
canonicalKey := http.CanonicalHeaderKey(key)
|
||||||
r.customHeaders[key] = value
|
if strings.Contains(canonicalKey, RemoteURLCustomHeaderCanonicalBaseKey) ||
|
||||||
r.logger.DebugfOp(op, "added '%s' with value '%s' to resource custom headers", key, value)
|
strings.Contains(canonicalKey, WebhookURLCustomHeaderCanonicalBaseKey) {
|
||||||
|
r.customHeaders[canonicalKey] = value
|
||||||
|
r.logger.DebugfOp(op, "added '%s' with value '%s' to resource custom headers", canonicalKey, value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.logger.DebugfOp(op, "skipping '%s' as it is not a custom header...", key)
|
r.logger.DebugfOp(op, "skipping '%s' as it is not a custom header...", canonicalKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithArg add a new argument to the Resource.
|
// WithArg add a new argument to the Resource.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package printer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -42,6 +43,7 @@ type ChromePrinterOptions struct {
|
|||||||
MarginRight float64
|
MarginRight float64
|
||||||
Landscape bool
|
Landscape bool
|
||||||
RpccBufferSize int64
|
RpccBufferSize int64
|
||||||
|
CustomHeaders map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultChromePrinterOptions returns the default
|
// DefaultChromePrinterOptions returns the default
|
||||||
@@ -61,6 +63,7 @@ func DefaultChromePrinterOptions(config conf.Config) ChromePrinterOptions {
|
|||||||
MarginRight: 1.0,
|
MarginRight: 1.0,
|
||||||
Landscape: false,
|
Landscape: false,
|
||||||
RpccBufferSize: config.DefaultGoogleChromeRpccBufferSize(),
|
RpccBufferSize: config.DefaultGoogleChromeRpccBufferSize(),
|
||||||
|
CustomHeaders: make(map[string]string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +147,10 @@ func (p chromePrinter) Print(destination string) error {
|
|||||||
if err := p.enableEvents(ctx, targetClient); err != nil {
|
if err := p.enableEvents(ctx, targetClient); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// add custom headers (if any).
|
||||||
|
if err := p.setCustomHeaders(ctx, targetClient); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// listen for all events.
|
// listen for all events.
|
||||||
if err := p.listenEvents(ctx, targetClient); err != nil {
|
if err := p.listenEvents(ctx, targetClient); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -247,6 +254,32 @@ func (p chromePrinter) enableEvents(ctx context.Context, client *cdp.Client) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p chromePrinter) setCustomHeaders(ctx context.Context, client *cdp.Client) error {
|
||||||
|
const op string = "printer.chromePrinter.setCustomHeaders"
|
||||||
|
resolver := func() error {
|
||||||
|
if len(p.opts.CustomHeaders) == 0 {
|
||||||
|
p.logger.DebugOp(op, "skipping custom headers as none have been provided...")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
customHeaders := make(map[string]string)
|
||||||
|
// useless but for the logs.
|
||||||
|
for key, value := range p.opts.CustomHeaders {
|
||||||
|
customHeaders[key] = value
|
||||||
|
p.logger.DebugfOp(op, "set '%s' to custom header '%s'", value, key)
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(customHeaders)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// should always be called after client.Network.Enable.
|
||||||
|
return client.Network.SetExtraHTTPHeaders(ctx, network.NewSetExtraHTTPHeadersArgs(b))
|
||||||
|
}
|
||||||
|
if err := resolver(); err != nil {
|
||||||
|
return xerror.New(op, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p chromePrinter) listenEvents(ctx context.Context, client *cdp.Client) error {
|
func (p chromePrinter) listenEvents(ctx context.Context, client *cdp.Client) error {
|
||||||
const op string = "printer.chromePrinter.listenEvents"
|
const op string = "printer.chromePrinter.listenEvents"
|
||||||
resolver := func() error {
|
resolver := func() error {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func multipartForm(
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
if kind == "url" {
|
if kind == "url" {
|
||||||
err := writer.WriteField("remoteURL", "http://google.com")
|
err := writer.WriteField("remoteURL", "https://google.com")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
for k, v := range formValues {
|
for k, v := range formValues {
|
||||||
|
|||||||
Reference in New Issue
Block a user