chore(webhook): deprecate Gotenberg-Webhook-Error-Url, make it non-mandatory if Gotenberg-Webhook-Events-Url is set

This commit is contained in:
Julien Neuhart
2026-03-29 17:12:29 +02:00
parent 1ab0117943
commit 452a500955
3 changed files with 68 additions and 12 deletions

View File

@@ -39,6 +39,11 @@ type client struct {
func (c client) send(ctx context.Context, body io.Reader, headers map[string]string, errored bool) error {
url := c.url
if errored {
if c.errorUrl == "" {
// No error URL provided; error details will be sent
// via the events URL instead.
return nil
}
url = c.errorUrl
}

View File

@@ -105,15 +105,22 @@ func webhookMiddleware(w *Webhook) api.Middleware {
ctx := c.Get("context").(*api.Context)
cancel := c.Get("cancel").(context.CancelFunc)
// Do we have a webhook error URL in case of... error?
// Do we have a webhook error URL and/or an events URL?
// At least one must be provided.
webhookErrorUrl := c.Request().Header.Get("Gotenberg-Webhook-Error-Url")
if webhookErrorUrl == "" {
webhookEventsUrl := c.Request().Header.Get("Gotenberg-Webhook-Events-Url")
if webhookErrorUrl == "" && webhookEventsUrl == "" {
return api.WrapError(
errors.New("empty webhook error URL"),
api.NewSentinelHttpError(http.StatusBadRequest, "Invalid 'Gotenberg-Webhook-Error-Url' header: empty value or header not provided"),
errors.New("empty webhook error URL and events URL"),
api.NewSentinelHttpError(http.StatusBadRequest, "At least one of 'Gotenberg-Webhook-Error-Url' or 'Gotenberg-Webhook-Events-Url' headers must be provided"),
)
}
if webhookErrorUrl != "" {
ctx.Log().Warn("'Gotenberg-Webhook-Error-Url' header is deprecated, use 'Gotenberg-Webhook-Events-Url' instead")
}
deadline, ok := ctx.Deadline()
if !ok {
return errors.New("context has no deadline")
@@ -126,9 +133,11 @@ func webhookMiddleware(w *Webhook) api.Middleware {
return fmt.Errorf("filter webhook URL: %w", err)
}
err = gotenberg.FilterDeadline(w.errorAllowList, w.errorDenyList, webhookErrorUrl, deadline)
if err != nil {
return fmt.Errorf("filter webhook error URL: %w", err)
if webhookErrorUrl != "" {
err = gotenberg.FilterDeadline(w.errorAllowList, w.errorDenyList, webhookErrorUrl, deadline)
if err != nil {
return fmt.Errorf("filter webhook error URL: %w", err)
}
}
// Let's check the HTTP methods for calling the webhook URLs.
@@ -164,9 +173,12 @@ func webhookMiddleware(w *Webhook) api.Middleware {
return fmt.Errorf("get method to use for webhook: %w", err)
}
webhookErrorMethod, err := methodFromHeader("Gotenberg-Webhook-Error-Method")
if err != nil {
return fmt.Errorf("get method to use for webhook error: %w", err)
var webhookErrorMethod string
if webhookErrorUrl != "" {
webhookErrorMethod, err = methodFromHeader("Gotenberg-Webhook-Error-Method")
if err != nil {
return fmt.Errorf("get method to use for webhook error: %w", err)
}
}
// What about extra HTTP headers?
@@ -183,8 +195,7 @@ func webhookMiddleware(w *Webhook) api.Middleware {
}
}
// What about the events URL?
webhookEventsUrl := c.Request().Header.Get("Gotenberg-Webhook-Events-Url")
// Filter the events URL if provided.
if webhookEventsUrl != "" {
err = gotenberg.FilterDeadline(w.allowList, w.denyList, webhookEventsUrl, deadline)
if err != nil {

View File

@@ -86,3 +86,43 @@ Feature: Webhook
"timestamp": "ignore"
}
"""
Scenario: Webhook Events URL Only (Success)
Given I have a default Gotenberg container
Given I have a webhook server
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
| files | testdata/page_1.pdf | file |
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
| Gotenberg-Webhook-Events-Url | http://host.docker.internal:%d/webhook/events | header |
Then the response status code should be 204
When I wait for the asynchronous request to the webhook
Then the webhook request header "Content-Type" should be "application/pdf"
Then there should be 1 PDF(s) in the webhook request
Then the webhook event should match JSON:
"""
{
"event": "webhook.success",
"correlationId": "ignore",
"timestamp": "ignore"
}
"""
Scenario: Webhook Events URL Only (Synchronous)
Given I have a Gotenberg container with the following environment variable(s):
| WEBHOOK_ENABLE_SYNC_MODE | true |
Given I have a webhook server
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
| files | testdata/page_1.pdf | file |
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
| Gotenberg-Webhook-Events-Url | http://host.docker.internal:%d/webhook/events | header |
Then the response status code should be 204
Then the webhook request header "Content-Type" should be "application/pdf"
Then there should be 1 PDF(s) in the webhook request
Then the webhook event should match JSON:
"""
{
"event": "webhook.success",
"correlationId": "ignore",
"timestamp": "ignore"
}
"""